merge the formfield patch from ooo-build
[ooovba.git] / soltools / giparser / gi_parse.cxx
blobe4b9242ff8b1b852dad947999c86625d84dfd2c5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gi_parse.cxx,v $
10 * $Revision: 1.6.16.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_soltools.hxx"
34 #include <gi_parse.hxx>
36 #include <stdio.h>
37 #include <string.h>
38 #include <fstream>
39 #include <gilacces.hxx>
42 using namespace std;
45 const char * C_sLineEnd = "\r\n";
49 inline void
50 WriteStr( ostream & o_rOut, const Simstr & i_rStr )
52 o_rOut.write( i_rStr.str(), i_rStr.l() );
55 inline void
56 WriteStr( ostream & o_rOut, const char * i_rStr )
58 o_rOut.write( i_rStr, strlen(i_rStr) );
61 inline void
62 GenericInfo_Parser::SetError( E_Error i_eError )
64 eErrorCode = i_eError;
65 nErrorLine = nCurLine;
69 GenericInfo_Parser::GenericInfo_Parser()
70 : sCurParsePosition(""),
71 nCurLine(0),
72 nLevel(0),
73 bGoon(false),
74 // sCurComment,
75 eErrorCode(ok),
76 nErrorLine(0),
77 pResult(0),
78 pResource(0)
82 GenericInfo_Parser::~GenericInfo_Parser()
86 bool
87 GenericInfo_Parser::LoadList( GenericInfoList_Builder & o_rResult,
88 const Simstr & i_sSourceFileName )
90 ifstream aFile( i_sSourceFileName.str() );
91 if ( aFile.fail() )
93 SetError(cannot_open);
94 return false;
97 aFile.seekg(0, ios::end);
98 UINT32 nTextSize = aFile.tellg();
99 if ( nTextSize == 0 || nTextSize == UINT32(-1) )
100 return true;
101 dpBuffer = new char[nTextSize+2];
103 aFile.seekg(0);
104 aFile.read( dpBuffer, nTextSize );
105 aFile.close();
107 sFilePtr = dpBuffer;
108 char * sLastChar = dpBuffer + nTextSize - 1;
110 while ( sFilePtr != sLastChar && *sFilePtr <= 32 )
111 ++sCurParsePosition;
112 if ( sFilePtr == sLastChar )
114 if ( *sFilePtr <= 32 )
115 return true;
117 else while ( *sLastChar <= 32 )
119 --sLastChar;
122 *(sLastChar+1) = '\n';
123 *(sLastChar+2) = '\0';
125 ResetState(o_rResult);
127 for ( ReadLine(); bGoon; ReadLine() )
129 bool bOk = InterpretLine();
130 if ( !bOk)
132 SetError(syntax_error);
133 break;
137 if ( nLevel > 0 && eErrorCode == ok)
139 SetError(unexpected_eof);
141 else if ( nLevel < 0 )
143 SetError(unexpected_list_end);
146 delete [] dpBuffer;
147 dpBuffer = 0;
148 sFilePtr = 0;
150 return eErrorCode == ok;
153 bool
154 GenericInfo_Parser::SaveList( const Simstr & i_rOutputFile,
155 GenericInfoList_Browser & io_rListBrowser )
157 ofstream aFile( i_rOutputFile.str() );
158 if ( aFile.fail() )
160 SetError(cannot_open);
161 return false;
164 ResetState(io_rListBrowser);
166 WriteList(aFile);
168 aFile.close();
169 return eErrorCode == ok;
172 void
173 GenericInfo_Parser::ResetState( GenericInfoList_Builder & io_rResult )
175 sCurParsePosition = "";
176 nCurLine = 0;
177 nLevel = 0;
178 bGoon = true;
179 sCurComment = "";
180 eErrorCode = ok;
181 nErrorLine = 0;
182 pResult = &io_rResult;
183 pResource = 0;
186 void
187 GenericInfo_Parser::ResetState( GenericInfoList_Browser & io_rSrc )
189 sCurParsePosition = "";
190 nCurLine = 0;
191 nLevel = 0;
192 bGoon = false;
193 sCurComment = "";
194 eErrorCode = ok;
195 nErrorLine = 0;
196 pResult = 0;
197 pResource = &io_rSrc;
201 void
202 GenericInfo_Parser::ReadLine()
204 if ( *sFilePtr == '\0' ) // See initialising of dpBuffer and sLastChar in LoadList().
206 bGoon = false;
207 return;
210 sCurParsePosition = sFilePtr;
211 while ( *sFilePtr != '\n' )
212 ++sFilePtr;
213 nCurLine++;
215 // Remove leading and trailing whitespace from line:
216 while ( sCurParsePosition != sFilePtr && *sCurParsePosition <= 32 )
217 ++sCurParsePosition;
219 char * sEndOfLine = sFilePtr;
220 while ( sEndOfLine != sCurParsePosition && *sEndOfLine <= 32 )
221 --sEndOfLine;
222 if ( sCurParsePosition != sEndOfLine || *sCurParsePosition > 32 )
223 ++sEndOfLine;
224 *sEndOfLine = '\0';
226 ++sFilePtr; // Go beyond line end to first character of next line.
229 bool
230 GenericInfo_Parser::InterpretLine()
232 switch ( ClassifyLine() )
234 case lt_key: ReadKey();
235 break;
236 case lt_open_list: PushLevel_Read();
237 break;
238 case lt_close_list: PopLevel_Read();
239 break;
240 case lt_comment: AddCurLine2CurComment();
241 break;
242 case lt_empty: AddCurLine2CurComment();
243 break;
244 default:
245 return false;
247 return true;
250 GenericInfo_Parser::E_LineType
251 GenericInfo_Parser::ClassifyLine()
253 switch ( *sCurParsePosition )
255 case '{': return lt_open_list;
256 case '}': return lt_close_list;
257 case '#': return lt_comment;
258 case '\0': return lt_empty;
261 return lt_key;
264 void
265 GenericInfo_Parser::ReadKey()
267 const char * pSearch = sCurParsePosition;
269 for ( ; *pSearch > 32; ++pSearch ) ;
270 UINT32 nKeyLength = pSearch - sCurParsePosition;
272 for ( ; *pSearch <= 32 && *pSearch > '\0'; ++pSearch ) ;
274 pResult->AddKey( sCurParsePosition, nKeyLength,
275 pSearch, strlen(pSearch),
276 sCurComment.str(), sCurComment.l()
278 sCurComment = "";
281 void
282 GenericInfo_Parser::PushLevel_Read()
284 nLevel++;
285 pResult->OpenList();
288 void
289 GenericInfo_Parser::PopLevel_Read()
291 nLevel--;
292 pResult->CloseList();
295 void
296 GenericInfo_Parser::AddCurLine2CurComment()
298 sCurComment += sCurParsePosition;
299 sCurComment += C_sLineEnd;
302 void
303 GenericInfo_Parser::WriteList( ostream & o_rFile )
305 static char sBuffer[32000];
307 for ( bGoon = pResource->Start_CurList();
308 bGoon;
309 bGoon = pResource->NextOf_CurList() )
311 pResource->Get_CurComment(&sBuffer[0]);
312 WriteComment(o_rFile,sBuffer);
314 pResource->Get_CurKey(&sBuffer[0]);
315 WriteKey(o_rFile,sBuffer);
317 pResource->Get_CurValue(&sBuffer[0]);
318 WriteValue(o_rFile,sBuffer);
320 if ( pResource->HasSubList_CurKey() )
322 PushLevel_Write();
325 WriteIndentation();
326 o_rFile.write("{",1);
327 o_rFile.write(C_sLineEnd, C_nLineEndLength);
329 WriteList(o_rFile);
332 WriteIndentation();
333 o_rFile.write("}",1);
334 o_rFile.write(C_sLineEnd, C_nLineEndLength);
336 PopLevel_Write();
338 } // end for
341 void
342 GenericInfo_Parser::PushLevel_Write()
344 nLevel++;
345 pResource->Push_CurList();
348 void
349 GenericInfo_Parser::PopLevel_Write()
351 nLevel--;
352 pResource->Pop_CurList();
355 void
356 GenericInfo_Parser::WriteComment( ostream & o_rFile,
357 const char * i_sStr )
359 WriteStr( o_rFile, i_sStr );
360 if ( i_sStr[ strlen(i_sStr)-1 ] != '\n' )
361 WriteStr( o_rFile, C_sLineEnd );
364 void
365 GenericInfo_Parser::WriteKey( ostream & o_rFile,
366 const char * i_sStr )
368 WriteIndentation(o_rFile);
369 WriteStr( o_rFile, i_sStr );
372 void
373 GenericInfo_Parser::WriteValue( ostream & o_rFile,
374 const char * i_sStr )
376 if ( i_sStr != 0 ? strlen(i_sStr) > 0 : false )
378 WriteStr(o_rFile," ");
379 WriteStr(o_rFile,i_sStr);
382 WriteStr(o_rFile,C_sLineEnd);
385 void
386 GenericInfo_Parser::WriteIndentation( ostream & o_rFile )
388 const int nIndentBound = 60;
390 static const char sIndentation[nIndentBound+1] =
391 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
392 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
393 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
395 if ( nLevel == 0 )
396 return;
398 if ( nLevel <= nIndentBound )
399 o_rFile.write( sIndentation, nLevel );
400 else
402 INT16 iLevel = nLevel;
403 for ( ; iLevel > nIndentBound; iLevel-=nIndentBound )
404 o_rFile.write( sIndentation, nIndentBound );
405 o_rFile.write( sIndentation, iLevel );