00001 #include <citrus/config.h>
00002
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <ctype.h>
00006 #include <unistd.h>
00007 #include <math.h>
00008
00009 #include <libxml/parserInternals.h>
00010
00011 #include <citrus/Prefix.H>
00012 #include <citrus/Dimension.H>
00013 #include <citrus/DimensionGroup.H>
00014 #include <citrus/Unit.H>
00015 #include <citrus/UnitSystem.H>
00016
00017 #define _( a ) (a)
00018 #define SUCKY_CAST (const char*)
00019
00027
00028
00029
00030 class UnitConfParserState
00031 {
00032 public:
00033 UnitConfParserState() ;
00034 ~UnitConfParserState() ;
00035 void startElement( const CHAR* name, const CHAR** attrs ) ;
00036 void endElement( const CHAR* name ) ;
00037 void characters( const CHAR* val, int len ) ;
00038 void startDocument() ;
00039 void endDocument() ;
00040 xmlEntityPtr getEntity( const CHAR* name ) ;
00041 void reset() ;
00042
00043 enum State {
00044 AtTop,
00045 InUnitConf,
00046 InDimensions,
00047 InPrefixes,
00048 InDimensionGroups,
00049 InUnitSystems,
00050 InDimension,
00051 InPrefix,
00052 InGroup,
00053 InDimPower,
00054 InUnit,
00055 InSystem,
00056 InStdUnit,
00057 Unknown
00058 } ;
00059
00060 protected:
00061 void terminateBuffer() ;
00062 void copyBufferTo( CHAR*& ) ;
00063 void emptyData( CHAR*& ) ;
00064
00065 static char* stateNames[] ;
00066 State level ;
00067 State unknownRecover ;
00068 int unknownDepth ;
00069 DimensionGroup* curGroup ;
00070 UnitSystem* curSys ;
00071 vector<DimensionPower> grpPowers ;
00072 CHAR* buffer ;
00073 int buflen ;
00074 int bufmax ;
00075 bool rememberString ;
00076
00077 CHAR* nameData ;
00078 CHAR* plurData ;
00079 CHAR* symData ;
00080 CHAR chrData ;
00081 double scale ;
00082 double offset ;
00083 int power ;
00084 bool one ;
00085 bool avoid ;
00086 bool noPlural ;
00087 bool noPrefix ;
00088 } ;
00089
00090 char* UnitConfParserState::stateNames[] = {
00091 "AtTop",
00092 "InUnitConf",
00093 "InDimensions",
00094 "InPrefixes",
00095 "InDimensionGroups",
00096 "InUnitSystems",
00097 "InDimension",
00098 "InPrefix",
00099 "InGroup",
00100 "InDimPower",
00101 "InUnit",
00102 "InSystem",
00103 "InStdUnit",
00104 "Unknown"
00105 } ;
00106
00107 xmlEntityPtr dumbGetEntity( void* a, const CHAR* name )
00108 {
00109 UnitConfParserState* u = (UnitConfParserState*)a ;
00110 return u->getEntity( name ) ;
00111 }
00112
00113 void dumbStartDocument( void* a )
00114 {
00115 UnitConfParserState* u = (UnitConfParserState*)a ;
00116 return u->startDocument() ;
00117 }
00118
00119 void dumbEndDocument( void* a )
00120 {
00121 UnitConfParserState* u = (UnitConfParserState*)a ;
00122 return u->endDocument() ;
00123 }
00124
00125 void dumbStartElement( void* a, const CHAR* name, const CHAR** attrs )
00126 {
00127 UnitConfParserState* u = (UnitConfParserState*)a ;
00128 u->startElement( name, attrs ) ;
00129 }
00130
00131 void dumbEndElement( void* a, const CHAR* name )
00132 {
00133 UnitConfParserState* u = (UnitConfParserState*)a ;
00134 u->endElement( name ) ;
00135 }
00136
00137 void dumbCharacters( void* a, const CHAR* chr, int len )
00138 {
00139 UnitConfParserState* u = (UnitConfParserState*)a ;
00140 u->characters( chr, len ) ;
00141 }
00142
00143 static xmlSAXHandler unitConfSAXParser = {
00144 0,
00145 0,
00146 0,
00147 0,
00148 0,
00149 (getEntitySAXFunc)&dumbGetEntity,
00150 0,
00151 0,
00152 0,
00153 0,
00154 0,
00155 0,
00156 (startDocumentSAXFunc)&dumbStartDocument,
00157 (endDocumentSAXFunc)&dumbEndDocument,
00158 (startElementSAXFunc)&dumbStartElement,
00159 (endElementSAXFunc)&dumbEndElement,
00160 0,
00161 (charactersSAXFunc)&dumbCharacters,
00162 0,
00163 0,
00164 0,
00165 0,
00166 0,
00167 0,
00168 } ;
00169
00170 int UnitReadConfig( const char* filename )
00171 {
00172 xmlParserCtxtPtr ctxt;
00173 UnitConfParserState ups ;
00174
00175 ctxt = xmlCreateFileParserCtxt( filename ) ;
00176 if (ctxt == 0)
00177 return -1 ;
00178
00179 ctxt->sax = &unitConfSAXParser ;
00180 ctxt->userData = &ups ;
00181 xmlParseDocument( ctxt ) ;
00182
00183 if (!ctxt->wellFormed) {
00184 return -1 ;
00185 // ABORT ABORT ABORT (free memory from state)
00186 }
00187 ctxt->sax = 0 ;
00188 xmlFreeParserCtxt( ctxt ) ;
00189
00190 return 0 ;
00191 }
00192
00193 UnitConfParserState::UnitConfParserState()
00194 {
00195 bufmax = 512*sizeof(CHAR) ;
00196 buffer = (CHAR*) malloc( 512*sizeof(CHAR) ) ;
00197
00198 nameData = 0 ;
00199 plurData = 0 ;
00200 symData = 0 ;
00201 scale = dtNaN ;
00202 offset = dtNaN ;
00203 power = 0 ;
00204 chrData = CHAR('\0') ;
00205
00206 reset() ;
00207 }
00208
00209 UnitConfParserState::~UnitConfParserState()
00210 {
00211 reset() ;
00212 free( buffer ) ;
00213 }
00214
00215 void UnitConfParserState::startElement( const CHAR* name,
00216 const CHAR** attrs )
00217 {
00218
00219 #ifdef DBG_STARTELE
00220 fprintf( stderr, "[%s] startElement( %s", stateNames[level], name ) ;
00221 if ( attrs ) {
00222 for (int i=0; attrs[i] ; i+=2 )
00223 fprintf( stderr, ", %s='%s'", attrs[i], attrs[i+1] ) ;
00224 }
00225 fprintf( stderr, " )\n" ) ;
00226 #endif // DBG_STARTELE
00227
00228 switch( level ) {
00229 case AtTop:
00230 if ( strcmp( SUCKY_CAST name, "unitconf" ) )
00231 fprintf( stderr, _("Expected unitconf as toplevel element, got <%s> tag."), name );
00232 else
00233 level = InUnitConf ;
00234 break ;
00235 case InUnitConf:
00236 if ( strcmp( SUCKY_CAST name, "dimensions" ) == 0 ) {
00237 level = InDimensions ;
00238 } else if ( strcmp( SUCKY_CAST name, "prefixes" ) == 0 ) {
00239 level = InPrefixes ;
00240 } else if ( strcmp( SUCKY_CAST name, "dimensiongroups" ) == 0 ) {
00241 level = InDimensionGroups ;
00242 } else if ( strcmp( SUCKY_CAST name, "unitsystems" ) == 0 ) {
00243 level = InUnitSystems ;
00244 } else {
00245 unknownRecover = level ;
00246 unknownDepth++ ;
00247 level = Unknown ;
00248 }
00249 break ;
00250 case InDimensions:
00251 emptyData( nameData ) ;
00252 chrData = '\0' ;
00253 if ( strcmp( SUCKY_CAST name, "dimension" ) == 0 ) {
00254 level = InDimension ;
00255 if ( attrs ) {
00256 for ( int i=0; attrs[i] ; i+=2 ) {
00257 if ( strcmp( SUCKY_CAST attrs[i], "char" ) == 0 )
00258 chrData = attrs[i+1][0] ;
00259 else
00260 fprintf( stderr, _("Expecting (char), got %s attrib.\n"), attrs[i]);
00261 }
00262 }
00263 } else {
00264 fprintf( stderr, _("Expecting dimension, got %s tag.\n"), name ) ;
00265 unknownRecover = level ;
00266 unknownDepth++ ;
00267 level = Unknown ;
00268 }
00269 break ;
00270 case InPrefixes:
00271 if ( strcmp( SUCKY_CAST name, "prefix" ) == 0 ) {
00272 level = InPrefix ;
00273 avoid = false ;
00274 emptyData( nameData ) ;
00275 emptyData( symData ) ;
00276 power = 0 ;
00277 if ( attrs ) {
00278 for ( int i=0; attrs[i] != 0 ; i++ ) {
00279 if ( strcmp( SUCKY_CAST attrs[i], "exponent" ) == 0 )
00280 power = atoi( SUCKY_CAST attrs[++i] ) ;
00281 else if ( strcmp( SUCKY_CAST attrs[i], "avoid" ) == 0 )
00282 avoid = tolower( attrs[++i][0] ) == 't' ;
00283 else
00284 fprintf( stderr, _("Expecting exponent or avoid, got %s attrib.\n"), attrs[i++] );
00285 }
00286 }
00287 } else {
00288 fprintf( stderr, _("Expecting dimension, got %s tag.\n"), name ) ;
00289 unknownRecover = level ;
00290 unknownDepth++ ;
00291 level = Unknown ;
00292 }
00293 break ;
00294 case InDimensionGroups:
00295 if ( strcmp( SUCKY_CAST name, "group" ) == 0 ) {
00296 level = InGroup ;
00297 grpPowers.clear() ;
00298 curGroup = new DimensionGroup ;
00299 emptyData( nameData ) ;
00300 } else {
00301 fprintf( stderr, _("Expecting group, got %s tag.\n"), name ) ;
00302 unknownRecover = level ;
00303 unknownDepth++ ;
00304 level = Unknown ;
00305 }
00306 break ;
00307 case InGroup:
00308 if ( strcmp( SUCKY_CAST name, "dimpower" ) == 0 ) {
00309 level = InDimPower ;
00310 chrData = '\0' ;
00311 power = 0 ;
00312 for ( int i=0; attrs[i] != 0 ; i++ ) {
00313 if ( strcmp( SUCKY_CAST attrs[i], "dim" ) == 0 )
00314 chrData = attrs[++i][0] ;
00315 else if ( strcmp( SUCKY_CAST attrs[i], "pwr" ) == 0 )
00316 power = atoi( SUCKY_CAST attrs[++i] ) ;
00317 else
00318 fprintf( stderr, _("Expecting dim, or pwr, got %s attrib.\n"), attrs[i++] );
00319 }
00320 // Handle attribs
00321 if ( (chrData=='\0') || !power || !curGroup ) {
00322 fprintf( stderr, _("Not all required attributes set or no group.\n") ) ;
00323 } else {
00324 Dimension* dimn = find_dsym( (char) chrData ) ;
00325 if ( ! dimn ) {
00326 fprintf( stderr, _("Expecting a base dimension symbol, got %c.\n"),
00327 chrData ) ;
00328 } else {
00329 grpPowers.push_back( DimensionPower( dimn, power ) ) ;
00330 }
00331 }
00332 } else if ( strcmp( SUCKY_CAST name, "unit" ) == 0 ) {
00333 level = InUnit ;
00334 emptyData( nameData ) ;
00335 emptyData( plurData ) ;
00336 emptyData( symData ) ;
00337 scale = dtNaN ;
00338 offset = dtNaN ;
00339 noPlural = false ;
00340 noPrefix = false ;
00341 avoid = false ;
00342 one = false ;
00343 for ( int i=0; attrs[i] != 0 ; i++ ) {
00344 if ( strcmp( SUCKY_CAST attrs[i], "scale" ) == 0 ) {
00345 scale = atof( SUCKY_CAST attrs[++i] ) ;
00346 //fprintf( stderr, "\t==>Unit(%s, %g)\n", name, scale ) ;
00347 } else if ( strcmp( SUCKY_CAST attrs[i], "offset" ) == 0 )
00348 offset = atof( SUCKY_CAST attrs[++i] ) ;
00349 else if ( strcmp( SUCKY_CAST attrs[i], "noplural" ) == 0 )
00350 noPlural = tolower( attrs[++i][0] ) == 't' ;
00351 else if ( strcmp( SUCKY_CAST attrs[i], "noprefix" ) == 0 )
00352 noPrefix = tolower( attrs[++i][0] ) == 't' ;
00353 else if ( strcmp( SUCKY_CAST attrs[i], "avoid" ) == 0 )
00354 avoid = tolower( attrs[++i][0] ) == 't' ;
00355 else if ( strcmp( SUCKY_CAST attrs[i], "one" ) == 0 )
00356 one = tolower( attrs[++i][0] ) == 't' ;
00357 else if ( strcmp( SUCKY_CAST attrs[i], "args" ) == 0 )
00358 i++ ; // ignore this for now
00359 else
00360 fprintf( stderr, _("Expecting (scale|offset|"
00361 "noplural|noprefix|avoid|one), got %s attrib.\n"),
00362 attrs[i++] );
00363 }
00364 } else if ( (strcmp( SUCKY_CAST name, "name" ) == 0) ||
00365 (strcmp( SUCKY_CAST name, "alias" ) == 0) ) {
00366 buflen = 0 ;
00367 rememberString = true ;
00368 } else {
00369 fprintf( stderr, _("Expecting dimpower or unit, got %s tag.\n"), name ) ;
00370 unknownRecover = level ;
00371 unknownDepth++ ;
00372 level = Unknown ;
00373 }
00374 break ;
00375 case InUnitSystems:
00376 // not handled yet
00377 if ( strcmp( SUCKY_CAST name, "system" ) == 0 ) {
00378 level = InSystem ;
00379 curSys = new UnitSystem ;
00380 // Handle attribs
00381 } else {
00382 fprintf( stderr, _("Expecting system, got %s tag.\n"), name ) ;
00383 unknownRecover = level ;
00384 unknownDepth++ ;
00385 level = Unknown ;
00386 }
00387 break ;
00388 case InSystem:
00389 if ( strcmp( SUCKY_CAST name, "stdunit" ) == 0 ) {
00390 level = InStdUnit ;
00391 // Handle attribs
00392
00393 } else if ( ( strcmp( SUCKY_CAST name, "name" ) == 0 ) ||
00394 ( strcmp( SUCKY_CAST name, "description" ) == 0 ) ||
00395 ( strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) ) {
00396 rememberString = true ;
00397 buflen = 0 ;
00398 } else {
00399 fprintf( stderr, _("Expecting (stdunit|name|abbrev|description), got %s tag.\n"), name ) ;
00400 unknownRecover = level ;
00401 unknownDepth++ ;
00402 level = Unknown ;
00403 }
00404 break ;
00405 case InPrefix:
00406 case InDimension:
00407 case InUnit:
00408 case InDimPower:
00409 case InStdUnit:
00410 if ( (strcmp( SUCKY_CAST name, "name" ) == 0 ) ||
00411 (strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) ||
00412 (strcmp( SUCKY_CAST name, "description" ) == 0 ) ||
00413 (strcmp( SUCKY_CAST name, "spec" ) == 0 ) ||
00414 (strcmp( SUCKY_CAST name, "group" ) == 0 ) ||
00415 (strcmp( SUCKY_CAST name, "dgroup" ) == 0 ) ||
00416 (strcmp( SUCKY_CAST name, "plural" ) == 0 ) ||
00417 (strcmp( SUCKY_CAST name, "alias" ) == 0 ) ) {
00418 buflen = 0 ;
00419 rememberString = true ;
00420 } else {
00421 fprintf( stderr, _("start %s: Go away, you shouldn't be here.\n"), SUCKY_CAST name ) ;
00422 unknownRecover = level ;
00423 unknownDepth++ ;
00424 level = Unknown ;
00425 }
00426 break ;
00427 case Unknown:
00428 unknownDepth++ ;
00429 }
00430 }
00431
00432 void UnitConfParserState::endElement( const CHAR* name )
00433 {
00434 #ifdef DBG_ENDELE
00435 fprintf( stderr, "[%s] endElement( %s )\n", stateNames[level], name ) ;
00436 #endif // DBG_ENDELE
00437
00438 switch (level) {
00439 case AtTop:
00440 fprintf( stderr, _("end %s: Go away, you shouldn't be here.\n"), SUCKY_CAST name ) ;
00441 break ;
00442 case InUnitConf:
00443 level = AtTop ;
00444 break ;
00445 case InPrefix:
00446 if ( strcmp( SUCKY_CAST name, "prefix" ) == 0 ) {
00447 if ( !nameData || !symData || !power )
00448 fprintf( stderr, _("Not all required attributes set.\n") ) ;
00449 else
00450 new Prefix( SUCKY_CAST nameData, SUCKY_CAST symData, power ) ;
00451 level = InPrefixes ;
00452 } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00453 copyBufferTo( nameData ) ;
00454 } else if ( strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) {
00455 copyBufferTo( symData ) ;
00456 }
00457 break ;
00458 case InDimension:
00459 if ( strcmp( SUCKY_CAST name, "dimension" ) == 0 ) {
00460 if ( (!nameData) || (chrData == '\0') ) {
00461 fprintf( stderr, _("Dimension must have a name and a character symbol.\n") ) ;
00462 } else {
00463 //fprintf( stderr, "\t==>Dimension(%s, %c)\n", nameData, chrData ) ;
00464 new Dimension( SUCKY_CAST nameData, (char) chrData ) ;
00465 }
00466 level = InDimensions ;
00467 } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00468 copyBufferTo( nameData ) ;
00469 }
00470 break ;
00471 case InGroup:
00472 if ( strcmp( SUCKY_CAST name, "group" ) == 0 ) {
00473 if ( curGroup ) {
00474 if ( ! curGroup->name() )
00475 fprintf( stderr, _("You must specify a group name.\n") ) ;
00476
00477 if ( grpPowers.size() > 0 ) {
00478 curGroup->setDimensions( grpPowers ) ;
00479 curGroup = 0 ;
00480 }
00481 }
00482
00483 level = InDimensionGroups ;
00484 } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00485 copyBufferTo( nameData ) ;
00486 if ( curGroup )
00487 curGroup->name( SUCKY_CAST nameData ) ;
00488 } else if ( strcmp( SUCKY_CAST name, "alias" ) == 0 ) {
00489 terminateBuffer() ;
00490
00491
00492
00493
00494 }
00495 break ;
00496 case InUnit:
00497 if ( strcmp( SUCKY_CAST name, "unit" ) == 0 ) {
00498 if ( !nameData || !curGroup || isnan(scale) ) {
00499 fprintf( stderr, _("Not all required attributes set or no group.\n") ) ;
00500 fprintf( stderr, "nameData=0x%x, symData=0x%x, scale=%g, curGroup=0x%x\n", nameData, symData, scale, curGroup ) ;
00501 } else {
00502 Unit* u ;
00503 if ( symData )
00504 u = new Unit( SUCKY_CAST nameData, SUCKY_CAST symData,
00505 scale, curGroup ) ;
00506 else // if no abbreviation, the unit name itself is used.
00507 u = new Unit( SUCKY_CAST nameData, SUCKY_CAST nameData,
00508 scale, curGroup ) ;
00509 u->prefix( !noPrefix ) ;
00510 u->avoid( avoid ) ;
00511 u->one( one ) ;
00512 if ( !isnan(offset) )
00513 u->offset( offset ) ;
00514 if ( noPlural ) {
00515 if ( plurData )
00516 fprintf( stderr, _("You cannot specify noplural and a plural form.\n") ) ;
00517 else
00518 u->plural( CITRUS_PLURAL_NONE ) ;
00519 } else {
00520 if ( plurData )
00521 u->plural( SUCKY_CAST plurData ) ;
00522 }
00523 if ( strcmp( SUCKY_CAST nameData, "none" ) == 0 )
00524 Unit::s_dimensionless = u ;
00525 emptyData( nameData ) ;
00526 emptyData( plurData ) ;
00527 emptyData( symData ) ;
00528 }
00529
00530 level = InGroup ;
00531 } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00532 copyBufferTo( nameData ) ;
00533 } else if ( strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) {
00534 copyBufferTo( symData ) ;
00535 } else if ( strcmp( SUCKY_CAST name, "plural" ) == 0 ) {
00536 copyBufferTo( plurData ) ;
00537 }
00538 break ;
00539 case InDimPower:
00540 level = InGroup ;
00541 break ;
00542 case InStdUnit:
00543 if ( strcmp( SUCKY_CAST name, "stdunit" ) == 0 ) {
00544 level = InSystem ;
00545 if ( curSys && nameData && symData ) {
00546 DimensionGroup* dgrp = DimensionGroup::find( SUCKY_CAST nameData ) ;
00547 if ( dgrp )
00548 if ( ! curSys->addSpec( dgrp, SUCKY_CAST symData ) )
00549 fprintf( stderr, "Bad specification for %s (%s=%s)\n",
00550 curSys->name(), nameData, symData ) ;
00551 }
00552 } else if ( strcmp( SUCKY_CAST name, "dgroup" ) == 0 ) {
00553 copyBufferTo( nameData ) ;
00554 } else if ( strcmp( SUCKY_CAST name, "spec" ) == 0 ) {
00555 copyBufferTo( symData ) ;
00556 }
00557 break ;
00558 case InSystem:
00559 if ( strcmp( SUCKY_CAST name, "system" ) == 0 ) {
00560 level = InUnitSystems ;
00561 curSys = 0 ;
00562 } else if ( strcmp( SUCKY_CAST name, "name" ) == 0 ) {
00563 terminateBuffer() ;
00564 if ( curSys )
00565 curSys->name( SUCKY_CAST buffer ) ;
00566 } else if ( strcmp( SUCKY_CAST name, "abbrev" ) == 0 ) {
00567 terminateBuffer() ;
00568 if ( curSys )
00569 curSys->abbr( SUCKY_CAST buffer ) ;
00570 } else if ( strcmp( SUCKY_CAST name, "description" ) == 0 ) {
00571 terminateBuffer() ;
00572 if ( curSys )
00573 curSys->description( SUCKY_CAST buffer ) ;
00574 }
00575 break ;
00576 case InDimensionGroups:
00577 case InDimensions:
00578 case InPrefixes:
00579 case InUnitSystems:
00580 level = InUnitConf ;
00581 break ;
00582 case Unknown:
00583 unknownDepth-- ;
00584 if ( unknownDepth == 0 )
00585 level = unknownRecover ;
00586 break ;
00587 }
00588 rememberString = false ;
00589 buflen = 0 ;
00590 }
00591
00592 void UnitConfParserState::characters( const CHAR* text, int len )
00593 {
00594 if ( ! rememberString )
00595 return ;
00596
00597 if ( len > bufmax - buflen ) {
00598 bufmax <<= 1 ;
00599 buffer = (CHAR*) realloc( buffer, sizeof(CHAR)*bufmax ) ;
00600 }
00601 memcpy( buffer + buflen, text, len*sizeof(CHAR) ) ;
00602 buflen += len*sizeof(CHAR) ;
00603 }
00604
00605 xmlEntityPtr UnitConfParserState::getEntity( const CHAR* name )
00606 {
00607 return xmlGetPredefinedEntity( name ) ;
00608 }
00609
00610 void UnitConfParserState::startDocument()
00611 {
00612 reset() ;
00613 }
00614
00615 void UnitConfParserState::endDocument()
00616 {
00617 if ( curGroup )
00618 delete curGroup ;
00619 if ( curSys )
00620 delete curSys ;
00621 }
00622
00623 void UnitConfParserState::reset()
00624 {
00625 // per document initialization (also called on construction)
00626 level = AtTop ;
00627 unknownRecover = AtTop ;
00628 unknownDepth = 0 ;
00629 curGroup = 0 ;
00630 curSys = 0 ;
00631 buflen = 0 ;
00632 rememberString = false ;
00633 emptyData( nameData ) ;
00634 emptyData( plurData ) ;
00635 emptyData( symData ) ;
00636 power = 0 ;
00637 scale = dtNaN ;
00638 offset = dtNaN ;
00639 }
00640
00641 void UnitConfParserState::terminateBuffer()
00642 {
00643 if ( buflen == bufmax ) {
00644 bufmax <<= 1 ;
00645 buffer = (CHAR*) realloc( buffer, sizeof(CHAR)*bufmax ) ;
00646 }
00647
00648 buffer[ buflen ] = CHAR('\0') ;
00649 }
00650
00651 void UnitConfParserState::copyBufferTo( CHAR*& string )
00652 {
00653 if ( string )
00654 emptyData( string ) ;
00655
00656 string = new CHAR[ buflen + 1 ] ;
00657 memcpy( string, buffer, buflen ) ;
00658 string[ buflen ] = CHAR('\0') ;
00659 }
00660
00661 void UnitConfParserState::emptyData( CHAR*& string )
00662 {
00663 if ( string )
00664 delete [] string ;
00665
00666 string = 0 ;
00667 }