xref: /trunk/main/soltools/giparser/gi_parse.cxx (revision 7a4715d3)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_soltools.hxx"
26 
27 #include <gi_parse.hxx>
28 
29 #include <stdio.h>
30 #include <string.h>
31 #include <fstream>
32 #include <gilacces.hxx>
33 
34 
35 using namespace std;
36 
37 
38 const char * C_sLineEnd = "\r\n";
39 
40 
41 
42 inline void
WriteStr(ostream & o_rOut,const Simstr & i_rStr)43 WriteStr( ostream & o_rOut, const Simstr & i_rStr )
44 {
45     o_rOut.write( i_rStr.str(), i_rStr.l() );
46 }
47 
48 inline void
WriteStr(ostream & o_rOut,const char * i_rStr)49 WriteStr( ostream & o_rOut, const char * i_rStr )
50 {
51     o_rOut.write( i_rStr, strlen(i_rStr) );
52 }
53 
54 inline void
SetError(E_Error i_eError)55 GenericInfo_Parser::SetError( E_Error i_eError )
56 {
57  	eErrorCode = i_eError;
58     nErrorLine = nCurLine;
59 }
60 
61 
GenericInfo_Parser()62 GenericInfo_Parser::GenericInfo_Parser()
63     :   sCurParsePosition(""),
64         nCurLine(0),
65         nLevel(0),
66         bGoon(false),
67         // sCurComment,
68         eErrorCode(ok),
69 	    nErrorLine(0),
70         pResult(0),
71         pResource(0)
72 {
73 }
74 
~GenericInfo_Parser()75 GenericInfo_Parser::~GenericInfo_Parser()
76 {
77 }
78 
79 bool
LoadList(GenericInfoList_Builder & o_rResult,const Simstr & i_sSourceFileName)80 GenericInfo_Parser::LoadList( GenericInfoList_Builder &  o_rResult,
81                               const Simstr &             i_sSourceFileName )
82 {
83     ifstream  aFile( i_sSourceFileName.str() );
84     if ( aFile.fail() )
85     {
86         SetError(cannot_open);
87         return false;
88     }
89 
90     aFile.seekg(0, ios::end);
91     UINT32 nTextSize = aFile.tellg();
92     if ( nTextSize == 0 || nTextSize == UINT32(-1) )
93         return true;
94     dpBuffer = new char[nTextSize+2];
95 
96     aFile.seekg(0);
97     aFile.read( dpBuffer, nTextSize );
98     aFile.close();
99 
100     sFilePtr = dpBuffer;
101     char * sLastChar = dpBuffer + nTextSize - 1;
102 
103     while ( sFilePtr != sLastChar && *sFilePtr <= 32 )
104         ++sCurParsePosition;
105     if ( sFilePtr == sLastChar )
106     {
107         if ( *sFilePtr <= 32 )
108             return true;
109     }
110     else while ( *sLastChar <= 32 )
111     {
112         --sLastChar;
113     }
114 
115     *(sLastChar+1) = '\n';
116     *(sLastChar+2) = '\0';
117 
118     ResetState(o_rResult);
119 
120     for ( ReadLine(); bGoon; ReadLine() )
121     {
122         bool bOk = InterpretLine();
123         if ( !bOk)
124         {
125             SetError(syntax_error);
126             break;
127         }
128     }
129 
130     if ( nLevel > 0 && eErrorCode == ok)
131     {
132         SetError(unexpected_eof);
133     }
134     else if ( nLevel < 0 )
135     {
136         SetError(unexpected_list_end);
137     }
138 
139     delete [] dpBuffer;
140     dpBuffer = 0;
141     sFilePtr = 0;
142 
143 	return eErrorCode == ok;
144 }
145 
146 bool
SaveList(const Simstr & i_rOutputFile,GenericInfoList_Browser & io_rListBrowser)147 GenericInfo_Parser::SaveList( const Simstr &            i_rOutputFile,
148 	                          GenericInfoList_Browser & io_rListBrowser )
149 {
150     ofstream  aFile( i_rOutputFile.str() );
151     if ( aFile.fail() )
152     {
153         SetError(cannot_open);
154         return false;
155     }
156 
157     ResetState(io_rListBrowser);
158 
159     WriteList(aFile);
160 
161 	aFile.close();
162 	return eErrorCode == ok;
163 }
164 
165 void
ResetState(GenericInfoList_Builder & io_rResult)166 GenericInfo_Parser::ResetState( GenericInfoList_Builder & io_rResult )
167 {
168     sCurParsePosition = "";
169     nCurLine = 0;
170     nLevel = 0;
171     bGoon = true;
172     sCurComment = "";
173     eErrorCode = ok;
174 	nErrorLine = 0;
175     pResult = &io_rResult;
176     pResource = 0;
177 }
178 
179 void
ResetState(GenericInfoList_Browser & io_rSrc)180 GenericInfo_Parser::ResetState( GenericInfoList_Browser & io_rSrc )
181 {
182     sCurParsePosition = "";
183     nCurLine = 0;
184     nLevel = 0;
185     bGoon = false;
186     sCurComment = "";
187     eErrorCode = ok;
188 	nErrorLine = 0;
189     pResult = 0;
190     pResource = &io_rSrc;
191 }
192 
193 
194 void
ReadLine()195 GenericInfo_Parser::ReadLine()
196 {
197     if ( *sFilePtr == '\0' )    // See initialising of dpBuffer and sLastChar in LoadList().
198 	{
199 		bGoon = false;
200 		return;
201 	}
202 
203     sCurParsePosition = sFilePtr;
204     while ( *sFilePtr != '\n' )
205         ++sFilePtr;
206     nCurLine++;
207 
208     // Remove leading and trailing whitespace from line:
209     while ( sCurParsePosition != sFilePtr && *sCurParsePosition <= 32 )
210         ++sCurParsePosition;
211 
212     char * sEndOfLine = sFilePtr;
213     while ( sEndOfLine != sCurParsePosition && *sEndOfLine <= 32 )
214           --sEndOfLine;
215     if ( sCurParsePosition != sEndOfLine || *sCurParsePosition > 32 )
216 	    ++sEndOfLine;
217     *sEndOfLine = '\0';
218 
219     ++sFilePtr; // Go beyond line end to first character of next line.
220 }
221 
222 bool
InterpretLine()223 GenericInfo_Parser::InterpretLine()
224 {
225     switch ( ClassifyLine() )
226     {
227         case lt_key:        ReadKey();
228                             break;
229         case lt_open_list:  PushLevel_Read();
230                             break;
231         case lt_close_list: PopLevel_Read();
232                             break;
233         case lt_comment:    AddCurLine2CurComment();
234                             break;
235         case lt_empty:      AddCurLine2CurComment();
236                             break;
237         default:
238                             return false;
239     }
240     return true;
241 }
242 
243 GenericInfo_Parser::E_LineType
ClassifyLine()244 GenericInfo_Parser::ClassifyLine()
245 {
246     switch ( *sCurParsePosition )
247     {
248      	case '{':   return lt_open_list;
249         case '}':   return lt_close_list;
250         case '#':   return lt_comment;
251         case '\0':   return lt_empty;
252     }
253 
254     return lt_key;
255 }
256 
257 void
ReadKey()258 GenericInfo_Parser::ReadKey()
259 {
260     const char * pSearch = sCurParsePosition;
261 
262     for ( ; *pSearch > 32; ++pSearch ) ;
263     UINT32 nKeyLength = pSearch - sCurParsePosition;
264 
265     for ( ; *pSearch <= 32 && *pSearch > '\0'; ++pSearch ) ;
266 
267     pResult->AddKey( sCurParsePosition,     nKeyLength,
268                      pSearch,               strlen(pSearch),
269                      sCurComment.str(),     sCurComment.l()
270                    );
271     sCurComment = "";
272 }
273 
274 void
PushLevel_Read()275 GenericInfo_Parser::PushLevel_Read()
276 {
277     nLevel++;
278     pResult->OpenList();
279 }
280 
281 void
PopLevel_Read()282 GenericInfo_Parser::PopLevel_Read()
283 {
284     nLevel--;
285     pResult->CloseList();
286 }
287 
288 void
AddCurLine2CurComment()289 GenericInfo_Parser::AddCurLine2CurComment()
290 {
291     sCurComment +=  sCurParsePosition;
292     sCurComment +=  C_sLineEnd;
293 }
294 
295 void
WriteList(ostream & o_rFile)296 GenericInfo_Parser::WriteList( ostream & o_rFile )
297 {
298     static char sBuffer[32000];
299 
300     for ( bGoon = pResource->Start_CurList();
301           bGoon;
302           bGoon = pResource->NextOf_CurList() )
303     {
304         pResource->Get_CurComment(&sBuffer[0]);
305         WriteComment(o_rFile,sBuffer);
306 
307         pResource->Get_CurKey(&sBuffer[0]);
308         WriteKey(o_rFile,sBuffer);
309 
310         pResource->Get_CurValue(&sBuffer[0]);
311         WriteValue(o_rFile,sBuffer);
312 
313         if ( pResource->HasSubList_CurKey() )
314         {
315             PushLevel_Write();
316 
317 /*
318             WriteIndentation();
319             o_rFile.write("{",1);
320             o_rFile.write(C_sLineEnd, C_nLineEndLength);
321 */
322             WriteList(o_rFile);
323 
324 /*
325             WriteIndentation();
326             o_rFile.write("}",1);
327             o_rFile.write(C_sLineEnd, C_nLineEndLength);
328 */
329             PopLevel_Write();
330         }
331     }   // end for
332 }
333 
334 void
PushLevel_Write()335 GenericInfo_Parser::PushLevel_Write()
336 {
337     nLevel++;
338     pResource->Push_CurList();
339 }
340 
341 void
PopLevel_Write()342 GenericInfo_Parser::PopLevel_Write()
343 {
344     nLevel--;
345     pResource->Pop_CurList();
346 }
347 
348 void
WriteComment(ostream & o_rFile,const char * i_sStr)349 GenericInfo_Parser::WriteComment( ostream &    o_rFile,
350                                   const char *  i_sStr )
351 {
352     WriteStr( o_rFile, i_sStr );
353     if ( i_sStr[ strlen(i_sStr)-1 ] != '\n' )
354         WriteStr( o_rFile, C_sLineEnd );
355 }
356 
357 void
WriteKey(ostream & o_rFile,const char * i_sStr)358 GenericInfo_Parser::WriteKey( ostream &    o_rFile,
359                               const char *  i_sStr )
360 {
361     WriteIndentation(o_rFile);
362     WriteStr( o_rFile, i_sStr );
363 }
364 
365 void
WriteValue(ostream & o_rFile,const char * i_sStr)366 GenericInfo_Parser::WriteValue( ostream &    o_rFile,
367                                 const char *  i_sStr )
368 {
369     if ( i_sStr != 0 ? strlen(i_sStr) > 0 : false )
370     {
371      	WriteStr(o_rFile," ");
372      	WriteStr(o_rFile,i_sStr);
373     }
374 
375     WriteStr(o_rFile,C_sLineEnd);
376 }
377 
378 void
WriteIndentation(ostream & o_rFile)379 GenericInfo_Parser::WriteIndentation( ostream &    o_rFile )
380 {
381     const int nIndentBound = 60;
382 
383     static const char sIndentation[nIndentBound+1] =
384         "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
385         "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
386         "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
387 
388     if ( nLevel == 0 )
389         return;
390 
391     if ( nLevel <= nIndentBound )
392         o_rFile.write( sIndentation, nLevel );
393     else
394     {
395         INT16 iLevel = nLevel;
396         for ( ; iLevel > nIndentBound; iLevel-=nIndentBound )
397             o_rFile.write( sIndentation, nIndentBound );
398         o_rFile.write( sIndentation, iLevel );
399     }
400 }
401 
402 
403 
404