| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: INI.h ////////////////////////////////////////////////////////////////////////////////////
- // Author: Colin Day, November 2001
- // Desc: INI Reader
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- #pragma once
- #ifndef __INI_H_
- #define __INI_H_
- // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
- #include <stddef.h> // for offsetof, which we don't use but everyone who includes us does
- #include "Common/STLTypedefs.h"
- #include "Common/AsciiString.h"
- #include "Common/GameCommon.h"
- //-------------------------------------------------------------------------------------------------
- class INI;
- class Xfer;
- class File;
- enum ScienceType;
- //-------------------------------------------------------------------------------------------------
- /** These control the behavior of loading the INI data into items */
- //-------------------------------------------------------------------------------------------------
- enum INILoadType
- {
- INI_LOAD_INVALID, ///< invalid load type
- INI_LOAD_OVERWRITE, ///< create new or load *over* existing data instance
- INI_LOAD_CREATE_OVERRIDES, ///< create new or load into *new* override data instance
- INI_LOAD_MULTIFILE ///< create new or continue loading into existing data instance.
- };
- //-------------------------------------------------------------------------------------------------
- /** INI constant defines */
- //-------------------------------------------------------------------------------------------------
- enum
- {
- INI_MAX_CHARS_PER_LINE = 1028, ///< max characters per line entry in any ini file
- };
- //-------------------------------------------------------------------------------------------------
- /** Status return codes for the INI reader */
- //-------------------------------------------------------------------------------------------------
- enum
- {
- // we map all of these to the same "real" error code, because
- // we generally don't care why it failed; but since the code distinguishes,
- // I didn't want to wipe out that intelligence. if we ever need to distinguish
- // failure modes at runtime, just put in real values for these.
- INI_CANT_SEARCH_DIR = ERROR_BAD_INI,
- INI_INVALID_DIRECTORY = ERROR_BAD_INI,
- INI_INVALID_PARAMS = ERROR_BAD_INI,
- INI_INVALID_NAME_LIST = ERROR_BAD_INI,
- INI_INVALID_DATA = ERROR_BAD_INI,
- INI_MISSING_END_TOKEN = ERROR_BAD_INI,
- INI_UNKNOWN_TOKEN = ERROR_BAD_INI,
- INI_BUFFER_TOO_SMALL = ERROR_BAD_INI,
- INI_FILE_NOT_OPEN = ERROR_BAD_INI,
- INI_FILE_ALREADY_OPEN = ERROR_BAD_INI,
- INI_CANT_OPEN_FILE = ERROR_BAD_INI,
- INI_UNKNOWN_ERROR = ERROR_BAD_INI,
- INI_END_OF_FILE = ERROR_BAD_INI
- };
- //-------------------------------------------------------------------------------------------------
- /** Function typedef for parsing data block fields.
- *
- * buffer - the character buffer of the line from INI that we are reading and parsing
- * instance - instance of what we're loading (for example a thingtemplate instance)
- * store - where to store the data parsed, this is a field in the *instance* 'instance'
- */
- //-------------------------------------------------------------------------------------------------
- typedef void (*INIFieldParseProc)( INI *ini, void *instance, void *store, const void* userData );
- //-------------------------------------------------------------------------------------------------
- typedef const char* ConstCharPtr;
- typedef const ConstCharPtr* ConstCharPtrArray;
- //-------------------------------------------------------------------------------------------------
- struct LookupListRec
- {
- const char* name;
- Int value;
- };
- typedef const LookupListRec *ConstLookupListRecArray;
- //-------------------------------------------------------------------------------------------------
- /** Parse tables for all fields of each data block are created using these */
- //-------------------------------------------------------------------------------------------------
- struct FieldParse
- {
- const char* token; ///< token of the field
- INIFieldParseProc parse; ///< the parse function
- const void* userData; ///< field-specific data
- Int offset; ///< offset to data field
- inline void set(const char* t, INIFieldParseProc p, const void* u, Int o)
- {
- token = t;
- parse = p;
- userData = u;
- offset = o;
- }
- };
- //-------------------------------------------------------------------------------------------------
- class MultiIniFieldParse
- {
- private:
- enum { MAX_MULTI_FIELDS = 16 };
- const FieldParse* m_fieldParse[MAX_MULTI_FIELDS];
- UnsignedInt m_extraOffset[MAX_MULTI_FIELDS];
- Int m_count;
- public:
- MultiIniFieldParse() : m_count(0)
- {
- //Added By Sadullah Nader
- //Initializations missing and needed
- for(Int i = 0; i < MAX_MULTI_FIELDS; i++)
- m_extraOffset[i] = 0;
- //
- }
-
- void add(const FieldParse* f, UnsignedInt e = 0);
- inline Int getCount() const { return m_count; }
- inline const FieldParse* getNthFieldParse(Int i) const { return m_fieldParse[i]; }
- inline UnsignedInt getNthExtraOffset(Int i) const { return m_extraOffset[i]; }
- };
- //-------------------------------------------------------------------------------------------------
- /** Function typedef for parsing INI types blocks */
- //-------------------------------------------------------------------------------------------------
- typedef void (*INIBlockParse)( INI *ini );
- typedef void (*BuildMultiIniFieldProc)(MultiIniFieldParse& p);
- //-------------------------------------------------------------------------------------------------
- /** INI Reader interface */
- //-------------------------------------------------------------------------------------------------
- class INI
- {
- public:
- INI();
- ~INI();
- void loadDirectory( AsciiString dirName, Bool subdirs, INILoadType loadType, Xfer *pXfer ); ///< load directory of INI files
- void load( AsciiString filename, INILoadType loadType, Xfer *pXfer ); ///< load INI file
- static Bool isDeclarationOfType( AsciiString blockType, AsciiString blockName, char *bufferToCheck );
- static Bool isEndOfBlock( char *bufferToCheck );
- // data type parsing (the highest level of what type of thing we're parsing)
- static void parseObjectDefinition( INI *ini );
- static void parseObjectReskinDefinition( INI *ini );
- static void parseWeaponTemplateDefinition( INI *ini );
- static void parseScienceDefinition( INI *ini );
- static void parseRankDefinition( INI *ini );
- static void parseCrateTemplateDefinition( INI *ini );
- static void parseLocomotorTemplateDefinition( INI *ini );
- static void parseLanguageDefinition( INI *ini );
- static void parsePlayerTemplateDefinition( INI *ini );
- static void parseGameDataDefinition( INI *ini );
- static void parseMapDataDefinition( INI *ini );
- static void parseAnim2DDefinition( INI *ini );
- static void parseAudioEventDefinition( INI *ini );
- static void parseDialogDefinition( INI *ini );
- static void parseMusicTrackDefinition( INI *ini );
- static void parseWebpageURLDefinition( INI *ini );
- static void parseHeaderTemplateDefinition( INI *ini );
- static void parseParticleSystemDefinition( INI *ini );
- static void parseWaterSettingDefinition( INI *ini );
- static void parseWaterTransparencyDefinition( INI *ini );
- static void parseMappedImageDefinition( INI *ini );
- static void parseArmorDefinition( INI *ini );
- static void parseDamageFXDefinition( INI *ini );
- static void parseDrawGroupNumberDefinition( INI *ini );
- static void parseTerrainDefinition( INI *ini );
- static void parseTerrainRoadDefinition( INI *ini );
- static void parseTerrainBridgeDefinition( INI *ini );
- static void parseMetaMapDefinition( INI *ini );
- static void parseFXListDefinition( INI *ini );
- static void parseObjectCreationListDefinition( INI* ini );
- static void parseMultiplayerSettingsDefinition( INI* ini );
- static void parseMultiplayerColorDefinition( INI* ini );
- static void parseOnlineChatColorDefinition( INI* ini );
- static void parseMapCacheDefinition( INI* ini );
- static void parseVideoDefinition( INI* ini );
- static void parseCommandButtonDefinition( INI *ini );
- static void parseCommandSetDefinition( INI *ini );
- static void parseUpgradeDefinition( INI *ini );
- static void parseMouseDefinition( INI* ini );
- static void parseMouseCursorDefinition( INI* ini );
- static void parseAIDataDefinition( INI *ini );
- static void parseSpecialPowerDefinition( INI *ini );
- static void parseInGameUIDefinition( INI *ini );
- static void parseControlBarSchemeDefinition( INI *ini );
- static void parseControlBarResizerDefinition( INI *ini );
- static void parseShellMenuSchemeDefinition( INI *ini );
- static void parseCampaignDefinition( INI *ini );
- static void parseAudioSettingsDefinition( INI *ini );
- static void parseMiscAudio( INI *ini );
- static void parseStaticGameLODDefinition( INI *ini);
- static void parseDynamicGameLODDefinition( INI *ini);
- static void parseStaticGameLODLevel( INI* ini, void * , void *store, const void*);
- static void parseDynamicGameLODLevel( INI* ini, void * , void *store, const void*);
- static void parseLODPreset( INI* ini);
- static void parseBenchProfile( INI* ini);
- static void parseEvaEvent( INI* ini );
- static void parseCredits( INI* ini );
- static void parseWindowTransitions( INI* ini );
- inline AsciiString getFilename( void ) const { return m_filename; }
- inline INILoadType getLoadType( void ) const { return m_loadType; }
- inline UnsignedInt getLineNum( void ) const { return m_lineNum; }
- inline const char *getSeps( void ) const { return m_seps; }
- inline const char *getSepsPercent( void ) const { return m_sepsPercent; }
- inline const char *getSepsColon( void ) const { return m_sepsColon; }
- inline const char *getSepsQuote( void ) { return m_sepsQuote; }
- inline Bool isEOF( void ) const { return m_endOfFile; }
- void initFromINI( void *what, const FieldParse* parseTable );
- void initFromINIMulti( void *what, const MultiIniFieldParse& parseTableList );
- void initFromINIMultiProc( void *what, BuildMultiIniFieldProc proc );
-
- static void parseUnsignedByte( INI *ini, void *instance, void *store, const void* userData );
- static void parseShort( INI *ini, void *instance, void *store, const void* userData );
- static void parseUnsignedShort( INI *ini, void *instance, void *store, const void* userData );
- static void parseInt( INI *ini, void *instance, void *store, const void* userData );
- static void parseUnsignedInt( INI *ini, void *instance, void *store, const void* userData );
- static void parseReal( INI *ini, void *instance, void *store, const void* userData );
- static void parsePositiveNonZeroReal( INI *ini, void *instance, void *store, const void* userData );
- static void parseBool( INI *ini, void *instance, void *store, const void* userData );
- static void parseBitInInt32( INI *ini, void *instance, void *store, const void* userData );
- static void parseAsciiString( INI *ini, void *instance, void *store, const void* userData );
- static void parseQuotedAsciiString( INI *ini, void *instance, void *store, const void* userData );
- static void parseAsciiStringVector( INI *ini, void *instance, void *store, const void* userData );
- static void parseAsciiStringVectorAppend( INI *ini, void *instance, void *store, const void* userData );
- static void parseAndTranslateLabel( INI *ini, void *instance, void *store, const void* userData );
- static void parseMappedImage( INI *ini, void *instance, void *store, const void *userData );
- static void parseAnim2DTemplate( INI *ini, void *instance, void *store, const void *userData );
- static void parsePercentToReal( INI *ini, void *instance, void *store, const void* userData );
- static void parseRGBColor( INI *ini, void *instance, void *store, const void* userData );
- static void parseRGBAColorInt( INI *ini, void *instance, void *store, const void* userData );
- static void parseColorInt( INI *ini, void *instance, void *store, const void* userData );
- static void parseCoord3D( INI *ini, void *instance, void *store, const void* userData );
- static void parseCoord2D( INI *ini, void *instance, void *store, const void *userData );
- static void parseICoord2D( INI *ini, void *instance, void *store, const void *userData );
- static void parseDynamicAudioEventRTS( INI *ini, void *instance, void *store, const void* userData );
- static void parseAudioEventRTS( INI *ini, void *instance, void *store, const void* userData );
- static void parseFXList( INI *ini, void *instance, void *store, const void* userData );
- static void parseParticleSystemTemplate( INI *ini, void *instance, void *store, const void *userData );
- static void parseObjectCreationList( INI *ini, void *instance, void *store, const void* userData );
- static void parseSpecialPowerTemplate( INI *ini, void *instance, void *store, const void *userData );
- static void parseUpgradeTemplate( INI *ini, void *instance, void *store, const void *userData );
- static void parseScience( INI *ini, void *instance, void *store, const void *userData );
- static void parseScienceVector( INI *ini, void *instance, void *store, const void *userData );
- static void parseGameClientRandomVariable( INI* ini, void *instance, void *store, const void* userData );
- static void parseBitString8( INI *ini, void *instance, void *store, const void* userData );
- static void parseBitString32( INI *ini, void *instance, void *store, const void* userData );
- static void parseByteSizedIndexList( INI *ini, void *instance, void *store, const void* userData );
- static void parseIndexList( INI *ini, void *instance, void *store, const void* userData );
- static void parseLookupList( INI *ini, void *instance, void *store, const void* userData );
- static void parseThingTemplate( INI *ini, void *instance, void *store, const void* userData );
- static void parseArmorTemplate( INI *ini, void *instance, void *store, const void* userData );
- static void parseDamageFX( INI *ini, void *instance, void *store, const void* userData );
- static void parseWeaponTemplate( INI *ini, void *instance, void *store, const void* userData );
- // parse a duration in msec and convert to duration in frames
- static void parseDurationReal( INI *ini, void *instance, void *store, const void* userData );
- // parse a duration in msec and convert to duration in integral number of frames, (unsignedint) rounding UP
- static void parseDurationUnsignedInt( INI *ini, void *instance, void *store, const void* userData );
- static void parseDurationUnsignedShort( INI *ini, void *instance, void *store, const void *userData );
- // parse acceleration in (dist/sec) and convert to (dist/frame)
- static void parseVelocityReal( INI *ini, void *instance, void *store, const void* userData );
- // parse acceleration in (dist/sec^2) and convert to (dist/frame^2)
- static void parseAccelerationReal( INI *ini, void *instance, void *store, const void* userData );
- // parse angle in degrees and convert to radians
- static void parseAngleReal( INI *ini, void *instance, void *store, const void *userData );
- // note that this parses in degrees/sec, and converts to rads/frame!
- static void parseAngularVelocityReal( INI *ini, void *instance, void *store, const void *userData );
- static void parseDamageTypeFlags(INI* ini, void* instance, void* store, const void* userData);
- static void parseDeathTypeFlags(INI* ini, void* instance, void* store, const void* userData);
- static void parseVeterancyLevelFlags(INI* ini, void* instance, void* store, const void* userData);
- static void parseSoundsList( INI* ini, void *instance, void *store, const void* /*userData*/ );
-
-
- /**
- return the next token. if seps is null (or omitted), the standard seps are used.
-
- this will *never* return null; if there are no more tokens, an exception will be thrown.
- */
- const char* getNextToken(const char* seps = NULL);
- /**
- just like getNextToken(), except that null is returned if no more tokens are present
- (rather than throwing an exception). usually you should call getNextToken(),
- but for some cases this is handier (ie, parsing a variable-length number of tokens).
- */
- const char* getNextTokenOrNull(const char* seps = NULL);
- /**
- This is called when the next thing you expect is something like:
-
- Tag:value
- pass "Tag" (without the colon) for 'expected', and you will have the 'value'
- token returned.
- If "Tag" is not the next token, an error is thrown.
- */
- const char* getNextSubToken(const char* expected);
- /**
- return the next ascii string. this is usually the same the result of getNextToken(),
- except that it allows for quote-delimited strings (eg, "foo bar"), so you can
- get strings with spaces, and/or empty strings.
- */
- AsciiString getNextAsciiString();
- AsciiString getNextQuotedAsciiString(); //fixed version of above. We can't fix the regular one for fear of breaking existing code. :-(
- /**
- utility routine that does a sscanf() on the string to get the Science, and throws
- an exception if not of the right form.
- */
- static ScienceType scanScience(const char* token);
- /**
- utility routine that does a sscanf() on the string to get the int, and throws
- an exception if not of the right form.
- */
- static Int scanInt(const char* token);
- /**
- utility routine that does a sscanf() on the string to get the unsigned int, and throws
- an exception if not of the right form.
- */
- static UnsignedInt scanUnsignedInt(const char* token);
- /**
- utility routine that does a sscanf() on the string to get the real, and throws
- an exception if not of the right form.
- */
- static Real scanReal(const char* token);
- static Real scanPercentToReal(const char* token);
- static Int scanIndexList(const char* token, ConstCharPtrArray nameList);
- static Int scanLookupList(const char* token, ConstLookupListRecArray lookupList);
- static Bool scanBool(const char* token);
- protected:
- static Bool isValidINIFilename( const char *filename ); ///< is this a valid .ini filename
- void prepFile( AsciiString filename, INILoadType loadType );
- void unPrepFile();
- void readLine( void );
- // FILE *m_file; ///< file pointer of file currently loading
- File *m_file; ///< file pointer of file currently loading
- AsciiString m_filename; ///< filename of file currently loading
- INILoadType m_loadType; ///< load time for current file
- UnsignedInt m_lineNum; ///< current line number that's been read
- char m_buffer[ INI_MAX_CHARS_PER_LINE ]; ///< buffer to read file contents into
- const char *m_seps; ///< for strtok parsing
- const char *m_sepsPercent; ///< m_seps with percent delimiter as well
- const char *m_sepsColon; ///< m_seps with colon delimiter as well
- const char *m_sepsQuote; ///< token to represent a quoted ascii string
- const char *m_blockEndToken; ///< token to represent end of data block
- Bool m_endOfFile; ///< TRUE when we've hit EOF
- #if defined(_DEBUG) || defined(_INTERNAL)
- char m_curBlockStart[ INI_MAX_CHARS_PER_LINE ]; ///< first line of cur block
- #endif
- };
- #endif // __INI_H_
|