Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/simpleini.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrodie Thiesfield <brofield@gmail.com>2007-01-23 03:09:28 +0300
committerBrodie Thiesfield <brofield@gmail.com>2007-01-23 03:09:28 +0300
commit1f2a422414e33ab7a77e5ff5d999fae61cbc99e0 (patch)
tree59df4989efb63a6b11e83ea0eac0661ca8baee52
parenta8efe3630ffe8818944071afd2a51e20b0d412f2 (diff)
version 4.0.1 release
-rw-r--r--SimpleIni.h67
-rw-r--r--SimpleIni.vcproj2
-rw-r--r--snippets.cpp64
-rw-r--r--test1.cpp153
-rw-r--r--testsi.cpp544
5 files changed, 434 insertions, 396 deletions
diff --git a/SimpleIni.h b/SimpleIni.h
index b27d976..fdc5650 100644
--- a/SimpleIni.h
+++ b/SimpleIni.h
@@ -3,9 +3,9 @@
<table>
<tr><th>Library <td>SimpleIni
<tr><th>File <td>SimpleIni.h
- <tr><th>Author <td>Brodie Thiesfield <code@jellycan.com>
+ <tr><th>Author <td>Brodie Thiesfield [code at jellycan dot com]
<tr><th>Source <td>http://code.jellycan.com/simpleini/
- <tr><th>Version <td>4.0
+ <tr><th>Version <td>4.0.1
</table>
Jump to the @link CSimpleIniTempl CSimpleIni @endlink interface documentation.
@@ -38,8 +38,11 @@
- support for non-standard character types or file encodings
via user-written converter classes
- support for adding/modifying values programmatically
- - compiles cleanly at warning level 4 (Windows/VC.NET 2003), warning level
- 3 (Windows/VC6) and -Wall (Linux/gcc)
+ - compiles cleanly in the following compilers:
+ - Windows/VC6 (warning level 3)
+ - Windows/VC.NET 2003 (warning level 4)
+ - Windows/VC 2005 (warning level 4)
+ - Linux/gcc (-Wall)
@section USAGE SUMMARY
@@ -193,12 +196,13 @@
// 4127 "conditional expression is constant" as the conversion classes trigger
// it with the statement if (sizeof(SI_CHAR) == sizeof(char)). This test will
// be optimized away in a release build.
+// 4503 'insert' : decorated name length exceeded, name was truncated
// 4702 "unreachable code" as the MS STL header causes it in release mode.
// Again, the code causing the warning will be cleaned up by the compiler.
// 4786 "identifier truncated to 256 characters" as this is thrown hundreds
// of times VC6 as soon as STL is used.
#ifdef _MSC_VER
-# pragma warning (disable: 4127 4702 4786)
+# pragma warning (disable: 4127 4503 4702 4786)
#endif
#include <string>
@@ -280,18 +284,19 @@ class CSimpleIniTempl
{
public:
/** key entry */
- struct Entry {
+ template<class SI_CHAR, class SI_STRLESS>
+ struct EntryTempl {
const SI_CHAR * pItem;
const SI_CHAR * pComment;
int nOrder;
- Entry(const SI_CHAR * a_pszItem = NULL, int a_nOrder = 0)
+ EntryTempl(const SI_CHAR * a_pszItem = NULL, int a_nOrder = 0)
: pItem(a_pszItem)
, pComment(NULL)
, nOrder(a_nOrder)
{ }
- Entry(const Entry & rhs) { operator=(rhs); }
- Entry & operator=(const Entry & rhs) {
+ EntryTempl(const EntryTempl & rhs) { operator=(rhs); }
+ EntryTempl & operator=(const EntryTempl & rhs) {
pItem = rhs.pItem;
pComment = rhs.pComment;
nOrder = rhs.nOrder;
@@ -300,21 +305,21 @@ public:
#if defined(_MSC_VER) && _MSC_VER <= 1200
/** STL of VC6 doesn't allow me to specify my own comparator for list::sort() */
- bool operator<(const Entry & rhs) const { return LoadOrder()(*this, rhs); }
- bool operator>(const Entry & rhs) const { return LoadOrder()(rhs, *this); }
+ bool operator<(const EntryTempl & rhs) const { return LoadOrder()(*this, rhs); }
+ bool operator>(const EntryTempl & rhs) const { return LoadOrder()(rhs, *this); }
#endif
/** Strict less ordering by name of key only */
- struct KeyOrder : std::binary_function<Entry, Entry, bool> {
- bool operator()(const Entry & lhs, const Entry & rhs) const {
+ struct KeyOrder : std::binary_function<EntryTempl, EntryTempl, bool> {
+ bool operator()(const EntryTempl & lhs, const EntryTempl & rhs) const {
const static SI_STRLESS isLess = SI_STRLESS();
return isLess(lhs.pItem, rhs.pItem);
}
};
/** Strict less ordering by order, and then name of key */
- struct LoadOrder : std::binary_function<Entry, Entry, bool> {
- bool operator()(const Entry & lhs, const Entry & rhs) const {
+ struct LoadOrder : std::binary_function<EntryTempl, EntryTempl, bool> {
+ bool operator()(const EntryTempl & lhs, const EntryTempl & rhs) const {
if (lhs.nOrder != rhs.nOrder) {
return lhs.nOrder < rhs.nOrder;
}
@@ -322,12 +327,13 @@ public:
}
};
};
+ typedef EntryTempl<SI_CHAR,SI_STRLESS> Entry;
/** map keys to values */
- typedef std::multimap<Entry,const SI_CHAR *,Entry::KeyOrder> TKeyVal;
+ typedef std::multimap<Entry,const SI_CHAR *,typename Entry::KeyOrder> TKeyVal;
/** map sections to key/value map */
- typedef std::map<Entry,TKeyVal,Entry::KeyOrder> TSection;
+ typedef std::map<Entry,TKeyVal,typename Entry::KeyOrder> TSection;
/** set of dependent string pointers. Note that these pointers are
dependent on memory owned by CSimpleIni.
@@ -920,7 +926,7 @@ private:
/** Skip over a newline character (or characters) for either DOS or UNIX */
- inline void SkipNewLine(const SI_CHAR *& a_pData) const {
+ inline void SkipNewLine(SI_CHAR *& a_pData) const {
a_pData += (*a_pData == '\r' && *(a_pData+1) == '\n') ? 2 : 1;
}
@@ -956,7 +962,7 @@ private:
size_t m_uDataLen;
/** File comment for this data, if one exists. */
- SI_CHAR * m_pFileComment;
+ const SI_CHAR * m_pFileComment;
/** Parsed INI data. Section -> (Key -> Value). */
TSection m_data;
@@ -1036,7 +1042,12 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
const char * a_pszFile
)
{
- FILE * fp = fopen(a_pszFile, "rb");
+ FILE * fp = NULL;
+#if __STDC_WANT_SECURE_LIB__
+ fopen_s(&fp, a_pszFile, "rb");
+#else
+ fp = fopen(a_pszFile, "rb");
+#endif
if (!fp) {
return SI_FILE;
}
@@ -1053,7 +1064,12 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
)
{
#ifdef _WIN32
- FILE * fp = _wfopen(a_pwszFile, L"rb");
+ FILE * fp = NULL;
+#if __STDC_WANT_SECURE_LIB__
+ _wfopen_s(&fp, a_pwszFile, L"rb");
+#else
+ fp = _wfopen(a_pwszFile, L"rb");
+#endif
if (!fp) return SI_FILE;
SI_Error rc = LoadFile(fp);
fclose(fp);
@@ -1766,7 +1782,12 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SaveFile(
const char * a_pszFile
)
{
- FILE * fp = fopen(a_pszFile, "wb");
+ FILE * fp = NULL;
+#if __STDC_WANT_SECURE_LIB__
+ fopen_s(&fp, a_pszFile, "wb");
+#else
+ fp = fopen(a_pszFile, "wb");
+#endif
if (!fp) return SI_FILE;
SI_Error rc = SaveFile(fp, true);
fclose(fp);
@@ -2617,7 +2638,7 @@ struct SI_NoCase {
(const unsigned char *)pRight) < 0;
}
if (sizeof(SI_CHAR) == sizeof(wchar_t)) {
- return wcsicmp((const wchar_t *)pLeft,
+ return _wcsicmp((const wchar_t *)pLeft,
(const wchar_t *)pRight) < 0;
}
return SI_GenericNoCase<SI_CHAR>()(pLeft, pRight);
diff --git a/SimpleIni.vcproj b/SimpleIni.vcproj
index c94042d..e5ee0db 100644
--- a/SimpleIni.vcproj
+++ b/SimpleIni.vcproj
@@ -126,7 +126,6 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="icuuc.lib"
OutputFile="$(OutDir)/testsi.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
@@ -172,7 +171,6 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="icuuc.lib"
OutputFile="$(OutDir)/testsi.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
diff --git a/snippets.cpp b/snippets.cpp
index 74f4852..3cb5ed0 100644
--- a/snippets.cpp
+++ b/snippets.cpp
@@ -1,10 +1,10 @@
-// File: snippets.cpp
-// Library: SimpleIni
-// Author: Brodie Thiesfield <code@jellycan.com>
-// Source: http://code.jellycan.com/simpleini/
-//
-// Snippets that are used on the website
-
+// File: snippets.cpp
+// Library: SimpleIni
+// Author: Brodie Thiesfield <code@jellycan.com>
+// Source: http://code.jellycan.com/simpleini/
+//
+// Snippets that are used on the website
+
#ifdef _WIN32
# pragma warning(disable: 4786)
#endif
@@ -15,14 +15,14 @@
#include <fstream>
#define SI_SUPPORT_IOSTREAMS
-#include "SimpleIni.h"
+#include "SimpleIni.h"
bool
snippets(
- const char * a_pszFile,
- bool a_bIsUtf8,
- bool a_bUseMultiKey,
- bool a_bUseMultiLine
+ const char * a_pszFile,
+ bool a_bIsUtf8,
+ bool a_bUseMultiKey,
+ bool a_bUseMultiLine
)
{
// LOADING DATA
@@ -39,40 +39,40 @@ snippets(
// GETTING SECTIONS AND KEYS
- // get all sections
+ // get all sections
CSimpleIniA::TNamesDepend sections;
ini.GetAllSections(sections);
- // get all keys in a section
+ // get all keys in a section
CSimpleIniA::TNamesDepend keys;
ini.GetAllKeys("section-name", keys);
// GETTING VALUES
// get the value of a key
- const char * pszValue = ini.GetValue("section-name",
- "key-name", NULL /*default*/);
-
+ const char * pszValue = ini.GetValue("section-name",
+ "key-name", NULL /*default*/);
+
// get the value of a key which may have multiple
// values. If bHasMultipleValues is true, then just
// one value has been returned
bool bHasMultipleValues;
- pszValue = ini.GetValue("section-name", "key-name",
- NULL /*default*/, &bHasMultipleValues);
-
- // get all values of a key with multiple values
+ pszValue = ini.GetValue("section-name", "key-name",
+ NULL /*default*/, &bHasMultipleValues);
+
+ // get all values of a key with multiple values
CSimpleIniA::TNamesDepend values;
ini.GetAllValues("section-name", "key-name", values);
- // sort the values into the original load order
+ // sort the values into the original load order
#if defined(_MSC_VER) && _MSC_VER <= 1200
/** STL of VC6 doesn't allow me to specify my own comparator for list::sort() */
values.sort();
#else
values.sort(CSimpleIniA::Entry::LoadOrder());
#endif
-
- // output all of the items
+
+ // output all of the items
CSimpleIniA::TNamesDepend::const_iterator i;
for (i = values.begin(); i != values.end(); ++i) {
printf("key-name = '%s'\n", i->pItem);
@@ -108,16 +108,16 @@ snippets(
// deleting an entire section and all keys in it
ini.Delete("section-name", NULL);
-
- // SAVING DATA
-
+
+ // SAVING DATA
+
// save the data to a string
rc = ini.Save(strData);
- if (rc < 0) return false;
+ if (rc < 0) return false;
// save the data back to the file
rc = ini.SaveFile(a_pszFile);
- if (rc < 0) return false;
-
- return true;
-}
+ if (rc < 0) return false;
+
+ return true;
+}
diff --git a/test1.cpp b/test1.cpp
index 851b099..5d92ea7 100644
--- a/test1.cpp
+++ b/test1.cpp
@@ -1,10 +1,10 @@
-// File: test1.cpp
-// Library: SimpleIni
-// Author: Brodie Thiesfield <code@jellycan.com>
-// Source: http://code.jellycan.com/simpleini/
-//
-// Automated testing for SimpleIni streams
-
+// File: test1.cpp
+// Library: SimpleIni
+// Author: Brodie Thiesfield <code@jellycan.com>
+// Source: http://code.jellycan.com/simpleini/
+//
+// Automated testing for SimpleIni streams
+
#ifdef _WIN32
# pragma warning(disable: 4786)
#endif
@@ -15,41 +15,45 @@
#include <fstream>
#define SI_SUPPORT_IOSTREAMS
-#include "SimpleIni.h"
-
-class Test
-{
- std::string m_strTest;
-
-public:
- Test(const char * a_pszName)
- : m_strTest(a_pszName)
- {
- printf("%s: test starting\n", m_strTest.c_str());
- }
-
- bool Success()
- {
- printf("%s: test succeeded\n", m_strTest.c_str());
- return false;
- }
-
- bool Failure(const char * pszReason)
- {
- printf("%s: test FAILED (%s)\n", m_strTest.c_str(), pszReason);
- return false;
- }
-};
-
-bool FileComparisonTest(const char * a_pszFile1, const char * a_pszFile2) {
- // ensure that the two files are the same
+#include "SimpleIni.h"
+
+class Test
+{
+ std::string m_strTest;
+
+public:
+ Test(const char * a_pszName)
+ : m_strTest(a_pszName)
+ {
+ printf("%s: test starting\n", m_strTest.c_str());
+ }
+
+ bool Success()
+ {
+ printf("%s: test succeeded\n", m_strTest.c_str());
+ return false;
+ }
+
+ bool Failure(const char * pszReason)
+ {
+ printf("%s: test FAILED (%s)\n", m_strTest.c_str(), pszReason);
+ return false;
+ }
+};
+
+bool FileComparisonTest(const char * a_pszFile1, const char * a_pszFile2) {
+ // ensure that the two files are the same
try {
std::string strFile1, strFile2;
char szBuf[1024];
- FILE * fp;
+ FILE * fp = NULL;
- fp = fopen(a_pszFile1, "rb");
+#if __STDC_WANT_SECURE_LIB__
+ fopen_s(&fp, a_pszFile1, "rb");
+#else
+ fp = fopen(a_pszFile1, "rb");
+#endif
if (!fp) throw false;
while (!feof(fp)) {
size_t n = fread(szBuf, 1, sizeof(szBuf), fp);
@@ -57,7 +61,12 @@ bool FileComparisonTest(const char * a_pszFile1, const char * a_pszFile2) {
}
fclose(fp);
- fp = fopen(a_pszFile2, "rb");
+ fp = NULL;
+#if __STDC_WANT_SECURE_LIB__
+ fopen_s(&fp, a_pszFile2, "rb");
+#else
+ fp = fopen(a_pszFile2, "rb");
+#endif
if (!fp) throw false;
while (!feof(fp)) {
size_t n = fread(szBuf, 1, sizeof(szBuf), fp);
@@ -74,8 +83,8 @@ bool FileComparisonTest(const char * a_pszFile1, const char * a_pszFile2) {
return true;
}
-bool FileLoadTest(const char * a_pszFile1, const char * a_pszFile2) {
- // ensure that the two files load into simpleini the same
+bool FileLoadTest(const char * a_pszFile1, const char * a_pszFile2) {
+ // ensure that the two files load into simpleini the same
CSimpleIniA ini(true, true, true);
bool b;
try {
@@ -88,8 +97,8 @@ bool FileLoadTest(const char * a_pszFile1, const char * a_pszFile2) {
if (ini.SaveFile("test2.ini") < 0) throw "Save failed for file 2";
b = FileComparisonTest("test1.ini", "test2.ini");
- unlink("test1.ini");
- unlink("test2.ini");
+ _unlink("test1.ini");
+ _unlink("test2.ini");
if (!b) throw "File comparison failed in FileLoadTest";
}
@@ -98,24 +107,24 @@ bool FileLoadTest(const char * a_pszFile1, const char * a_pszFile2) {
}
return true;
-}
-
-bool TestStreams()
-{
- const char * rgszTestFile[3] = {
- "test1-input.ini",
- "test1-output.ini",
- "test1-expected.ini"
- };
-
- Test oTest("TestStreams");
-
- CSimpleIniA ini;
- ini.SetUnicode(true);
- ini.SetMultiKey(true);
- ini.SetMultiLine(true);
-
- // load the file
+}
+
+bool TestStreams()
+{
+ const char * rgszTestFile[3] = {
+ "test1-input.ini",
+ "test1-output.ini",
+ "test1-expected.ini"
+ };
+
+ Test oTest("TestStreams");
+
+ CSimpleIniA ini;
+ ini.SetUnicode(true);
+ ini.SetMultiKey(true);
+ ini.SetMultiLine(true);
+
+ // load the file
try {
std::ifstream infile;
infile.open(rgszTestFile[0], std::ifstream::in | std::ifstream::binary);
@@ -135,20 +144,20 @@ bool TestStreams()
try {
std::ofstream outfile;
outfile.open(rgszTestFile[1], std::ofstream::out | std::ofstream::binary);
- if (ini.Save(outfile) < 0) throw false;
+ if (ini.Save(outfile) < 0) throw false;
outfile.close();
}
catch (...) {
return oTest.Failure("Failed to save file");
}
-
- // file comparison test
- if (!FileComparisonTest(rgszTestFile[1], rgszTestFile[2])) {
- return oTest.Failure("Failed file comparison");
- }
- if (!FileLoadTest(rgszTestFile[1], rgszTestFile[2])) {
- return oTest.Failure("Failed file load comparison");
- }
-
- return oTest.Success();
-}
+
+ // file comparison test
+ if (!FileComparisonTest(rgszTestFile[1], rgszTestFile[2])) {
+ return oTest.Failure("Failed file comparison");
+ }
+ if (!FileLoadTest(rgszTestFile[1], rgszTestFile[2])) {
+ return oTest.Failure("Failed file load comparison");
+ }
+
+ return oTest.Success();
+}
diff --git a/testsi.cpp b/testsi.cpp
index 2227d84..8bd5ded 100644
--- a/testsi.cpp
+++ b/testsi.cpp
@@ -1,284 +1,294 @@
-// File: testsi.cpp
-// Library: SimpleIni
-// Author: Brodie Thiesfield <code@jellycan.com>
-// Source: http://code.jellycan.com/simpleini/
-//
-// Demo of usage
-
+// File: testsi.cpp
+// Library: SimpleIni
+// Author: Brodie Thiesfield <code@jellycan.com>
+// Source: http://code.jellycan.com/simpleini/
+//
+// Demo of usage
+
#ifdef _WIN32
# pragma warning(disable: 4786)
#endif
-#include <locale.h>
-#include <stdio.h>
-
-#define SI_SUPPORT_IOSTREAMS
-#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
-# include <fstream>
-#endif
-
-//#define SI_CONVERT_GENERIC
-//#define SI_CONVERT_ICU
-//#define SI_CONVERT_WIN32
-#include "SimpleIni.h"
-
-#ifdef _WIN32
-# include <tchar.h>
-#else // !_WIN32
-# define TCHAR char
-# define _T(x) x
-# define _tprintf printf
-# define _tmain main
-#endif // _WIN32
-
-static void
-Test(
- CSimpleIni & ini
- )
-{
- const TCHAR *pszSection = 0;
- const TCHAR *pItem = 0;
- const TCHAR *pszVal = 0;
-
- // get the value of the key "foo" in section "standard"
- bool bHasMulti;
- pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti);
- _tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"),
- pszVal ? pszVal : _T("(null)"), bHasMulti);
-
- // set the value of the key "foo" in section "standard"
- ini.SetValue(_T("standard"), _T("foo"), _T("wibble"));
- pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti);
- _tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"),
- pszVal ? pszVal : _T("(null)"), bHasMulti);
-
- // get all values of the key "foo" in section "standard"
- CSimpleIni::TNamesDepend values;
- if (ini.GetAllValues(_T("standard"), _T("foo"), values)) {
- _tprintf(_T("\n-- Values of standard::foo are:\n"));
- CSimpleIni::TNamesDepend::const_iterator i = values.begin();
- for (; i != values.end(); ++i) {
- pszVal = i->pItem;
- _tprintf(_T(" -> '%s'\n"), pszVal);
- }
- }
-
- // get the size of the section [standard]
- _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
- ini.GetSectionSize(_T("standard")));
-
- // delete the key "foo" in section "standard"
- ini.Delete(_T("standard"), _T("foo"));
- pszVal = ini.GetValue(_T("standard"), _T("foo"), 0);
- _tprintf(_T("\n-- Value of standard::foo is now '%s'\n"),
- pszVal ? pszVal : _T("(null)"));
-
- // get the size of the section [standard]
- _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
- ini.GetSectionSize(_T("standard")));
-
- // get the list of all key names for the section "standard"
- _tprintf(_T("\n-- Dumping keys of section: [standard]\n"));
- CSimpleIni::TNamesDepend keys;
- ini.GetAllKeys(_T("standard"), keys);
-
- // dump all of the key names
- CSimpleIni::TNamesDepend::const_iterator iKey = keys.begin();
- for ( ; iKey != keys.end(); ++iKey ) {
- pItem = iKey->pItem;
- _tprintf(_T("Key: %s\n"), pItem);
- }
-
- // delete the section "standard"
- ini.Delete(_T("standard"), NULL);
- _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
- ini.GetSectionSize(_T("standard")));
-
- // iterate through every section in the file
- _tprintf(_T("\n-- Dumping all sections\n"));
- CSimpleIni::TNamesDepend sections;
- ini.GetAllSections(sections);
- CSimpleIni::TNamesDepend::const_iterator iSection = sections.begin();
- for ( ; iSection != sections.end(); ++iSection ) {
- pszSection = iSection->pItem;
-
- // print the section name
- printf("\n");
- if (*pszSection) {
- _tprintf(_T("[%s]\n"), pszSection);
- }
-
- // if there are keys and values...
- const CSimpleIni::TKeyVal * pSectionData = ini.GetSection(pszSection);
- if (pSectionData) {
- // iterate over all keys and dump the key name and value
- CSimpleIni::TKeyVal::const_iterator iKeyVal = pSectionData->begin();
- for ( ;iKeyVal != pSectionData->end(); ++iKeyVal) {
- pItem = iKeyVal->first.pItem;
- pszVal = iKeyVal->second;
- _tprintf(_T("%s=%s\n"), pItem, pszVal);
- }
- }
- }
-}
-
-#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
-static bool
-TestStreams(
- const TCHAR * a_pszFile,
- bool a_bIsUtf8,
- bool a_bUseMultiKey,
- bool a_bUseMultiLine
- )
-{
- // load the file
- CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine);
- _tprintf(_T("Loading file: %s\n"), a_pszFile);
+#include <locale.h>
+#include <stdio.h>
+
+#define SI_SUPPORT_IOSTREAMS
+#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
+# include <fstream>
+#endif
+
+//#define SI_CONVERT_GENERIC
+//#define SI_CONVERT_ICU
+//#define SI_CONVERT_WIN32
+#include "SimpleIni.h"
+
+#ifdef SI_CONVERT_ICU
+// if converting using ICU then we need the ICU library
+# pragma comment(lib, "icuuc.lib")
+#endif
+
+#ifdef _WIN32
+# include <tchar.h>
+#else // !_WIN32
+# define TCHAR char
+# define _T(x) x
+# define _tprintf printf
+# define _tmain main
+#endif // _WIN32
+
+static void
+Test(
+ CSimpleIni & ini
+ )
+{
+ const TCHAR *pszSection = 0;
+ const TCHAR *pItem = 0;
+ const TCHAR *pszVal = 0;
+
+ // get the value of the key "foo" in section "standard"
+ bool bHasMulti;
+ pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti);
+ _tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"),
+ pszVal ? pszVal : _T("(null)"), bHasMulti);
+
+ // set the value of the key "foo" in section "standard"
+ ini.SetValue(_T("standard"), _T("foo"), _T("wibble"));
+ pszVal = ini.GetValue(_T("standard"), _T("foo"), 0, &bHasMulti);
+ _tprintf(_T("\n-- Value of standard::foo is '%s' (hasMulti = %d)\n"),
+ pszVal ? pszVal : _T("(null)"), bHasMulti);
+
+ // get all values of the key "foo" in section "standard"
+ CSimpleIni::TNamesDepend values;
+ if (ini.GetAllValues(_T("standard"), _T("foo"), values)) {
+ _tprintf(_T("\n-- Values of standard::foo are:\n"));
+ CSimpleIni::TNamesDepend::const_iterator i = values.begin();
+ for (; i != values.end(); ++i) {
+ pszVal = i->pItem;
+ _tprintf(_T(" -> '%s'\n"), pszVal);
+ }
+ }
+
+ // get the size of the section [standard]
+ _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
+ ini.GetSectionSize(_T("standard")));
+
+ // delete the key "foo" in section "standard"
+ ini.Delete(_T("standard"), _T("foo"));
+ pszVal = ini.GetValue(_T("standard"), _T("foo"), 0);
+ _tprintf(_T("\n-- Value of standard::foo is now '%s'\n"),
+ pszVal ? pszVal : _T("(null)"));
+
+ // get the size of the section [standard]
+ _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
+ ini.GetSectionSize(_T("standard")));
+
+ // get the list of all key names for the section "standard"
+ _tprintf(_T("\n-- Dumping keys of section: [standard]\n"));
+ CSimpleIni::TNamesDepend keys;
+ ini.GetAllKeys(_T("standard"), keys);
+
+ // dump all of the key names
+ CSimpleIni::TNamesDepend::const_iterator iKey = keys.begin();
+ for ( ; iKey != keys.end(); ++iKey ) {
+ pItem = iKey->pItem;
+ _tprintf(_T("Key: %s\n"), pItem);
+ }
+
+ // delete the section "standard"
+ ini.Delete(_T("standard"), NULL);
+ _tprintf(_T("\n-- Number of keys in section [standard] = %d\n"),
+ ini.GetSectionSize(_T("standard")));
+
+ // iterate through every section in the file
+ _tprintf(_T("\n-- Dumping all sections\n"));
+ CSimpleIni::TNamesDepend sections;
+ ini.GetAllSections(sections);
+ CSimpleIni::TNamesDepend::const_iterator iSection = sections.begin();
+ for ( ; iSection != sections.end(); ++iSection ) {
+ pszSection = iSection->pItem;
+
+ // print the section name
+ printf("\n");
+ if (*pszSection) {
+ _tprintf(_T("[%s]\n"), pszSection);
+ }
+
+ // if there are keys and values...
+ const CSimpleIni::TKeyVal * pSectionData = ini.GetSection(pszSection);
+ if (pSectionData) {
+ // iterate over all keys and dump the key name and value
+ CSimpleIni::TKeyVal::const_iterator iKeyVal = pSectionData->begin();
+ for ( ;iKeyVal != pSectionData->end(); ++iKeyVal) {
+ pItem = iKeyVal->first.pItem;
+ pszVal = iKeyVal->second;
+ _tprintf(_T("%s=%s\n"), pItem, pszVal);
+ }
+ }
+ }
+}
+
+#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
+static bool
+TestStreams(
+ const TCHAR * a_pszFile,
+ bool a_bIsUtf8,
+ bool a_bUseMultiKey,
+ bool a_bUseMultiLine
+ )
+{
+ // load the file
+ CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine);
+ _tprintf(_T("Loading file: %s\n"), a_pszFile);
std::ifstream infile;
infile.open(a_pszFile, std::ifstream::in | std::ifstream::binary);
SI_Error rc = ini.Load(infile);
infile.close();
- if (rc < 0) {
- printf("Failed to open file.\n");
- return false;
- }
+ if (rc < 0) {
+ printf("Failed to open file.\n");
+ return false;
+ }
Test(ini);
- // save the file (simple)
- _tprintf(_T("\n-- Saving file to: testsi-out-streams.ini\n"));
+ // save the file (simple)
+ _tprintf(_T("\n-- Saving file to: testsi-out-streams.ini\n"));
std::ofstream outfile;
outfile.open("testsi-out-streams.ini", std::ofstream::out | std::ofstream::binary);
- ini.Save(outfile);
+ ini.Save(outfile);
outfile.close();
return true;
}
-#endif // SI_SUPPORT_IOSTREAMS
-
-static bool
-TestFile(
- const TCHAR * a_pszFile,
- bool a_bIsUtf8,
- bool a_bUseMultiKey,
- bool a_bUseMultiLine
- )
-{
- // load the file
- CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine);
- _tprintf(_T("Loading file: %s\n"), a_pszFile);
- SI_Error rc = ini.LoadFile(a_pszFile);
- if (rc < 0) {
- printf("Failed to open file.\n");
- return false;
- }
-
- // run the tests
- Test(ini);
-
- // save the file (simple)
- _tprintf(_T("\n-- Saving file to: testsi-out.ini\n"));
- ini.SaveFile("testsi-out.ini");
-
- // save the file (with comments)
- // Note: to save the file and add a comment to the beginning, use
- // code such as the following.
- _tprintf(_T("\n-- Saving file to: testsi-out-comment.ini\n"));
- FILE * fp = fopen("testsi-out-comment.ini", "wb");
- if (fp) {
- // add a string to the file in the correct text format
- CSimpleIni::Converter convert = ini.GetConverter();
- convert.ConvertToStore(_T("; output from testsi.cpp test program")
- SI_NEWLINE SI_NEWLINE);
-
- CSimpleIni::FileWriter writer(fp);
- if (a_bIsUtf8) {
- writer.Write(SI_BOM_UTF8);
- }
- writer.Write(convert.Data());
- ini.Save(writer);
-
- fclose(fp);
- }
-
- return true;
-}
-
-static bool
-ParseCommandLine(
- int argc,
- TCHAR * argv[],
- const TCHAR * & a_pszFile,
- bool & a_bIsUtf8,
- bool & a_bUseMultiKey,
- bool & a_bUseMultiLine
- )
-{
- a_pszFile = 0;
- a_bIsUtf8 = false;
- a_bUseMultiKey = false;
- a_bUseMultiLine = false;
- for (--argc; argc > 0; --argc) {
- if (argv[argc][0] == '-') {
- switch (argv[argc][1]) {
- case TCHAR('u'):
- a_bIsUtf8 = true;
- break;
- case TCHAR('m'):
- a_bUseMultiKey = true;
- break;
- case TCHAR('l'):
- a_bUseMultiLine = true;
- break;
- }
- }
- else {
- a_pszFile = argv[argc];
- }
- }
- if (!a_pszFile) {
- _tprintf(
- _T("Usage: testsi [-u] [-m] [-l] iniFile\n")
- _T(" -u Load file as UTF-8 (Default is to use system locale)\n")
- _T(" -m Enable multiple keys\n")
- _T(" -l Enable multiple line values\n")
- );
- return false;
- }
-
- return true;
-}
-
-extern bool TestStreams();
-
-int
-_tmain(
- int argc,
- TCHAR * argv[]
- )
-{
- setlocale(LC_ALL, "");
-
- // start of automated testing...
- TestStreams();
-
- // parse the command line
- const TCHAR * pszFile;
- bool bIsUtf8, bUseMultiKey, bUseMultiLine;
- if (!ParseCommandLine(argc, argv, pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
- return 1;
- }
-
- // run the test
- if (!TestFile(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
- return 1;
- }
-#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
- if (!TestStreams(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
- return 1;
- }
-#endif
-
- return 0;
-}
-
+#endif // SI_SUPPORT_IOSTREAMS
+
+static bool
+TestFile(
+ const TCHAR * a_pszFile,
+ bool a_bIsUtf8,
+ bool a_bUseMultiKey,
+ bool a_bUseMultiLine
+ )
+{
+ // load the file
+ CSimpleIni ini(a_bIsUtf8, a_bUseMultiKey, a_bUseMultiLine);
+ _tprintf(_T("Loading file: %s\n"), a_pszFile);
+ SI_Error rc = ini.LoadFile(a_pszFile);
+ if (rc < 0) {
+ printf("Failed to open file.\n");
+ return false;
+ }
+
+ // run the tests
+ Test(ini);
+
+ // save the file (simple)
+ _tprintf(_T("\n-- Saving file to: testsi-out.ini\n"));
+ ini.SaveFile("testsi-out.ini");
+
+ // save the file (with comments)
+ // Note: to save the file and add a comment to the beginning, use
+ // code such as the following.
+ _tprintf(_T("\n-- Saving file to: testsi-out-comment.ini\n"));
+ FILE * fp = NULL;
+#if __STDC_WANT_SECURE_LIB__
+ fopen_s(&fp, "testsi-out-comment.ini", "wb");
+#else
+ fp = fopen("testsi-out-comment.ini", "wb");
+#endif
+ if (fp) {
+ // add a string to the file in the correct text format
+ CSimpleIni::Converter convert = ini.GetConverter();
+ convert.ConvertToStore(_T("; output from testsi.cpp test program")
+ SI_NEWLINE SI_NEWLINE);
+
+ CSimpleIni::FileWriter writer(fp);
+ if (a_bIsUtf8) {
+ writer.Write(SI_BOM_UTF8);
+ }
+ writer.Write(convert.Data());
+ ini.Save(writer);
+
+ fclose(fp);
+ }
+
+ return true;
+}
+
+static bool
+ParseCommandLine(
+ int argc,
+ TCHAR * argv[],
+ const TCHAR * & a_pszFile,
+ bool & a_bIsUtf8,
+ bool & a_bUseMultiKey,
+ bool & a_bUseMultiLine
+ )
+{
+ a_pszFile = 0;
+ a_bIsUtf8 = false;
+ a_bUseMultiKey = false;
+ a_bUseMultiLine = false;
+ for (--argc; argc > 0; --argc) {
+ if (argv[argc][0] == '-') {
+ switch (argv[argc][1]) {
+ case TCHAR('u'):
+ a_bIsUtf8 = true;
+ break;
+ case TCHAR('m'):
+ a_bUseMultiKey = true;
+ break;
+ case TCHAR('l'):
+ a_bUseMultiLine = true;
+ break;
+ }
+ }
+ else {
+ a_pszFile = argv[argc];
+ }
+ }
+ if (!a_pszFile) {
+ _tprintf(
+ _T("Usage: testsi [-u] [-m] [-l] iniFile\n")
+ _T(" -u Load file as UTF-8 (Default is to use system locale)\n")
+ _T(" -m Enable multiple keys\n")
+ _T(" -l Enable multiple line values\n")
+ );
+ return false;
+ }
+
+ return true;
+}
+
+extern bool TestStreams();
+
+int
+_tmain(
+ int argc,
+ TCHAR * argv[]
+ )
+{
+ setlocale(LC_ALL, "");
+
+ // start of automated testing...
+ TestStreams();
+
+ // parse the command line
+ const TCHAR * pszFile;
+ bool bIsUtf8, bUseMultiKey, bUseMultiLine;
+ if (!ParseCommandLine(argc, argv, pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
+ return 1;
+ }
+
+ // run the test
+ if (!TestFile(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
+ return 1;
+ }
+#if defined(SI_SUPPORT_IOSTREAMS) && !defined(_UNICODE)
+ if (!TestStreams(pszFile, bIsUtf8, bUseMultiKey, bUseMultiLine)) {
+ return 1;
+ }
+#endif
+
+ return 0;
+}
+