Skip to content

Commit 20d6cc0

Browse files
authored
refactor(ini): Simplify token related INI code (#2596)
1 parent f40235c commit 20d6cc0

23 files changed

Lines changed: 66 additions & 102 deletions

File tree

Core/GameEngine/Include/Common/INI.h

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,11 @@ typedef void (*BuildMultiIniFieldProc)(MultiIniFieldParse& p);
160160
//-------------------------------------------------------------------------------------------------
161161
class INI
162162
{
163-
INI(const INI&);
164-
INI& operator=(const INI&);
163+
INI(const INI&) CPP_11(= delete);
164+
INI& operator=(const INI&) CPP_11(= delete);
165165

166166
public:
167-
168167
INI();
169-
~INI();
170168

171169
// TheSuperHackers @feature xezon 19/08/2025
172170
// Load a specific INI file by name and/or INI files from a directory (and its subdirectories).
@@ -251,11 +249,12 @@ class INI
251249
AsciiString getFilename() const { return m_filename; }
252250
INILoadType getLoadType() const { return m_loadType; }
253251
UnsignedInt getLineNum() const { return m_lineNum; }
254-
const char *getSeps() const { return m_seps; }
255-
const char *getSepsPercent() const { return m_sepsPercent; }
256-
const char *getSepsColon() const { return m_sepsColon; }
257-
const char *getSepsQuote() { return m_sepsQuote; }
258252
Bool isEOF() const { return m_endOfFile; }
253+
static const char *getSeps() { return " \n\r\t="; } ///< default delimiters for strtok parsing
254+
static const char *getSepsPercent() { return " \n\r\t=%%"; } ///< default delimiters & percent delimiter
255+
static const char *getSepsColon() { return " \n\r\t=:"; } ///< default delimiters & colon delimiter
256+
static const char *getSepsQuote() { return "\"\n="; } ///< delimiters to represent a quoted ascii string
257+
static const char *getEndToken() { return "End"; } ///< token to represent an end of data block
259258

260259
void initFromINI( void *what, const FieldParse* parseTable );
261260
void initFromINIMulti( void *what, const MultiIniFieldParse& parseTableList );
@@ -321,20 +320,19 @@ class INI
321320
static void parseVeterancyLevelFlags(INI* ini, void* instance, void* store, const void* userData);
322321
static void parseSoundsList( INI* ini, void *instance, void *store, const void* /*userData*/ );
323322

324-
325323
/**
326-
return the next token. if seps is null (or omitted), the standard seps are used.
324+
return the next token. if seps is not specified, the standard seps are used.
327325
328326
this will *never* return null; if there are no more tokens, an exception will be thrown.
329327
*/
330-
const char* getNextToken(const char* seps = nullptr);
328+
static const char* getNextToken(const char* seps = getSeps());
331329

332330
/**
333331
just like getNextToken(), except that null is returned if no more tokens are present
334332
(rather than throwing an exception). usually you should call getNextToken(),
335333
but for some cases this is handier (ie, parsing a variable-length number of tokens).
336334
*/
337-
const char* getNextTokenOrNull(const char* seps = nullptr);
335+
static const char* getNextTokenOrNull(const char* seps = getSeps());
338336

339337
/**
340338
This is called when the next thing you expect is something like:
@@ -346,7 +344,7 @@ class INI
346344
347345
If "Tag" is not the next token, an error is thrown.
348346
*/
349-
const char* getNextSubToken(const char* expected);
347+
static const char* getNextSubToken(const char* expected);
350348

351349
/**
352350
return the next ascii string. this is usually the same the result of getNextToken(),
@@ -400,14 +398,9 @@ class INI
400398
unsigned m_readBufferUsed; ///< number of bytes in read buffer
401399

402400
AsciiString m_filename; ///< filename of file currently loading
403-
INILoadType m_loadType; ///< load time for current file
401+
INILoadType m_loadType; ///< load type for current file
404402
UnsignedInt m_lineNum; ///< current line number that's been read
405403
char m_buffer[ INI_MAX_CHARS_PER_LINE+1 ];///< buffer to read file contents into
406-
const char *m_seps; ///< for strtok parsing
407-
const char *m_sepsPercent; ///< m_seps with percent delimiter as well
408-
const char *m_sepsColon; ///< m_seps with colon delimiter as well
409-
const char *m_sepsQuote; ///< token to represent a quoted ascii string
410-
const char *m_blockEndToken; ///< token to represent end of data block
411404
Bool m_endOfFile; ///< TRUE when we've hit EOF
412405
#ifdef DEBUG_CRASHING
413406
char m_curBlockStart[ INI_MAX_CHARS_PER_LINE+1 ]; ///< first line of cur block

Core/GameEngine/Source/Common/INI/INI.cpp

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -180,26 +180,14 @@ INI::INI()
180180
m_filename = "None";
181181
m_loadType = INI_LOAD_INVALID;
182182
m_lineNum = 0;
183-
m_seps = " \n\r\t="; ///< make sure you update m_sepsPercent/m_sepsColon as well
184-
m_sepsPercent = " \n\r\t=%%";
185-
m_sepsColon = " \n\r\t=:";
186-
m_sepsQuote = "\"\n="; ///< stop at " = EOL
187-
m_blockEndToken = "END";
188-
m_endOfFile = FALSE;
189183
m_buffer[0] = 0;
184+
m_endOfFile = FALSE;
190185
#ifdef DEBUG_CRASHING
191186
m_curBlockStart[0] = 0;
192187
#endif
193188

194189
}
195190

196-
//-------------------------------------------------------------------------------------------------
197-
//-------------------------------------------------------------------------------------------------
198-
INI::~INI()
199-
{
200-
201-
}
202-
203191
//-------------------------------------------------------------------------------------------------
204192
UnsignedInt INI::loadFileDirectory( AsciiString fileDirName, INILoadType loadType, Xfer *pXfer, Bool subdirs )
205193
{
@@ -397,7 +385,7 @@ UnsignedInt INI::load( AsciiString filename, INILoadType loadType, Xfer *pXfer )
397385
AsciiString currentLine = m_buffer;
398386

399387
// the first word is the type of data we're processing
400-
const char *token = strtok( m_buffer, m_seps );
388+
const char *token = strtok( m_buffer, getSeps() );
401389
if( token )
402390
{
403391
INIBlockParse parse = findBlockParse(token);
@@ -710,7 +698,7 @@ void INI::parseAsciiStringVector( INI* ini, void * /*instance*/, void *store, co
710698
{
711699
std::vector<AsciiString>* asv = (std::vector<AsciiString>*)store;
712700
asv->clear();
713-
for (const char *token = ini->getNextTokenOrNull(); token != nullptr; token = ini->getNextTokenOrNull())
701+
for (const char *token = ini->getNextTokenOrNull(); token; token = ini->getNextTokenOrNull())
714702
{
715703
asv->push_back(token);
716704
}
@@ -723,7 +711,7 @@ void INI::parseAsciiStringVectorAppend( INI* ini, void * /*instance*/, void *sto
723711
std::vector<AsciiString>* asv = (std::vector<AsciiString>*)store;
724712
// nope, don't clear. duh.
725713
// asv->clear();
726-
for (const char *token = ini->getNextTokenOrNull(); token != nullptr; token = ini->getNextTokenOrNull())
714+
for (const char *token = ini->getNextTokenOrNull(); token; token = ini->getNextTokenOrNull())
727715
{
728716
asv->push_back(token);
729717
}
@@ -735,7 +723,7 @@ void INI::parseAsciiStringVectorAppend( INI* ini, void * /*instance*/, void *sto
735723
{
736724
ScienceVec* asv = (ScienceVec*)store;
737725
asv->clear();
738-
for (const char *token = ini->getNextTokenOrNull(); token != nullptr; token = ini->getNextTokenOrNull())
726+
for (const char *token = ini->getNextTokenOrNull(); token; token = ini->getNextTokenOrNull())
739727
{
740728
if (stricmp(token, "None") == 0)
741729
{
@@ -952,7 +940,7 @@ void INI::parseBitString32( INI* ini, void * /*instance*/, void *store, const vo
952940
Bool foundAddOrSub = false;
953941

954942
// loop through all tokens
955-
for (const char *token = ini->getNextTokenOrNull(); token != nullptr; token = ini->getNextTokenOrNull())
943+
for (const char *token = ini->getNextTokenOrNull(); token; token = ini->getNextTokenOrNull())
956944
{
957945
if (stricmp(token, "NONE") == 0)
958946
{
@@ -1528,7 +1516,7 @@ void INI::initFromINIMulti( void *what, const MultiIniFieldParse& parseTableList
15281516
if( field )
15291517
{
15301518

1531-
if( stricmp( field, m_blockEndToken ) == 0 )
1519+
if( stricmp( field, getEndToken() ) == 0 )
15321520
{
15331521
done = TRUE;
15341522
}
@@ -1580,7 +1568,7 @@ void INI::initFromINIMulti( void *what, const MultiIniFieldParse& parseTableList
15801568

15811569
done = TRUE;
15821570
DEBUG_CRASH( ("Error parsing block '%s', in INI file '%s'. Missing '%s' token",
1583-
m_curBlockStart, getFilename().str(), m_blockEndToken) );
1571+
m_curBlockStart, getFilename().str(), getEndToken()) );
15841572
throw INI_MISSING_END_TOKEN;
15851573

15861574
}
@@ -1592,7 +1580,6 @@ void INI::initFromINIMulti( void *what, const MultiIniFieldParse& parseTableList
15921580
//-------------------------------------------------------------------------------------------------
15931581
/*static*/ const char* INI::getNextToken(const char* seps)
15941582
{
1595-
if (!seps) seps = getSeps();
15961583
const char *token = ::strtok(nullptr, seps);
15971584
if (!token)
15981585
throw INI_INVALID_DATA;
@@ -1602,7 +1589,6 @@ void INI::initFromINIMulti( void *what, const MultiIniFieldParse& parseTableList
16021589
//-------------------------------------------------------------------------------------------------
16031590
/*static*/ const char* INI::getNextTokenOrNull(const char* seps)
16041591
{
1605-
if (!seps) seps = getSeps();
16061592
const char *token = ::strtok(nullptr, seps);
16071593
return token;
16081594
}
@@ -1876,12 +1862,10 @@ void INI::parseSoundsList( INI* ini, void *instance, void *store, const void* /*
18761862
std::vector<AsciiString> *vec = (std::vector<AsciiString>*) store;
18771863
vec->clear();
18781864

1879-
const char* SEPS = " \t,=";
1880-
const char *c = ini->getNextTokenOrNull(SEPS);
1881-
while ( c )
1865+
constexpr const char* Seps = " \t,=";
1866+
for (const char* token = ini->getNextTokenOrNull(Seps); token; token = ini->getNextTokenOrNull(Seps))
18821867
{
1883-
vec->push_back( c );
1884-
c = ini->getNextTokenOrNull(SEPS);
1868+
vec->push_back(token);
18851869
}
18861870
}
18871871

Generals/Code/GameEngine/Include/Common/BitFlagsIO.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void BitFlags<NUMBITS>::parse(INI* ini, AsciiString* str)
6767
Bool foundAddOrSub = false;
6868

6969
// loop through all tokens
70-
for (const char *token = ini->getNextTokenOrNull(); token != nullptr; token = ini->getNextTokenOrNull())
70+
for (const char *token = ini->getNextTokenOrNull(); token; token = ini->getNextTokenOrNull())
7171
{
7272
if (str)
7373
{

Generals/Code/GameEngine/Source/Common/Thing/ThingTemplate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ static void parsePrerequisiteUnit( INI* ini, void *instance, void * /*store*/, c
548548

549549
ProductionPrerequisite prereq;
550550
Bool orUnitWithPrevious = FALSE;
551-
for (const char *token = ini->getNextToken(); token != nullptr; token = ini->getNextTokenOrNull())
551+
for (const char *token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
552552
{
553553
prereq.addUnitPrereq( AsciiString( token ), orUnitWithPrevious );
554554
orUnitWithPrevious = TRUE;

Generals/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,10 @@ TurretAIData::TurretAIData()
202202
static void parseTWS(INI* ini, void * /*instance*/, void * store, const void* /*userData*/)
203203
{
204204
UnsignedInt* tws = (UnsignedInt*)store;
205-
const char* token = ini->getNextToken();
206-
while (token != nullptr)
205+
for (const char* token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
207206
{
208207
WeaponSlotType wslot = (WeaponSlotType)INI::scanIndexList(token, TheWeaponSlotTypeNames);
209208
*tws |= (1 << wslot);
210-
token = ini->getNextTokenOrNull();
211209
}
212210
}
213211

Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/InstantDeathBehavior.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ InstantDeathBehaviorModuleData::InstantDeathBehaviorModuleData()
6262
static void parseFX( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ )
6363
{
6464
InstantDeathBehaviorModuleData* self = (InstantDeathBehaviorModuleData*)instance;
65-
for (const char* token = ini->getNextToken(); token != nullptr; token = ini->getNextTokenOrNull())
65+
for (const char* token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
6666
{
6767
const FXList *fxl = TheFXListStore->findFXList((token)); // could be null! this is OK!
6868
self->m_fx.push_back(fxl);
@@ -73,7 +73,7 @@ static void parseFX( INI* ini, void *instance, void * /*store*/, const void* /*u
7373
static void parseOCL( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ )
7474
{
7575
InstantDeathBehaviorModuleData* self = (InstantDeathBehaviorModuleData*)instance;
76-
for (const char* token = ini->getNextToken(); token != nullptr; token = ini->getNextTokenOrNull())
76+
for (const char* token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
7777
{
7878
const ObjectCreationList *ocl = TheObjectCreationListStore->findObjectCreationList(token); // could be null! this is OK!
7979
self->m_ocls.push_back(ocl);
@@ -84,7 +84,7 @@ static void parseOCL( INI* ini, void *instance, void * /*store*/, const void* /*
8484
static void parseWeapon( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ )
8585
{
8686
InstantDeathBehaviorModuleData* self = (InstantDeathBehaviorModuleData*)instance;
87-
for (const char* token = ini->getNextToken(); token != nullptr; token = ini->getNextTokenOrNull())
87+
for (const char* token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
8888
{
8989
const WeaponTemplate *wt = TheWeaponStore->findWeaponTemplate(token); // could be null! this is OK!
9090
self->m_weapons.push_back(wt);

Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/SlowDeathBehavior.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ static void parseFX( INI* ini, void *instance, void * /*store*/, const void* /*u
8181
{
8282
SlowDeathBehaviorModuleData* self = (SlowDeathBehaviorModuleData*)instance;
8383
SlowDeathPhaseType sdphase = (SlowDeathPhaseType)INI::scanIndexList(ini->getNextToken(), TheSlowDeathPhaseNames);
84-
for (const char* token = ini->getNextToken(); token != nullptr; token = ini->getNextTokenOrNull())
84+
for (const char* token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
8585
{
8686
const FXList *fxl = TheFXListStore->findFXList((token)); // could be null! this is OK!
8787
self->m_fx[sdphase].push_back(fxl);
@@ -95,7 +95,7 @@ static void parseOCL( INI* ini, void *instance, void * /*store*/, const void* /*
9595
{
9696
SlowDeathBehaviorModuleData* self = (SlowDeathBehaviorModuleData*)instance;
9797
SlowDeathPhaseType sdphase = (SlowDeathPhaseType)INI::scanIndexList(ini->getNextToken(), TheSlowDeathPhaseNames);
98-
for (const char* token = ini->getNextToken(); token != nullptr; token = ini->getNextTokenOrNull())
98+
for (const char* token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
9999
{
100100
const ObjectCreationList *ocl = TheObjectCreationListStore->findObjectCreationList(token); // could be null! this is OK!
101101
self->m_ocls[sdphase].push_back(ocl);
@@ -109,7 +109,7 @@ static void parseWeapon( INI* ini, void *instance, void * /*store*/, const void*
109109
{
110110
SlowDeathBehaviorModuleData* self = (SlowDeathBehaviorModuleData*)instance;
111111
SlowDeathPhaseType sdphase = (SlowDeathPhaseType)INI::scanIndexList(ini->getNextToken(), TheSlowDeathPhaseNames);
112-
for (const char* token = ini->getNextToken(); token != nullptr; token = ini->getNextTokenOrNull())
112+
for (const char* token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
113113
{
114114
const WeaponTemplate *wt = TheWeaponStore->findWeaponTemplate(token); // could be null! this is OK!
115115
self->m_weapons[sdphase].push_back(wt);

Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,12 +1351,12 @@ class GenericObjectCreationNugget : public ObjectCreationNugget
13511351
static void parseDebrisObjectNames( INI* ini, void *instance, void *store, const void* /*userData*/ )
13521352
{
13531353
GenericObjectCreationNugget* debrisNugget = (GenericObjectCreationNugget*)instance;
1354-
for (const char* debrisName = ini->getNextToken(); debrisName; debrisName = ini->getNextTokenOrNull())
1354+
for (const char* token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
13551355
{
13561356
if (TheGlobalData->m_preloadAssets)
1357-
debrisModelNamesGlobalHack.push_back(debrisName);
1358-
debrisNugget->m_names.push_back(AsciiString(debrisName));
1359-
debrisName = ini->getNextTokenOrNull();
1357+
debrisModelNamesGlobalHack.push_back(token);
1358+
debrisNugget->m_names.push_back(AsciiString(token));
1359+
token = ini->getNextTokenOrNull();
13601360
}
13611361
}
13621362

Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,16 +172,16 @@ const LocomotorTemplateVector* AIUpdateModuleData::findLocomotorTemplateVector(L
172172
}
173173

174174
self->m_locomotorTemplates[set].clear();
175-
for (const char* locoName = ini->getNextToken(); locoName; locoName = ini->getNextTokenOrNull())
175+
for (const char* token = ini->getNextToken(); token; token = ini->getNextTokenOrNull())
176176
{
177-
if (!*locoName || stricmp(locoName, "None") == 0)
177+
if (!*token || stricmp(token, "None") == 0)
178178
continue;
179179

180-
NameKeyType locoKey = NAMEKEY(locoName);
180+
NameKeyType locoKey = NAMEKEY(token);
181181
const LocomotorTemplate* lt = TheLocomotorStore->findLocomotorTemplate(locoKey);
182182
if (!lt)
183183
{
184-
DEBUG_CRASH(("Locomotor %s not found!",locoName));
184+
DEBUG_CRASH(("Locomotor %s not found!",token));
185185
throw INI_INVALID_DATA;
186186
}
187187
self->m_locomotorTemplates[set].push_back(lt);

Generals/Code/GameEngine/Source/GameLogic/Object/Update/AutoDepositUpdate.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,9 @@ void parseUpgradePair( INI *ini, void *instance, void *store, const void *userDa
7474
info.amount = 0;
7575

7676
const char *token = ini->getNextToken( ini->getSepsColon() );
77-
7877
if ( stricmp(token, "UpgradeType") == 0 )
7978
{
80-
token = ini->getNextTokenOrNull( ini->getSepsColon() );
81-
if (!token) throw INI_INVALID_DATA;
82-
79+
token = ini->getNextToken( ini->getSepsColon() );
8380
info.type = token;
8481
}
8582
else

0 commit comments

Comments
 (0)