rtemstoolkit: Update SimpleIni to latest

The resolves C++17 warnings.

Updates #4970
This commit is contained in:
Chris Johns
2023-11-22 14:30:59 +11:00
parent a4b312ee4f
commit 00af5a6ada

View File

@@ -3,9 +3,9 @@
<table>
<tr><th>Library <td>SimpleIni
<tr><th>File <td>SimpleIni.h
<tr><th>Author <td>Brodie Thiesfield [code at jellycan dot com]
<tr><th>Author <td>Brodie Thiesfield
<tr><th>Source <td>https://github.com/brofield/simpleini
<tr><th>Version <td>4.17
<tr><th>Version <td>4.20
</table>
Jump to the @link CSimpleIniTempl CSimpleIni @endlink interface documentation.
@@ -20,7 +20,7 @@
@section features FEATURES
- MIT Licence allows free use in all software (including GPL and commercial)
- multi-platform (Windows 95/98/ME/NT/2K/XP/2003, Windows CE, Linux, Unix)
- multi-platform (Windows CE/9x/NT..10/etc, Linux, MacOSX, Unix)
- loading and saving of INI-style configuration files
- configuration files can have any newline format on all platforms
- liberal acceptance of file format
@@ -42,22 +42,31 @@
- Windows/VC6 (warning level 3)
- Windows/VC.NET 2003 (warning level 4)
- Windows/VC 2005 (warning level 4)
- Windows/VC 2019 (warning level 4)
- Linux/gcc (-Wall)
@section usage USAGE SUMMARY
-# Decide if you will be using utf8 or MBCS files, and working with the
data in utf8, wchar_t or ICU chars.
-# If you will only be using straight utf8 files and access the data via the
char interface, then you do not need any conversion library and could define
SI_NO_CONVERSION. Note that no conversion also means no validation of the data.
If no converter is specified then the default converter is SI_CONVERT_GENERIC
on Mac/Linux and SI_CONVERT_WIN32 on Windows. If you need widechar support on
Mac/Linux then use either SI_CONVERT_GENERIC or SI_CONVERT_ICU. These are also
supported on all platforms.
-# Define the appropriate symbol for the converter you wish to use and
include the SimpleIni.h header file. If no specific converter is defined
then the default converter is used. The default conversion mode uses
SI_CONVERT_WIN32 on Windows and SI_CONVERT_GENERIC on all other
platforms. If you are using ICU then SI_CONVERT_ICU is supported on all
platforms.
-# Declare an instance the appropriate class. Note that the following
include the SimpleIni.h header file.
-# Declare an instance of the appropriate class. Note that the following
definitions are just shortcuts for commonly used types. Other types
(PRUnichar, unsigned short, unsigned char) are also possible.
<table>
<tr><th>Interface <th>Case-sensitive <th>Load UTF-8 <th>Load MBCS <th>Typedef
<tr><th>SI_NO_CONVERSION
<tr><td>char <td>No <td>Yes <td>No <td>CSimpleIniA
<tr><td>char <td>Yes <td>Yes <td>No <td>CSimpleIniCaseA
<tr><th>SI_CONVERT_GENERIC
<tr><td>char <td>No <td>Yes <td>Yes #1 <td>CSimpleIniA
<tr><td>char <td>Yes <td>Yes <td>Yes <td>CSimpleIniCaseA
@@ -88,6 +97,8 @@
<tr><td>GetValue <td>Return a value for a section & key
<tr><td>SetValue <td>Add or update a value for a section & key
<tr><td>Delete <td>Remove a section, or a key from a section
<tr><td>SectionExists <td>Does a section exist?
<tr><td>KeyExists <td>Does a key exist?
</table>
-# Call Save() or SaveFile() to save the INI configuration data
@@ -161,6 +172,7 @@
SI_STRLESS class, or by sorting the strings external to this library.
- Usage of the <mbstring.h> header on Windows can be disabled by defining
SI_NO_MBCS. This is defined automatically on Windows CE platforms.
- Not thread-safe so manage your own locking
@section contrib CONTRIBUTIONS
@@ -213,11 +225,11 @@
#endif
#include <cstring>
#include <cstdlib>
#include <string>
#include <map>
#include <list>
#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
#ifdef SI_SUPPORT_IOSTREAMS
@@ -233,16 +245,16 @@
# define SI_ASSERT(x)
#endif
enum SI_Error {
SI_OK = 0, //!< No error
SI_UPDATED = 1, //!< An existing value was updated
SI_INSERTED = 2, //!< A new value was inserted
using SI_Error = int;
// note: test for any error with (retval < 0)
SI_FAIL = -1, //!< Generic failure
SI_NOMEM = -2, //!< Out of memory error
SI_FILE = -3 //!< File error (see errno for detail error)
};
constexpr int SI_OK = 0; //!< No error
constexpr int SI_UPDATED = 1; //!< An existing value was updated
constexpr int SI_INSERTED = 2; //!< A new value was inserted
// note: test for any error with (retval < 0)
constexpr int SI_FAIL = -1; //!< Generic failure
constexpr int SI_NOMEM = -2; //!< Out of memory error
constexpr int SI_FILE = -3; //!< File error (see errno for detail error)
#define SI_UTF8_SIGNATURE "\xEF\xBB\xBF"
@@ -327,7 +339,7 @@ public:
#endif
/** Strict less ordering by name of key only */
struct KeyOrder : std::binary_function<Entry, Entry, bool> {
struct KeyOrder {
bool operator()(const Entry & lhs, const Entry & rhs) const {
const static SI_STRLESS isLess = SI_STRLESS();
return isLess(lhs.pItem, rhs.pItem);
@@ -335,7 +347,7 @@ public:
};
/** Strict less ordering by order, and then name of key */
struct LoadOrder : std::binary_function<Entry, Entry, bool> {
struct LoadOrder {
bool operator()(const Entry & lhs, const Entry & rhs) const {
if (lhs.nOrder != rhs.nOrder) {
return lhs.nOrder < rhs.nOrder;
@@ -541,6 +553,35 @@ public:
/** Query the status of spaces output */
bool UsingSpaces() const { return m_bSpaces; }
/** Should we recognise and parse quotes in single line values?
\param a_bParseQuotes Parse quoted data in values?
*/
void SetQuotes(bool a_bParseQuotes = true) {
m_bParseQuotes = a_bParseQuotes;
}
/** Are we permitting keys and values to be quoted? */
bool UsingQuotes() const { return m_bParseQuotes; }
/** When reading/writing an ini file, do we require every key to have an equals
sign to delineate a valid key value. If false, then every valid key must
have an equals sign and any lines without an equals sign is ignored. If
true then keys do not require an equals sign to be considered a key. Note
that this means that any non-commented line of text would become a key.
\param a_bAllowKeyOnly Permit keys without an equals sign or value.
*/
void SetAllowKeyOnly(bool a_bAllowKeyOnly = true) {
m_bAllowKeyOnly = a_bAllowKeyOnly;
}
/** Do we allow keys to exist without a value or equals sign? */
bool GetAllowKeyOnly() const { return m_bAllowKeyOnly; }
/*-----------------------------------------------------------------------*/
/** @}
@{ @name Loading INI Data */
@@ -837,13 +878,27 @@ public:
are in use!
@param a_pSection Name of the section to return
@return boolean Was a section matching the supplied
name found.
@return Section data
*/
const TKeyVal * GetSection(
const SI_CHAR * a_pSection
) const;
/** Test if a section exists. Convenience function */
inline bool SectionExists(
const SI_CHAR * a_pSection
) const {
return GetSection(a_pSection) != NULL;
}
/** Test if the key exists in a section. Convenience function. */
inline bool KeyExists(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey
) const {
return GetValue(a_pSection, a_pKey) != NULL;
}
/** Retrieve the value for a specific key. If multiple keys are enabled
(see SetMultiKey) then only the first value associated with that key
will be returned, see GetAllValues for getting all values with multikey.
@@ -1065,8 +1120,8 @@ public:
data returned by GetSection is invalid and must not be used after
anything has been deleted from that section using this method.
Note when multiple keys is enabled, this will delete all keys with
that name; there is no way to selectively delete individual key/values
in this situation.
that name; to selectively delete individual key/values, use
DeleteValue.
@param a_pSection Section to delete key from, or if
a_pKey is NULL, the section to remove.
@@ -1085,6 +1140,33 @@ public:
bool a_bRemoveEmpty = false
);
/** Delete an entire section, or a key from a section. If value is
provided, only remove keys with the value. Note that the data
returned by GetSection is invalid and must not be used after
anything has been deleted from that section using this method.
Note when multiple keys is enabled, all keys with the value will
be deleted.
@param a_pSection Section to delete key from, or if
a_pKey is NULL, the section to remove.
@param a_pKey Key to remove from the section. Set to
NULL to remove the entire section.
@param a_pValue Value of key to remove from the section.
Set to NULL to remove all keys.
@param a_bRemoveEmpty If the section is empty after this key has
been deleted, should the empty section be
removed?
@return true Key/value or section was deleted.
@return false Key/value or section was not found.
*/
bool DeleteValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
const SI_CHAR * a_pValue,
bool a_bRemoveEmpty = false
);
/*-----------------------------------------------------------------------*/
/** @}
@{ @name Converter */
@@ -1186,6 +1268,7 @@ private:
bool IsMultiLineTag(const SI_CHAR * a_pData) const;
bool IsMultiLineData(const SI_CHAR * a_pData) const;
bool IsSingleLineQuotedValue(const SI_CHAR* a_pData) const;
bool LoadMultiLineText(
SI_CHAR *& a_pData,
const SI_CHAR *& a_pVal,
@@ -1217,6 +1300,9 @@ private:
/** File comment for this data, if one exists. */
const SI_CHAR * m_pFileComment;
/** constant empty string */
const SI_CHAR m_cEmptyString;
/** Parsed INI data. Section -> (Key -> Value). */
TSection m_data;
@@ -1238,6 +1324,12 @@ private:
/** Should spaces be written out surrounding the equals sign? */
bool m_bSpaces;
/** Should quoted data in values be recognized and parsed? */
bool m_bParseQuotes;
/** Do keys always need to have an equals sign when reading/writing? */
bool m_bAllowKeyOnly;
/** Next order value, used to ensure sections and keys are output in the
same order that they are loaded/added.
*/
@@ -1257,10 +1349,13 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::CSimpleIniTempl(
: m_pData(0)
, m_uDataLen(0)
, m_pFileComment(NULL)
, m_cEmptyString(0)
, m_bStoreIsUtf8(a_bIsUtf8)
, m_bAllowMultiKey(a_bAllowMultiKey)
, m_bAllowMultiLine(a_bAllowMultiLine)
, m_bSpaces(true)
, m_bParseQuotes(false)
, m_bAllowKeyOnly(false)
, m_nOrder(0)
{ }
@@ -1359,7 +1454,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
}
// allocate and ensure NULL terminated
char * pData = new char[lSize+1];
char * pData = new(std::nothrow) char[lSize+static_cast<size_t>(1)];
if (!pData) {
return SI_NOMEM;
}
@@ -1386,21 +1481,26 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadData(
size_t a_uDataLen
)
{
SI_CONVERTER converter(m_bStoreIsUtf8);
if (!a_pData) {
return SI_OK;
}
// if the UTF-8 BOM exists, consume it and set mode to unicode, if we have
// already loaded data and try to change mode half-way through then this will
// be ignored and we will assert in debug versions
if (a_uDataLen >= 3 && memcmp(a_pData, SI_UTF8_SIGNATURE, 3) == 0) {
a_pData += 3;
a_uDataLen -= 3;
SI_ASSERT(m_bStoreIsUtf8 || !m_pData); // we don't expect mixed mode data
SetUnicode();
}
if (a_uDataLen == 0) {
return SI_OK;
}
// consume the UTF-8 BOM if it exists
if (m_bStoreIsUtf8 && a_uDataLen >= 3) {
if (memcmp(a_pData, SI_UTF8_SIGNATURE, 3) == 0) {
a_pData += 3;
a_uDataLen -= 3;
}
}
// determine the length of the converted data
SI_CONVERTER converter(m_bStoreIsUtf8);
size_t uLen = converter.SizeFromStore(a_pData, a_uDataLen);
if (uLen == (size_t)(-1)) {
return SI_FAIL;
@@ -1408,7 +1508,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadData(
// allocate memory for the data, ensure that there is a NULL
// terminator wherever the converted data ends
SI_CHAR * pData = new SI_CHAR[uLen+1];
SI_CHAR * pData = new(std::nothrow) SI_CHAR[uLen+1];
if (!pData) {
return SI_NOMEM;
}
@@ -1512,6 +1612,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::FindEntry(
{
a_pComment = NULL;
bool bHaveValue = false;
SI_CHAR * pTrail = NULL;
while (*a_pData) {
// skip spaces and empty lines
@@ -1569,19 +1670,20 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::FindEntry(
}
// find the end of the key name (it may contain spaces)
// and convert it to lowercase as necessary
a_pKey = a_pData;
while (*a_pData && *a_pData != '=' && !IsNewLineChar(*a_pData)) {
++a_pData;
}
// *a_pData is null, equals, or newline
// if it's an invalid line, just skip it
if (*a_pData != '=') {
// if no value and we don't allow no value, then invalid
bHaveValue = (*a_pData == '=');
if (!bHaveValue && !m_bAllowKeyOnly) {
continue;
}
// empty keys are invalid
if (a_pKey == a_pData) {
if (bHaveValue && a_pKey == a_pData) {
while (*a_pData && !IsNewLineChar(*a_pData)) {
++a_pData;
}
@@ -1594,6 +1696,9 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::FindEntry(
--pTrail;
}
++pTrail;
if (bHaveValue) {
// process the value
*pTrail = 0;
// skip leading whitespace on the value
@@ -1622,10 +1727,27 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::FindEntry(
// check for multi-line entries
if (m_bAllowMultiLine && IsMultiLineTag(a_pVal)) {
// skip the "<<<" to get the tag that will end the multiline
const SI_CHAR * pTagName = a_pVal + 3;
const SI_CHAR* pTagName = a_pVal + 3;
return LoadMultiLineText(a_pData, a_pVal, pTagName);
}
// check for quoted values, we are not supporting escapes in quoted values (yet)
if (m_bParseQuotes) {
--pTrail;
if (pTrail > a_pVal && *a_pVal == '"' && *pTrail == '"') {
++a_pVal;
*pTrail = 0;
}
}
}
else {
// no value to process, just prepare for the next
if (*a_pData) {
SkipNewLine(a_pData);
}
*pTrail = 0;
}
// return the standard entry
return true;
}
@@ -1683,6 +1805,41 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::IsMultiLineData(
return false;
}
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
bool
CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::IsSingleLineQuotedValue(
const SI_CHAR* a_pData
) const
{
// data needs quoting if it starts or ends with whitespace
// and doesn't have embedded newlines
// empty string
if (!*a_pData) {
return false;
}
// check for prefix
if (IsSpace(*a_pData)) {
return true;
}
// embedded newlines
while (*a_pData) {
if (IsNewLineChar(*a_pData)) {
return false;
}
++a_pData;
}
// check for suffix
if (IsSpace(*--a_pData)) {
return true;
}
return false;
}
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
bool
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::IsNewLineChar(
@@ -1716,8 +1873,8 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadMultiLineText(
a_pVal = a_pData;
// find the end tag. This tag must start in column 1 and be
// followed by a newline. No whitespace removal is done while
// searching for this tag.
// followed by a newline. We ignore any whitespace after the end
// tag but not whitespace before it.
SI_CHAR cEndOfLineChar = *a_pData;
for(;;) {
// if we are loading comments then we need a comment character as
@@ -1773,12 +1930,20 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadMultiLineText(
// if are looking for a tag then do the check now. This is done before
// checking for end of the data, so that if we have the tag at the end
// of the data then the tag is removed correctly.
if (a_pTagName &&
(!IsLess(pDataLine, a_pTagName) && !IsLess(a_pTagName, pDataLine)))
{
if (a_pTagName) {
// strip whitespace from the end of this tag
SI_CHAR* pc = a_pData - 1;
while (pc > pDataLine && IsSpace(*pc)) --pc;
SI_CHAR ch = *++pc;
*pc = 0;
if (!IsLess(pDataLine, a_pTagName) && !IsLess(a_pTagName, pDataLine)) {
break;
}
*pc = ch;
}
// if we are at the end of the data then we just automatically end
// this entry and return the current data.
if (!cEndOfLineChar) {
@@ -1833,7 +1998,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::CopyString(
for ( ; a_pString[uLen]; ++uLen) /*loop*/ ;
}
++uLen; // NULL character
SI_CHAR * pCopy = new SI_CHAR[uLen];
SI_CHAR * pCopy = new(std::nothrow) SI_CHAR[uLen];
if (!pCopy) {
return SI_NOMEM;
}
@@ -1878,7 +2043,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::AddEntry(
// only set the comment if this is a section only entry
Entry oSection(a_pSection, ++m_nOrder);
if (a_pComment && (!a_pKey || !a_pValue)) {
if (a_pComment && !a_pKey) {
oSection.pComment = a_pComment;
}
@@ -1888,14 +2053,15 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::AddEntry(
iSection = i.first;
bInserted = true;
}
if (!a_pKey || !a_pValue) {
// section only entries are specified with pItem and pVal as NULL
if (!a_pKey) {
// section only entries are specified with pItem as NULL
return bInserted ? SI_INSERTED : SI_UPDATED;
}
// check for existence of the key
TKeyVal & keyval = iSection->second;
typename TKeyVal::iterator iKey = keyval.find(a_pKey);
bInserted = iKey == keyval.end();
// remove all existing entries but save the load order and
// comment of the first entry
@@ -1918,6 +2084,11 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::AddEntry(
iKey = keyval.end();
}
// values need to be a valid string, even if they are an empty string
if (!a_pValue) {
a_pValue = &m_cEmptyString;
}
// make string copies if necessary
bool bForceCreateNewKey = m_bAllowMultiKey && !a_bForceReplace;
if (a_bCopyStrings) {
@@ -1942,8 +2113,8 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::AddEntry(
}
typename TKeyVal::value_type oEntry(oKey, static_cast<const SI_CHAR *>(NULL));
iKey = keyval.insert(oEntry);
bInserted = true;
}
iKey->second = a_pValue;
return bInserted ? SI_INSERTED : SI_UPDATED;
}
@@ -2010,10 +2181,10 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::GetLongValue(
char * pszSuffix = szValue;
if (szValue[0] == '0' && (szValue[1] == 'x' || szValue[1] == 'X')) {
if (!szValue[2]) return a_nDefault;
nValue = ::strtol(&szValue[2], &pszSuffix, 16);
nValue = strtol(&szValue[2], &pszSuffix, 16);
}
else {
nValue = ::strtol(szValue, &pszSuffix, 10);
nValue = strtol(szValue, &pszSuffix, 10);
}
// any invalid strings will return the default value
@@ -2043,7 +2214,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SetLongValue(
#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE
sprintf_s(szInput, a_bUseHex ? "0x%lx" : "%ld", a_nValue);
#else // !__STDC_WANT_SECURE_LIB__
sprintf(szInput, a_bUseHex ? "0x%lx" : "%ld", a_nValue);
snprintf(szInput, sizeof(szInput), a_bUseHex ? "0x%lx" : "%ld", a_nValue);
#endif // __STDC_WANT_SECURE_LIB__
// convert to output text
@@ -2105,7 +2276,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SetDoubleValue(
#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE
sprintf_s(szInput, "%f", a_nValue);
#else // !__STDC_WANT_SECURE_LIB__
sprintf(szInput, "%f", a_nValue);
snprintf(szInput, sizeof(szInput), "%f", a_nValue);
#endif // __STDC_WANT_SECURE_LIB__
// convert to output text
@@ -2390,6 +2561,19 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Save(
oSections.sort(typename Entry::LoadOrder());
#endif
// if there is an empty section name, then it must be written out first
// regardless of the load order
typename TNamesDepend::iterator is = oSections.begin();
for (; is != oSections.end(); ++is) {
if (!*is->pItem) {
// move the empty section name to the front of the section list
if (is != oSections.begin()) {
oSections.splice(oSections.begin(), oSections, is, std::next(is));
}
break;
}
}
// write the file comment if we have one
bool bNeedNewLine = false;
if (m_pFileComment) {
@@ -2465,12 +2649,20 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Save(
}
a_oOutput.Write(convert.Data());
// write the value
// write the value as long
if (*iValue->pItem || !m_bAllowKeyOnly) {
if (!convert.ConvertToStore(iValue->pItem)) {
return SI_FAIL;
}
a_oOutput.Write(m_bSpaces ? " = " : "=");
if (m_bAllowMultiLine && IsMultiLineData(iValue->pItem)) {
if (m_bParseQuotes && IsSingleLineQuotedValue(iValue->pItem)) {
// the only way to preserve external whitespace on a value (i.e. before or after)
// is to quote it. This is simple quoting, we don't escape quotes within the data.
a_oOutput.Write("\"");
a_oOutput.Write(convert.Data());
a_oOutput.Write("\"");
}
else if (m_bAllowMultiLine && IsMultiLineData(iValue->pItem)) {
// multi-line data needs to be processed specially to ensure
// that we use the correct newline format for the current system
a_oOutput.Write("<<<END_OF_TEXT" SI_NEWLINE_A);
@@ -2482,6 +2674,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Save(
else {
a_oOutput.Write(convert.Data());
}
}
a_oOutput.Write(SI_NEWLINE_A);
}
}
@@ -2528,6 +2721,18 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Delete(
const SI_CHAR * a_pKey,
bool a_bRemoveEmpty
)
{
return DeleteValue(a_pSection, a_pKey, NULL, a_bRemoveEmpty);
}
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
bool
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::DeleteValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
const SI_CHAR * a_pValue,
bool a_bRemoveEmpty
)
{
if (!a_pSection) {
return false;
@@ -2545,18 +2750,30 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Delete(
return false;
}
const static SI_STRLESS isLess = SI_STRLESS();
// remove any copied strings and then the key
typename TKeyVal::iterator iDelete;
bool bDeleted = false;
do {
iDelete = iKeyVal++;
if(a_pValue == NULL ||
(isLess(a_pValue, iDelete->second) == false &&
isLess(iDelete->second, a_pValue) == false)) {
DeleteString(iDelete->first.pItem);
DeleteString(iDelete->second);
iSection->second.erase(iDelete);
bDeleted = true;
}
}
while (iKeyVal != iSection->second.end()
&& !IsLess(a_pKey, iKeyVal->first.pItem));
if(!bDeleted) {
return false;
}
// done now if the section is not empty or we are not pruning away
// the empty sections. Otherwise let it fall through into the section
// deletion code
@@ -2610,13 +2827,15 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::DeleteString(
// SimpleIni.h, set the converter that you wish you use by defining one of the
// following symbols.
//
// SI_NO_CONVERSION Do not make the "W" wide character version of the
// library available. Only CSimpleIniA etc is defined.
// SI_CONVERT_GENERIC Use the Unicode reference conversion library in
// the accompanying files ConvertUTF.h/c
// SI_CONVERT_ICU Use the IBM ICU conversion library. Requires
// ICU headers on include path and icuuc.lib
// SI_CONVERT_WIN32 Use the Win32 API functions for conversion.
#if !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU)
#if !defined(SI_NO_CONVERSION) && !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU)
# ifdef _WIN32
# define SI_CONVERT_WIN32
# else
@@ -2873,7 +3092,7 @@ public:
// This uses the Unicode reference implementation to do the
// conversion from UTF-8 to wchar_t. The required files are
// ConvertUTF.h and ConvertUTF.c which should be included in
// the distribution but are publically available from unicode.org
// the distribution but are publicly available from unicode.org
// at http://www.unicode.org/Public/PROGRAMS/CVTUTF/
ConversionResult retval;
const UTF8 * pUtf8 = (const UTF8 *) a_pInputData;
@@ -2960,7 +3179,7 @@ public:
// This uses the Unicode reference implementation to do the
// conversion from wchar_t to UTF-8. The required files are
// ConvertUTF.h and ConvertUTF.c which should be included in
// the distribution but are publically available from unicode.org
// the distribution but are publicly available from unicode.org
// at http://www.unicode.org/Public/PROGRAMS/CVTUTF/
ConversionResult retval;
UTF8 * pUtf8 = (UTF8 *) a_pOutputData;
@@ -3346,6 +3565,19 @@ public:
#endif // SI_CONVERT_WIN32
// ---------------------------------------------------------------------------
// SI_NO_CONVERSION
// ---------------------------------------------------------------------------
#ifdef SI_NO_CONVERSION
#define SI_Case SI_GenericCase
#define SI_NoCase SI_GenericNoCase
#endif // SI_NO_CONVERSION
// ---------------------------------------------------------------------------
// TYPE DEFINITIONS
// ---------------------------------------------------------------------------
@@ -3355,27 +3587,35 @@ typedef CSimpleIniTempl<char,
typedef CSimpleIniTempl<char,
SI_Case<char>,SI_ConvertA<char> > CSimpleIniCaseA;
#if defined(SI_CONVERT_ICU)
#if defined(SI_NO_CONVERSION)
// if there is no wide char conversion then we don't need to define the
// widechar "W" versions of CSimpleIni
# define CSimpleIni CSimpleIniA
# define CSimpleIniCase CSimpleIniCaseA
# define SI_NEWLINE SI_NEWLINE_A
#else
# if defined(SI_CONVERT_ICU)
typedef CSimpleIniTempl<UChar,
SI_NoCase<UChar>,SI_ConvertW<UChar> > CSimpleIniW;
typedef CSimpleIniTempl<UChar,
SI_Case<UChar>,SI_ConvertW<UChar> > CSimpleIniCaseW;
#else
# else
typedef CSimpleIniTempl<wchar_t,
SI_NoCase<wchar_t>,SI_ConvertW<wchar_t> > CSimpleIniW;
typedef CSimpleIniTempl<wchar_t,
SI_Case<wchar_t>,SI_ConvertW<wchar_t> > CSimpleIniCaseW;
#endif
# endif
#ifdef _UNICODE
# ifdef _UNICODE
# define CSimpleIni CSimpleIniW
# define CSimpleIniCase CSimpleIniCaseW
# define SI_NEWLINE SI_NEWLINE_W
#else // !_UNICODE
# else // !_UNICODE
# define CSimpleIni CSimpleIniA
# define CSimpleIniCase CSimpleIniCaseA
# define SI_NEWLINE SI_NEWLINE_A
#endif // _UNICODE
# endif // _UNICODE
#endif
#ifdef _MSC_VER
# pragma warning (pop)