From ca5561c395332b266b73b9cb56c50d1cc3c275c5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 5 Aug 2013 15:24:23 +0200 Subject: [PATCH] cIniFile now reads .example.ini if not requested not to. As specified in #44, when the .ini file cannot be opened, a .example.ini is tried, and if it succeeds, it is written as .ini. This makes it easy to provide ini file templates. --- iniFile/iniFile.cpp | 879 ++++++++++++++++++++++++---------------- iniFile/iniFile.h | 198 +++++---- source/GroupManager.cpp | 7 +- source/Root.cpp | 17 +- 4 files changed, 644 insertions(+), 457 deletions(-) diff --git a/iniFile/iniFile.cpp b/iniFile/iniFile.cpp index 76f71284f..5ecbc5e06 100644 --- a/iniFile/iniFile.cpp +++ b/iniFile/iniFile.cpp @@ -12,17 +12,13 @@ ////////////////////////////////////////////////////////////////////// /* - !! MODIFIED BY FAKETRUTH !! +!! MODIFIED BY FAKETRUTH and xoft !! */ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules // C++ Includes -#include #include -#include - -using namespace std; // C Includes #include @@ -31,26 +27,32 @@ using namespace std; #include "iniFile.h" #if defined(WIN32) -#define iniEOL endl + #define iniEOL endl #else -#define iniEOL '\r' << endl + #define iniEOL '\r' << endl #endif #ifndef _WIN32 -#define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__)) + #define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__)) #endif +using namespace std; -cIniFile::cIniFile( const string iniPath) + +cIniFile::cIniFile(const string & a_Path) : + m_IsCaseInsensitive(true) { - Path( iniPath); - caseInsensitive = true; + Path(a_Path); } -bool cIniFile::ReadFile() + + + + +bool cIniFile::ReadFile(bool a_AllowExampleRedirect) { // Normally you would use ifstream, but the SGI CC compiler has // a few bugs with ifstream. So ... fstream used. @@ -58,12 +60,31 @@ bool cIniFile::ReadFile() string line; string keyname, valuename, value; string::size_type pLeft, pRight; + bool IsFromExampleRedirect = false; + + f.open((FILE_IO_PREFIX + m_Path).c_str(), ios::in); + if (f.fail()) + { + f.clear(); + if (a_AllowExampleRedirect) + { + // Retry with the .example.ini file instead of .ini: + string ExPath(m_Path.substr(0, m_Path.length() - 4)); + ExPath.append(".example.ini"); + f.open((FILE_IO_PREFIX + ExPath).c_str(), ios::in); + if (f.fail()) + { + return false; + } + IsFromExampleRedirect = true; + } + else + { + return false; + } + } - f.open( (FILE_IO_PREFIX + path).c_str(), ios::in); - if ( f.fail()) - return false; - - while (getline( f, line)) + while (getline(f, line)) { // To be compatible with Win32, check for existence of '\r'. // Win32 files have the '\r' and Unix files don't at the end of a line. @@ -75,49 +96,49 @@ bool cIniFile::ReadFile() { continue; } - if ( line[lineLength - 1] == '\r') + if (line[lineLength - 1] == '\r') { - line = line.substr( 0, lineLength - 1); + line = line.substr(0, lineLength - 1); } if (line.length() == 0) { continue; } - + // Check that the user hasn't opened a binary file by checking the first // character of each line! - if ( !isprint( line[0])) + if (!isprint(line[0])) { - printf( "Failing on char %d\n", line[0]); + printf("%s: Binary-check failed on char %d\n", __FUNCTION__, line[0]); f.close(); return false; } - if (( pLeft = line.find_first_of(";#[=")) == string::npos) + if ((pLeft = line.find_first_of(";#[=")) == string::npos) { continue; } - - switch ( line[pLeft]) + + switch (line[pLeft]) { case '[': { if ( ((pRight = line.find_last_of("]")) != string::npos) && (pRight > pLeft) - ) + ) { - keyname = line.substr( pLeft + 1, pRight - pLeft - 1); - AddKeyName( keyname); + keyname = line.substr(pLeft + 1, pRight - pLeft - 1); + AddKeyName(keyname); } break; } case '=': { - valuename = line.substr( 0, pLeft); - value = line.substr( pLeft + 1); - SetValue( keyname, valuename, value); + valuename = line.substr(0, pLeft); + value = line.substr(pLeft + 1); + SetValue(keyname, valuename, value); break; } @@ -126,11 +147,11 @@ bool cIniFile::ReadFile() { if (names.size() == 0) { - HeaderComment( line.substr( pLeft + 1)); + HeaderComment(line.substr(pLeft + 1)); } else { - KeyComment( keyname, line.substr( pLeft + 1)); + KeyComment(keyname, line.substr(pLeft + 1)); } break; } @@ -138,9 +159,197 @@ bool cIniFile::ReadFile() } // while (getline()) f.close(); - if (names.size() > 0) + if (names.size() == 0) { - return true; + return false; + } + + if (IsFromExampleRedirect) + { + WriteFile(); + } + return true; +} + + + + + +bool cIniFile::WriteFile(void) const +{ + unsigned commentID, keyID, valueID; + // Normally you would use ofstream, but the SGI CC compiler has + // a few bugs with ofstream. So ... fstream used. + fstream f; + + f.open((FILE_IO_PREFIX + m_Path).c_str(), ios::out); + if (f.fail()) + { + return false; + } + + // Write header comments. + for (commentID = 0; commentID < comments.size(); ++commentID) + { + f << ';' << comments[commentID] << iniEOL; + } + if (comments.size()) + { + f << iniEOL; + } + + // Write keys and values. + for (keyID = 0; keyID < keys.size(); ++keyID) + { + f << '[' << names[keyID] << ']' << iniEOL; + + // Comments. + for (commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) + { + f << ';' << keys[keyID].comments[commentID] << iniEOL; + } + + // Values. + for (valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + { + f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; + } + f << iniEOL; + } + f.close(); + + return true; +} + + + + + +long cIniFile::FindKey(const string & a_KeyName) const +{ + string CaseKeyName = CheckCase(a_KeyName); + for (unsigned keyID = 0; keyID < names.size(); ++keyID) + { + if (CheckCase(names[keyID]) == CaseKeyName) + { + return long(keyID); + } + } + return noID; +} + + + + + +long cIniFile::FindValue(unsigned const keyID, const string & a_ValueName) const +{ + if (!keys.size() || (keyID >= keys.size())) + { + return noID; + } + + string CaseValueName = CheckCase(a_ValueName); + for (unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + { + if (CheckCase(keys[keyID].names[valueID]) == CaseValueName) + { + return long(valueID); + } + } + return noID; +} + + + + + +unsigned cIniFile::AddKeyName(const string & keyname) +{ + names.resize(names.size() + 1, keyname); + keys.resize(keys.size() + 1); + return names.size() - 1; +} + + + + + +string cIniFile::KeyName(unsigned const keyID) const +{ + if (keyID < names.size()) + { + return names[keyID]; + } + else + { + return ""; + } +} + + + + + +unsigned cIniFile::NumValues(unsigned const keyID) +{ + if (keyID < keys.size()) + { + return keys[keyID].names.size(); + } + return 0; +} + + + + + +unsigned cIniFile::NumValues(const string & keyname) +{ + long keyID = FindKey(keyname); + if (keyID == noID) + { + return 0; + } + return keys[keyID].names.size(); +} + + + + + +string cIniFile::ValueName(unsigned const keyID, unsigned const valueID) const +{ + if (keyID < keys.size() && valueID < keys[keyID].names.size()) + { + return keys[keyID].names[valueID]; + } + return ""; +} + + + + + +string cIniFile::ValueName(const string & keyname, unsigned const valueID) const +{ + long keyID = FindKey(keyname); + if (keyID == noID) + { + return ""; + } + return ValueName(keyID, valueID); +} + + + + + +bool cIniFile::SetValue(unsigned const keyID, unsigned const valueID, const string & value) +{ + if ((keyID < keys.size()) && (valueID < keys[keyID].names.size())) + { + keys[keyID].values[valueID] = value; } return false; } @@ -149,245 +358,116 @@ bool cIniFile::ReadFile() -bool cIniFile::WriteFile() +bool cIniFile::SetValue(const string & keyname, const string & valuename, const string & value, bool const create) { - unsigned commentID, keyID, valueID; - // Normally you would use ofstream, but the SGI CC compiler has - // a few bugs with ofstream. So ... fstream used. - fstream f; + long keyID = FindKey(keyname); + if (keyID == noID) + { + if (create) + { + keyID = long(AddKeyName(keyname)); + } + else + { + return false; + } + } - f.open( (FILE_IO_PREFIX + path).c_str(), ios::out); - if ( f.fail()) - return false; + long valueID = FindValue(unsigned(keyID), valuename); + if (valueID == noID) + { + if (!create) + { + return false; + } + keys[keyID].names.resize(keys[keyID].names.size() + 1, valuename); + keys[keyID].values.resize(keys[keyID].values.size() + 1, value); + } + else + { + if (!create) + { + keys[keyID].values[valueID] = value; + } + else + { + keys[keyID].names.resize(keys[keyID].names.size() + 1, valuename); + keys[keyID].values.resize(keys[keyID].values.size() + 1, value); + } + } - // Write header comments. - for ( commentID = 0; commentID < comments.size(); ++commentID) - f << ';' << comments[commentID] << iniEOL; - if ( comments.size()) - f << iniEOL; - - // Write keys and values. - for ( keyID = 0; keyID < keys.size(); ++keyID) { - f << '[' << names[keyID] << ']' << iniEOL; - // Comments. - for ( commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) - f << ';' << keys[keyID].comments[commentID] << iniEOL; - // Values. - for ( valueID = 0; valueID < keys[keyID].names.size(); ++valueID) - f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; - f << iniEOL; - } - f.close(); - - return true; + return true; } -long cIniFile::FindKey( const string & keyname) const +bool cIniFile::SetValueI(const string & keyname, const string & valuename, int const value, bool const create) { - for ( unsigned keyID = 0; keyID < names.size(); ++keyID) - if ( CheckCase( names[keyID]) == CheckCase( keyname)) - return long(keyID); - return noID; + AString Data; + Printf(Data, "%d", value); + return SetValue(keyname, valuename, Data, create); } -long cIniFile::FindValue( unsigned const keyID, const string & valuename) const +bool cIniFile::SetValueF(const string & keyname, const string & valuename, double const value, bool const create) { - if ( !keys.size() || keyID >= keys.size()) - return noID; - - for ( unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) - if ( CheckCase( keys[keyID].names[valueID]) == CheckCase( valuename)) - return long(valueID); - return noID; + AString Data; + Printf(Data, "%f", value); + return SetValue(keyname, valuename, Data, create); } -unsigned cIniFile::AddKeyName( const string & keyname) +bool cIniFile::SetValueV(const string & keyname, const string & valuename, char * format, ...) { - names.resize( names.size() + 1, keyname); - keys.resize( keys.size() + 1); - return names.size() - 1; + va_list args; + va_start(args, format); + + AString Data; + AppendVPrintf(Data, format, args); + va_end(args); + return SetValue(keyname, valuename, Data); } -string cIniFile::KeyName( unsigned const keyID) const +string cIniFile::GetValue(unsigned const keyID, unsigned const valueID, const string & defValue) const { - if ( keyID < names.size()) - return names[keyID]; - else - return ""; + if ((keyID < keys.size()) && (valueID < keys[keyID].names.size())) + { + return keys[keyID].values[valueID]; + } + return defValue; } -unsigned cIniFile::NumValues( unsigned const keyID) +string cIniFile::GetValue(const string & keyname, const string & valuename, const string & defValue) const { - if ( keyID < keys.size()) - return keys[keyID].names.size(); - return 0; -} + long keyID = FindKey(keyname); + if (keyID == noID) + { + return defValue; + } + long valueID = FindValue(unsigned(keyID), valuename); + if (valueID == noID) + { + return defValue; + } - - - -unsigned cIniFile::NumValues( const string & keyname) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return 0; - return keys[keyID].names.size(); -} - - - - - -string cIniFile::ValueName( unsigned const keyID, unsigned const valueID) const -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - return keys[keyID].names[valueID]; - return ""; -} - - - - - -string cIniFile::ValueName( const string & keyname, unsigned const valueID) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return ""; - return ValueName( keyID, valueID); -} - - - - - -bool cIniFile::SetValue( unsigned const keyID, unsigned const valueID, const string & value) -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - keys[keyID].values[valueID] = value; - - return false; -} - - - - - -bool cIniFile::SetValue( const string & keyname, const string & valuename, const string & value, bool const create) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) { - if ( create) - keyID = long( AddKeyName( keyname)); - else - return false; - } - - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) { - if ( !create) - return false; - keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); - keys[keyID].values.resize( keys[keyID].values.size() + 1, value); - } else - { - if(!create) - keys[keyID].values[valueID] = value; - else - { - keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); - keys[keyID].values.resize( keys[keyID].values.size() + 1, value); - } - } - - return true; -} - - - - - -bool cIniFile::SetValueI( const string & keyname, const string & valuename, int const value, bool const create) -{ - AString Data; - Printf(Data, "%d", value); - return SetValue( keyname, valuename, Data, create); -} - - - - - -bool cIniFile::SetValueF( const string & keyname, const string & valuename, double const value, bool const create) -{ - AString Data; - Printf(Data, "%f", value); - return SetValue( keyname, valuename, Data, create); -} - - - - - -bool cIniFile::SetValueV( const string & keyname, const string & valuename, char *format, ...) -{ - va_list args; - - va_start( args, format); - - AString Data; - AppendVPrintf(Data, format, args); - va_end( args); - return SetValue( keyname, valuename, Data); -} - - - - - -string cIniFile::GetValue( unsigned const keyID, unsigned const valueID, const string & defValue) const -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - return keys[keyID].values[valueID]; - return defValue; -} - - - - - -string cIniFile::GetValue( const string & keyname, const string & valuename, const string & defValue) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return defValue; - - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) - return defValue; - - return keys[keyID].values[valueID]; + return keys[keyID].values[valueID]; } @@ -398,7 +478,7 @@ int cIniFile::GetValueI(const string & keyname, const string & valuename, int co { AString Data; Printf(Data, "%d", defValue); - return atoi( GetValue( keyname, valuename, Data).c_str()); + return atoi(GetValue(keyname, valuename, Data).c_str()); } @@ -407,9 +487,9 @@ int cIniFile::GetValueI(const string & keyname, const string & valuename, int co double cIniFile::GetValueF(const string & keyname, const string & valuename, double const defValue) const { - AString Data; - Printf(Data, "%f", defValue); - return atof( GetValue( keyname, valuename, Data).c_str()); + AString Data; + Printf(Data, "%f", defValue); + return atof(GetValue(keyname, valuename, Data).c_str()); } @@ -418,15 +498,15 @@ double cIniFile::GetValueF(const string & keyname, const string & valuename, dou AString cIniFile::GetValueSet(const AString & keyname, const AString & valuename, const AString & defValue) { - long keyID = FindKey( keyname); - if ( keyID == noID) + long keyID = FindKey(keyname); + if (keyID == noID) { SetValue(keyname, valuename, defValue); return defValue; } - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) + long valueID = FindValue(unsigned(keyID), valuename); + if (valueID == noID) { SetValue(keyname, valuename, defValue); return defValue; @@ -441,9 +521,9 @@ AString cIniFile::GetValueSet(const AString & keyname, const AString & valuename double cIniFile::GetValueSetF(const AString & keyname, const AString & valuename, const double defValue) { - AString Data; - Printf(Data, "%f", defValue); - return atof(GetValueSet(keyname, valuename, Data).c_str()); + AString Data; + Printf(Data, "%f", defValue); + return atof(GetValueSet(keyname, valuename, Data).c_str()); } @@ -454,182 +534,273 @@ int cIniFile::GetValueSetI(const AString & keyname, const AString & valuename, c { AString Data; Printf(Data, "%d", defValue); - return atoi(GetValueSet(keyname, valuename, Data).c_str()); + return atoi(GetValueSet(keyname, valuename, Data).c_str()); } -bool cIniFile::DeleteValueByID( const unsigned keyID, const unsigned valueID ) +bool cIniFile::DeleteValueByID(const unsigned keyID, const unsigned valueID) { - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + if (keyID < keys.size() && valueID < keys[keyID].names.size()) { // This looks strange, but is neccessary. vector::iterator npos = keys[keyID].names.begin() + valueID; vector::iterator vpos = keys[keyID].values.begin() + valueID; - keys[keyID].names.erase( npos, npos + 1); - keys[keyID].values.erase( vpos, vpos + 1); + keys[keyID].names.erase(npos, npos + 1); + keys[keyID].values.erase(vpos, vpos + 1); return true; } return false; } -bool cIniFile::DeleteValue( const string & keyname, const string & valuename) + + + + +bool cIniFile::DeleteValue(const string & keyname, const string & valuename) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) - return false; + long valueID = FindValue(unsigned(keyID), valuename); + if (valueID == noID) + { + return false; + } - return DeleteValueByID( keyID, valueID ); + return DeleteValueByID(keyID, valueID); } -bool cIniFile::DeleteKey( const string & keyname) + + + + +bool cIniFile::DeleteKey(const string & keyname) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } - // Now hopefully this destroys the vector lists within keys. - // Looking at source, this should be the case using the destructor. - // If not, I may have to do it explicitly. Memory leak check should tell. - // memleak_test.cpp shows that the following not required. - //keys[keyID].names.clear(); - //keys[keyID].values.clear(); + vector::iterator npos = names.begin() + keyID; + vector::iterator kpos = keys.begin() + keyID; + names.erase(npos, npos + 1); + keys.erase(kpos, kpos + 1); - vector::iterator npos = names.begin() + keyID; - vector::iterator kpos = keys.begin() + keyID; - names.erase( npos, npos + 1); - keys.erase( kpos, kpos + 1); - - return true; + return true; } -void cIniFile::Erase() + + + + +void cIniFile::Clear(void) { - // This loop not needed. The vector<> destructor seems to do - // all the work itself. memleak_test.cpp shows this. - //for ( unsigned i = 0; i < keys.size(); ++i) { - // keys[i].names.clear(); - // keys[i].values.clear(); - //} - names.clear(); - keys.clear(); - comments.clear(); + names.clear(); + keys.clear(); + comments.clear(); } -void cIniFile::HeaderComment( const string & comment) + + + + +void cIniFile::HeaderComment(const string & comment) { - comments.resize( comments.size() + 1, comment); + comments.push_back(comment); + // comments.resize(comments.size() + 1, comment); } -string cIniFile::HeaderComment( unsigned const commentID) const + + + + +string cIniFile::HeaderComment(unsigned const commentID) const { - if ( commentID < comments.size()) - return comments[commentID]; - return ""; + if (commentID < comments.size()) + { + return comments[commentID]; + } + return ""; } -bool cIniFile::DeleteHeaderComment( unsigned commentID) + + + + +bool cIniFile::DeleteHeaderComment(unsigned commentID) { - if ( commentID < comments.size()) { - vector::iterator cpos = comments.begin() + commentID; - comments.erase( cpos, cpos + 1); - return true; - } - return false; + if (commentID < comments.size()) + { + vector::iterator cpos = comments.begin() + commentID; + comments.erase(cpos, cpos + 1); + return true; + } + return false; } -unsigned cIniFile::NumKeyComments( unsigned const keyID) const + + + + +unsigned cIniFile::NumKeyComments(unsigned const keyID) const { - if ( keyID < keys.size()) - return keys[keyID].comments.size(); - return 0; + if (keyID < keys.size()) + { + return keys[keyID].comments.size(); + } + return 0; } -unsigned cIniFile::NumKeyComments( const string & keyname) const + + + + +unsigned cIniFile::NumKeyComments(const string & keyname) const { - long keyID = FindKey( keyname); - if ( keyID == noID) - return 0; - return keys[keyID].comments.size(); + long keyID = FindKey(keyname); + if (keyID == noID) + return 0; + return keys[keyID].comments.size(); } -bool cIniFile::KeyComment( unsigned const keyID, const string & comment) + + + + +bool cIniFile::KeyComment(unsigned const keyID, const string & comment) { - if ( keyID < keys.size()) { - keys[keyID].comments.resize( keys[keyID].comments.size() + 1, comment); - return true; - } - return false; + if (keyID < keys.size()) + { + keys[keyID].comments.resize(keys[keyID].comments.size() + 1, comment); + return true; + } + return false; } -bool cIniFile::KeyComment( const string & keyname, const string & comment) + + + + +bool cIniFile::KeyComment(const string & keyname, const string & comment) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return KeyComment( unsigned(keyID), comment); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } + return KeyComment(unsigned(keyID), comment); } -string cIniFile::KeyComment( unsigned const keyID, unsigned const commentID) const + + + + +string cIniFile::KeyComment(unsigned const keyID, unsigned const commentID) const { - if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) - return keys[keyID].comments[commentID]; - return ""; + if ((keyID < keys.size()) && (commentID < keys[keyID].comments.size())) + { + return keys[keyID].comments[commentID]; + } + return ""; } -string cIniFile::KeyComment( const string & keyname, unsigned const commentID) const + + + + +string cIniFile::KeyComment(const string & keyname, unsigned const commentID) const { - long keyID = FindKey( keyname); - if ( keyID == noID) - return ""; - return KeyComment( unsigned(keyID), commentID); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return ""; + } + return KeyComment(unsigned(keyID), commentID); } -bool cIniFile::DeleteKeyComment( unsigned const keyID, unsigned const commentID) + + + + +bool cIniFile::DeleteKeyComment(unsigned const keyID, unsigned const commentID) { - if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) { - vector::iterator cpos = keys[keyID].comments.begin() + commentID; - keys[keyID].comments.erase( cpos, cpos + 1); - return true; - } - return false; + if ((keyID < keys.size()) && (commentID < keys[keyID].comments.size())) + { + vector::iterator cpos = keys[keyID].comments.begin() + commentID; + keys[keyID].comments.erase(cpos, cpos + 1); + return true; + } + return false; } -bool cIniFile::DeleteKeyComment( const string & keyname, unsigned const commentID) + + + + +bool cIniFile::DeleteKeyComment(const string & keyname, unsigned const commentID) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return DeleteKeyComment( unsigned(keyID), commentID); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } + return DeleteKeyComment(unsigned(keyID), commentID); } -bool cIniFile::DeleteKeyComments( unsigned const keyID) + + + + +bool cIniFile::DeleteKeyComments(unsigned const keyID) { - if ( keyID < keys.size()) { - keys[keyID].comments.clear(); - return true; - } - return false; + if (keyID < keys.size()) + { + keys[keyID].comments.clear(); + return true; + } + return false; } -bool cIniFile::DeleteKeyComments( const string & keyname) + + + + +bool cIniFile::DeleteKeyComments(const string & keyname) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return DeleteKeyComments( unsigned(keyID)); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } + return DeleteKeyComments(unsigned(keyID)); } -string cIniFile::CheckCase( string s) const + + + + +string cIniFile::CheckCase(const string & s) const { - if ( caseInsensitive) - for ( string::size_type i = 0; i < s.length(); ++i) - s[i] = (char)tolower(s[i]); - return s; + if (!m_IsCaseInsensitive) + { + return s; + } + string res(s); + size_t len = res.length(); + for (size_t i = 0; i < len; i++) + { + res[i] = tolower(res[i]); + } + return res; } + + + + diff --git a/iniFile/iniFile.h b/iniFile/iniFile.h index 1afc404e3..ebbcc5081 100644 --- a/iniFile/iniFile.h +++ b/iniFile/iniFile.h @@ -30,135 +30,155 @@ -class cIniFile // tolua_export -{ // tolua_export +// tolua_begin + +class cIniFile +{ private: - bool caseInsensitive; - std::string path; - struct key { + bool m_IsCaseInsensitive; + std::string m_Path; + + struct key + { std::vector names; std::vector values; std::vector comments; - }; - std::vector keys; - std::vector names; + } ; + + std::vector keys; + std::vector names; std::vector comments; - std::string CheckCase( std::string s) const; + + /// If the object is case-insensitive, returns s as lowercase; otherwise returns s as-is + std::string CheckCase(const std::string & s) const; public: - enum errors{ noID = -1}; // tolua_export - cIniFile( const std::string iniPath = ""); // tolua_export - virtual ~cIniFile() {} + enum errors + { + noID = -1, + }; + + /// Creates a new instance; sets m_Path to a_Path, but doesn't read the file + cIniFile(const std::string & a_Path = ""); // Sets whether or not keynames and valuenames should be case sensitive. // The default is case insensitive. - void CaseSensitive() {caseInsensitive = false;} // tolua_export - void CaseInsensitive() {caseInsensitive = true;} // tolua_export + void CaseSensitive (void) { m_IsCaseInsensitive = false; } + void CaseInsensitive(void) { m_IsCaseInsensitive = true; } // Sets path of ini file to read and write from. - void Path(const std::string & newPath) {path = newPath;} // tolua_export - std::string Path() const {return path;} // tolua_export - void SetPath(const std::string & newPath) {Path( newPath);} // tolua_export + void Path(const std::string & newPath) {m_Path = newPath;} + const std::string & Path(void) const {return m_Path;} + void SetPath(const std::string & newPath) {Path(newPath);} - // Reads ini file specified using path. - // Returns true if successful, false otherwise. - bool ReadFile(); // tolua_export + /** Reads the ini file specified in m_Path + If the file doesn't exist and a_AllowExampleRedirect is true, tries to read .example.ini, and + writes its contents as .ini, if successful. + Returns true if successful, false otherwise. + */ + bool ReadFile(bool a_AllowExampleRedirect = true); - // Writes data stored in class to ini file. - bool WriteFile(); // tolua_export + /// Writes data stored in class to ini file specified in m_Path + bool WriteFile(void) const; - // Deletes all stored ini data. - void Erase(); // tolua_export - void Clear() {Erase();} // tolua_export - void Reset() {Erase();} // tolua_export + /// Deletes all stored ini data (but doesn't touch the file) + void Clear(void); + void Reset(void) { Clear(); } + void Erase(void) { Clear(); } // OBSOLETE, this name is misguiding and will be removed from the interface - // Returns index of specified key, or noID if not found. - long FindKey( const std::string & keyname) const; // tolua_export + /// Returns index of specified key, or noID if not found + long FindKey(const std::string & keyname) const; - // Returns index of specified value, in the specified key, or noID if not found. - long FindValue( const unsigned keyID, const std::string & valuename) const; // tolua_export + /// Returns index of specified value, in the specified key, or noID if not found + long FindValue(const unsigned keyID, const std::string & valuename) const; - // Returns number of keys currently in the ini. - unsigned NumKeys() const {return names.size();} // tolua_export - unsigned GetNumKeys() const {return NumKeys();} // tolua_export + /// Returns number of keys currently in the ini + unsigned NumKeys (void) const {return names.size();} + unsigned GetNumKeys(void) const {return NumKeys();} - // Add a key name. - unsigned AddKeyName( const std::string & keyname); // tolua_export + /// Add a key name + unsigned AddKeyName(const std::string & keyname); // Returns key names by index. - std::string KeyName( const unsigned keyID) const; // tolua_export - std::string GetKeyName( const unsigned keyID) const {return KeyName(keyID);} // tolua_export + std::string KeyName(const unsigned keyID) const; + std::string GetKeyName(const unsigned keyID) const {return KeyName(keyID);} // Returns number of values stored for specified key. - unsigned NumValues( const std::string & keyname); // tolua_export - unsigned GetNumValues( const std::string & keyname) {return NumValues( keyname);} // tolua_export - unsigned NumValues( const unsigned keyID); // tolua_export - unsigned GetNumValues( const unsigned keyID) {return NumValues( keyID);} // tolua_export + unsigned NumValues (const std::string & keyname); + unsigned GetNumValues(const std::string & keyname) {return NumValues(keyname);} + unsigned NumValues (const unsigned keyID); + unsigned GetNumValues(const unsigned keyID) {return NumValues(keyID);} // Returns value name by index for a given keyname or keyID. - std::string ValueName( const std::string & keyname, const unsigned valueID) const; // tolua_export - std::string GetValueName( const std::string & keyname, const unsigned valueID) const { // tolua_export - return ValueName( keyname, valueID); - } // tolua_export - std::string ValueName( const unsigned keyID, const unsigned valueID) const; // tolua_export - std::string GetValueName( const unsigned keyID, const unsigned valueID) const { // tolua_export - return ValueName( keyID, valueID); - } // tolua_export + std::string ValueName( const std::string & keyname, const unsigned valueID) const; + std::string GetValueName( const std::string & keyname, const unsigned valueID) const + { + return ValueName(keyname, valueID); + } + std::string ValueName (const unsigned keyID, const unsigned valueID) const; + std::string GetValueName(const unsigned keyID, const unsigned valueID) const + { + return ValueName(keyID, valueID); + } // Gets value of [keyname] valuename =. // Overloaded to return string, int, and double. // Returns defValue if key/value not found. - AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const; // tolua_export - AString GetValue (const unsigned keyID, const unsigned valueID, const AString & defValue = "") const; // tolua_export - double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const; // tolua_export - int GetValueI(const AString & keyname, const AString & valuename, const int defValue = 0) const; // tolua_export - bool GetValueB(const AString & keyname, const AString & valuename, const bool defValue = false) const { // tolua_export - return ( GetValueI( keyname, valuename, int( defValue)) > 0); - } // tolua_export + AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const; + AString GetValue (const unsigned keyID, const unsigned valueID, const AString & defValue = "") const; + double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const; + int GetValueI(const AString & keyname, const AString & valuename, const int defValue = 0) const; + bool GetValueB(const AString & keyname, const AString & valuename, const bool defValue = false) const + { + return (GetValueI(keyname, valuename, int(defValue)) > 0); + } // Gets the value; if not found, write the default to the INI file - AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = ""); // tolua_export - double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0); // tolua_export - int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0); // tolua_export - bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) { // tolua_export + AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = ""); + double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0); + int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0); + bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) + { return (GetValueSetI(keyname, valuename, defValue ? 1 : 0) > 0); - } // tolua_export + } // Sets value of [keyname] valuename =. // Specify the optional paramter as false (0) if you do not want it to create // the key if it doesn't exist. Returns true if data entered, false otherwise. // Overloaded to accept string, int, and double. - bool SetValue( const unsigned keyID, const unsigned valueID, const std::string & value); // tolua_export - bool SetValue( const std::string & keyname, const std::string & valuename, const std::string & value, const bool create = true); // tolua_export - bool SetValueI( const std::string & keyname, const std::string & valuename, const int value, const bool create = true); // tolua_export - bool SetValueB( const std::string & keyname, const std::string & valuename, const bool value, const bool create = true) { // tolua_export + bool SetValue( const unsigned keyID, const unsigned valueID, const std::string & value); + bool SetValue( const std::string & keyname, const std::string & valuename, const std::string & value, const bool create = true); + bool SetValueI( const std::string & keyname, const std::string & valuename, const int value, const bool create = true); + bool SetValueB( const std::string & keyname, const std::string & valuename, const bool value, const bool create = true) + { return SetValueI( keyname, valuename, int(value), create); - } // tolua_export - bool SetValueF( const std::string & keyname, const std::string & valuename, const double value, const bool create = true); // tolua_export + } + bool SetValueF( const std::string & keyname, const std::string & valuename, const double value, const bool create = true); bool SetValueV( const std::string & keyname, const std::string & valuename, char *format, ...); // Deletes specified value. // Returns true if value existed and deleted, false otherwise. - bool DeleteValueByID( const unsigned keyID, const unsigned valueID ); // tolua_export - bool DeleteValue( const std::string & keyname, const std::string & valuename); // tolua_export + bool DeleteValueByID( const unsigned keyID, const unsigned valueID ); + bool DeleteValue( const std::string & keyname, const std::string & valuename); // Deletes specified key and all values contained within. // Returns true if key existed and deleted, false otherwise. - bool DeleteKey(const std::string & keyname); // tolua_export + bool DeleteKey(const std::string & keyname); // Header comment functions. // Header comments are those comments before the first key. // // Number of header comments. - unsigned NumHeaderComments() {return comments.size();} // tolua_export + unsigned NumHeaderComments(void) {return comments.size();} // Add a header comment. - void HeaderComment( const std::string & comment); // tolua_export + void HeaderComment(const std::string & comment); // Return a header comment. - std::string HeaderComment( const unsigned commentID) const; // tolua_export + std::string HeaderComment(const unsigned commentID) const; // Delete a header comment. - bool DeleteHeaderComment( unsigned commentID); // tolua_export + bool DeleteHeaderComment(unsigned commentID); // Delete all header comments. - void DeleteHeaderComments() {comments.clear();} // tolua_export + void DeleteHeaderComments(void) {comments.clear();} + // Key comment functions. // Key comments are those comments within a key. Any comments @@ -167,20 +187,26 @@ public: // the CIniFile::WriteFile() is called. // // Number of key comments. - unsigned NumKeyComments( const unsigned keyID) const; // tolua_export - unsigned NumKeyComments( const std::string & keyname) const; // tolua_export + unsigned NumKeyComments( const unsigned keyID) const; + unsigned NumKeyComments( const std::string & keyname) const; + // Add a key comment. - bool KeyComment( const unsigned keyID, const std::string & comment); // tolua_export - bool KeyComment( const std::string & keyname, const std::string & comment); // tolua_export + bool KeyComment(const unsigned keyID, const std::string & comment); + bool KeyComment(const std::string & keyname, const std::string & comment); + // Return a key comment. - std::string KeyComment( const unsigned keyID, const unsigned commentID) const; // tolua_export - std::string KeyComment( const std::string & keyname, const unsigned commentID) const; // tolua_export + std::string KeyComment(const unsigned keyID, const unsigned commentID) const; + std::string KeyComment(const std::string & keyname, const unsigned commentID) const; + // Delete a key comment. - bool DeleteKeyComment( const unsigned keyID, const unsigned commentID); // tolua_export - bool DeleteKeyComment( const std::string & keyname, const unsigned commentID); // tolua_export + bool DeleteKeyComment(const unsigned keyID, const unsigned commentID); + bool DeleteKeyComment(const std::string & keyname, const unsigned commentID); + // Delete all comments for a key. - bool DeleteKeyComments( const unsigned keyID); // tolua_export - bool DeleteKeyComments( const std::string & keyname); // tolua_export -}; // tolua_export + bool DeleteKeyComments(const unsigned keyID); + bool DeleteKeyComments(const std::string & keyname); +}; + +// tolua_end #endif diff --git a/source/GroupManager.cpp b/source/GroupManager.cpp index 396ad2e2f..cef32dd58 100644 --- a/source/GroupManager.cpp +++ b/source/GroupManager.cpp @@ -47,11 +47,8 @@ cGroupManager::cGroupManager() cIniFile IniFile("groups.ini"); if (!IniFile.ReadFile()) { - LOGINFO("groups.ini inaccessible, using groups.example.ini for defaults!"); - IniFile.Path("groups.example.ini"); - IniFile.ReadFile(); - IniFile.Path("groups.ini"); - IniFile.WriteFile(); + LOGWARNING("groups.ini inaccessible, no groups are defined"); + return; } unsigned int NumKeys = IniFile.GetNumKeys(); diff --git a/source/Root.cpp b/source/Root.cpp index 59242c60d..f12ccc832 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -112,10 +112,7 @@ void cRoot::Start(void) cIniFile IniFile("settings.ini"); if (!IniFile.ReadFile()) { - LOGINFO("settings.ini inaccessible, using settings.example.ini for defaults!"); - IniFile.Path("settings.example.ini"); - IniFile.ReadFile(); - IniFile.Path("settings.ini"); + LOGWARNING("settings.ini inaccessible, all settings are reset to default values"); } m_PrimaryServerVersion = IniFile.GetValueI("Server", "PrimaryServerVersion", 0); if (m_PrimaryServerVersion == 0) @@ -139,23 +136,19 @@ void cRoot::Start(void) cIniFile WebIniFile("webadmin.ini"); if (!WebIniFile.ReadFile()) { - LOGINFO("webadmin.ini inaccessible, using webadmin.example.ini for defaults!"); - WebIniFile.Path("webadmin.example.ini"); - WebIniFile.ReadFile(); - WebIniFile.Path("webadmin.ini"); - WebIniFile.WriteFile(); + LOGWARNING("webadmin.ini inaccessible, wabadmin is disabled"); } - if (WebIniFile.GetValueB("WebAdmin", "Enabled", false )) + if (WebIniFile.GetValueB("WebAdmin", "Enabled", false)) { LOG("Creating WebAdmin..."); m_WebAdmin = new cWebAdmin(8080); } LOG("Loading settings..."); - m_GroupManager = new cGroupManager(); + m_GroupManager = new cGroupManager(); m_CraftingRecipes = new cCraftingRecipes; - m_FurnaceRecipe = new cFurnaceRecipe(); + m_FurnaceRecipe = new cFurnaceRecipe(); LOG("Loading worlds..."); LoadWorlds();