mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-17 21:03:19 +08:00
Merge pull request #4186 from RaiKoHoff/Dev_Master
Fix Margin handling (context, bookmarks)
This commit is contained in:
commit
4df9d9eb0c
@ -4,9 +4,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.19
|
||||
</table>
|
||||
|
||||
Jump to the @link CSimpleIniTempl CSimpleIni @endlink interface documentation.
|
||||
@ -43,22 +43,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
|
||||
@ -89,6 +98,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
|
||||
|
||||
@ -214,34 +225,6 @@
|
||||
# pragma warning (disable: 4127 4503 4702 4786)
|
||||
#endif
|
||||
|
||||
// Defines the conversion classes for different libraries. Before including
|
||||
// SimpleIni.h, set the converter that you wish you use by defining one of the
|
||||
// following symbols.
|
||||
//
|
||||
// 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)
|
||||
# ifdef _WIN32
|
||||
# define SI_CONVERT_WIN32
|
||||
# else
|
||||
# define SI_CONVERT_GENERIC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef SI_CONVERT_WIN32
|
||||
#ifndef VC_EXTRALEAN
|
||||
#define VC_EXTRALEAN 1
|
||||
#endif
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <cstring> // for wcscpy_s, wcscat_s
|
||||
#include <cstdlib> // for _countof
|
||||
#include <string>
|
||||
@ -249,7 +232,6 @@
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <strsafe.h>
|
||||
|
||||
#ifdef SI_SUPPORT_IOSTREAMS
|
||||
# include <iostream>
|
||||
@ -264,18 +246,25 @@
|
||||
# define SI_ASSERT(x)
|
||||
#endif
|
||||
|
||||
//using SI_Error = int;
|
||||
//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)
|
||||
enum class SI_Error : int {
|
||||
SI_OK = 0, //!< No error
|
||||
SI_UPDATED = 1, //!< An existing value was updated
|
||||
SI_INSERTED = 2, //!< A new value was inserted
|
||||
|
||||
SI_OK = 0, //!< No error
|
||||
SI_UPDATED = 1, //!< An existing value was updated
|
||||
SI_INSERTED = 2, //!< A new value was inserted
|
||||
// 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)
|
||||
SI_FAIL = -1, //!< Generic failure
|
||||
SI_NOMEM = -2, //!< Out of memory error
|
||||
SI_FILE = -3 //!< File error (see errno for detail error)
|
||||
};
|
||||
|
||||
|
||||
#define SI_UTF8_SIGNATURE "\xEF\xBB\xBF"
|
||||
#define SI_UTF16LE_SIGNATURE "\xFF\xFE"
|
||||
#define SI_UTF16BE_SIGNATURE "\xFE\xFF"
|
||||
@ -332,7 +321,7 @@ template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
|
||||
class CSimpleIniTempl
|
||||
{
|
||||
public:
|
||||
using SI_CHAR_T = SI_CHAR;
|
||||
typedef SI_CHAR SI_CHAR_T;
|
||||
|
||||
/** key entry */
|
||||
struct Entry {
|
||||
@ -384,15 +373,15 @@ public:
|
||||
};
|
||||
|
||||
/** map keys to values */
|
||||
using TKeyVal = std::multimap<Entry,const SI_CHAR *,typename Entry::KeyOrder>;
|
||||
typedef std::multimap<Entry,const SI_CHAR *,typename Entry::KeyOrder> TKeyVal;
|
||||
|
||||
/** map sections to key/value map */
|
||||
using TSection = std::map<Entry,TKeyVal,typename Entry::KeyOrder>;
|
||||
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.
|
||||
*/
|
||||
using TNamesDepend = std::list<Entry>;
|
||||
typedef std::list<Entry> TNamesDepend;
|
||||
|
||||
/** interface definition for the OutputWriter object to pass to Save()
|
||||
in order to output the INI file data.
|
||||
@ -599,6 +588,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 */
|
||||
@ -910,6 +928,21 @@ public:
|
||||
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.
|
||||
@ -1293,8 +1326,9 @@ private:
|
||||
return isLess(a_pLeft, a_pRight);
|
||||
}
|
||||
|
||||
bool IsMultiLineTag(const SI_CHAR * a_pVal) const;
|
||||
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,
|
||||
@ -1326,6 +1360,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;
|
||||
|
||||
@ -1347,6 +1384,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.
|
||||
*/
|
||||
@ -1366,10 +1409,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)
|
||||
{ }
|
||||
|
||||
@ -1501,7 +1547,7 @@ CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::LoadFile(
|
||||
}
|
||||
|
||||
// allocate and ensure NULL terminated
|
||||
auto* pData = new(std::nothrow) char[(size_t)dwFileSize + 1];
|
||||
auto* pData = new(std::nothrow) char[(size_t)dwFileSize + static_cast<size_t>(1)];
|
||||
if (!pData) {
|
||||
return SI_Error::SI_NOMEM;
|
||||
}
|
||||
@ -1543,7 +1589,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
|
||||
}
|
||||
|
||||
// allocate and ensure NULL terminated
|
||||
auto * pData = new(std::nothrow) char[lSize+1];
|
||||
char * pData = new(std::nothrow) char[lSize+static_cast<size_t>(1)];
|
||||
if (!pData) {
|
||||
return SI_Error::SI_NOMEM;
|
||||
}
|
||||
@ -1739,6 +1785,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
|
||||
@ -1801,14 +1848,16 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::FindEntry(
|
||||
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;
|
||||
}
|
||||
@ -1821,6 +1870,9 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::FindEntry(
|
||||
--pTrail;
|
||||
}
|
||||
++pTrail;
|
||||
|
||||
if (bHaveValue) {
|
||||
// process the value
|
||||
*pTrail = 0;
|
||||
|
||||
// skip leading whitespace on the value
|
||||
@ -1853,6 +1905,23 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::FindEntry(
|
||||
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;
|
||||
}
|
||||
@ -1910,6 +1979,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(
|
||||
@ -1943,8 +2047,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
|
||||
@ -1988,7 +2092,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadMultiLineText(
|
||||
|
||||
// move this line down to the location that it should be if necessary
|
||||
if (pDataLine < pCurrLine) {
|
||||
auto nLen = (size_t) (a_pData - pCurrLine);
|
||||
size_t nLen = (size_t) (a_pData - pCurrLine);
|
||||
memmove(pDataLine, pCurrLine, nLen * sizeof(SI_CHAR));
|
||||
pDataLine[nLen] = '\0';
|
||||
}
|
||||
@ -2000,12 +2104,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) {
|
||||
@ -2123,6 +2235,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::AddEntry(
|
||||
// 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
|
||||
@ -2145,6 +2258,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) {
|
||||
@ -2169,8 +2287,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_Error::SI_INSERTED : SI_Error::SI_UPDATED;
|
||||
}
|
||||
@ -2621,8 +2739,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SaveFile(
|
||||
#else // !__STDC_WANT_SECURE_LIB__
|
||||
fp = fopen(a_pszFile, "wb");
|
||||
#endif // __STDC_WANT_SECURE_LIB__
|
||||
if (!fp)
|
||||
return SI_Error::SI_FILE;
|
||||
if (!fp) return SI_Error::SI_FILE;
|
||||
SI_Error rc = SaveFile(fp, a_bAddSignature);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
@ -2742,6 +2859,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) {
|
||||
@ -2822,27 +2952,35 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::Save(
|
||||
}
|
||||
a_oOutput.Write(convert.Data());
|
||||
|
||||
// write the value
|
||||
if (!convert.ConvertToStore(iValue->pItem)) {
|
||||
return SI_Error::SI_FAIL;
|
||||
}
|
||||
a_oOutput.Write(m_bSpaces ? " = " : "=");
|
||||
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);
|
||||
bNeedNewLine = false;
|
||||
if (!OutputMultiLineText(a_oOutput, convert, iValue->pItem)) {
|
||||
return SI_Error::SI_FAIL;
|
||||
// write the value as long
|
||||
if (*iValue->pItem || !m_bAllowKeyOnly) {
|
||||
if (!convert.ConvertToStore(iValue->pItem)) {
|
||||
return SI_Error::SI_FAIL;
|
||||
}
|
||||
a_oOutput.Write(m_bSpaces ? " = " : "=");
|
||||
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("\"");
|
||||
}
|
||||
a_oOutput.Write("END_OF_TEXT");
|
||||
}
|
||||
else {
|
||||
a_oOutput.Write(convert.Data());
|
||||
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);
|
||||
if (!OutputMultiLineText(a_oOutput, convert, iValue->pItem)) {
|
||||
return SI_Error::SI_FAIL;
|
||||
}
|
||||
a_oOutput.Write("END_OF_TEXT");
|
||||
}
|
||||
else {
|
||||
a_oOutput.Write(convert.Data());
|
||||
}
|
||||
}
|
||||
a_oOutput.Write(SI_NEWLINE_A);
|
||||
bNeedNewLine = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//???bNeedNewLine = true;
|
||||
}
|
||||
@ -2987,6 +3125,26 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::DeleteString(
|
||||
// CONVERSION FUNCTIONS
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Defines the conversion classes for different libraries. Before including
|
||||
// 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_NO_CONVERSION) && !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU)
|
||||
# ifdef _WIN32
|
||||
# define SI_CONVERT_WIN32
|
||||
# else
|
||||
# define SI_CONVERT_GENERIC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Generic case-sensitive less than comparison. This class returns numerically
|
||||
* ordered ASCII case-sensitive text for all possible sizes and types of
|
||||
@ -3553,6 +3711,13 @@ public:
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
#define VC_EXTRALEAN 1
|
||||
#endif
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifdef SI_NO_MBCS
|
||||
# define SI_NoCase SI_GenericNoCase
|
||||
#else // !SI_NO_MBCS
|
||||
@ -3705,6 +3870,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
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -3714,6 +3892,13 @@ using CSimpleIniA = CSimpleIniTempl<char,
|
||||
using CSimpleIniCaseA = CSimpleIniTempl<char,
|
||||
SI_Case<char>,SI_ConvertA<char> >;
|
||||
|
||||
#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;
|
||||
@ -3735,6 +3920,7 @@ using CSimpleIniCaseW = CSimpleIniTempl<wchar_t,
|
||||
# define CSimpleIniCase CSimpleIniCaseA
|
||||
# define SI_NEWLINE SI_NEWLINE_A
|
||||
#endif // _UNICODE
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (pop)
|
||||
|
||||
3625
src/Config/doc/SimpleIni_orig.h
Normal file
3625
src/Config/doc/SimpleIni_orig.h
Normal file
File diff suppressed because it is too large
Load Diff
19
src/Edit.c
19
src/Edit.c
@ -9466,16 +9466,21 @@ void EditBookmarkToggle(HWND hwnd, const DocLn ln, const int modifiers)
|
||||
UNREFERENCED_PARAMETER(hwnd);
|
||||
int const all = ALL_MARKERS_BITMASK();
|
||||
int const bitmask = SciCall_MarkerGet(ln) & all;
|
||||
if (!bitmask) {
|
||||
SciCall_MarkerAdd(ln, MARKER_NP3_BOOKMARK); // set
|
||||
} else if (bitmask & BOOKMARK_BITMASK()) {
|
||||
bool const bookmark = (bool)(bitmask & BOOKMARK_BITMASK());
|
||||
if (bookmark) {
|
||||
SciCall_MarkerDelete(ln, MARKER_NP3_BOOKMARK); // unset
|
||||
} else {
|
||||
for (int m = MARKER_NP3_1; m < MARKER_NP3_BOOKMARK; ++m) {
|
||||
if (bitmask & (1 << m)) {
|
||||
SciCall_MarkerDeleteAll(m);
|
||||
}
|
||||
else {
|
||||
if (bitmask) {
|
||||
for (int m = MARKER_NP3_1; m < MARKER_NP3_BOOKMARK; ++m) {
|
||||
if (bitmask & (1 << m)) {
|
||||
SciCall_MarkerDeleteAll(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!bitmask || (bitmask == OCC_INVISIBLE_BITMASK())) {
|
||||
SciCall_MarkerAdd(ln, MARKER_NP3_BOOKMARK); // set
|
||||
}
|
||||
}
|
||||
if (modifiers & SCMOD_ALT) {
|
||||
SciCall_GotoLine(ln);
|
||||
|
||||
@ -1850,7 +1850,7 @@ HWND InitInstance(const HINSTANCE hInstance, LPCWSTR pszCmdLine, int nCmdShow)
|
||||
|
||||
UpdateToolbar();
|
||||
UpdateStatusbar(true);
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
ResetMouseDWellTime();
|
||||
|
||||
// print file immediately and quit
|
||||
@ -3189,7 +3189,7 @@ LRESULT MsgThemeChanged(HWND hwnd, WPARAM wParam,LPARAM lParam)
|
||||
|
||||
UpdateToolbar();
|
||||
UpdateStatusbar(true);
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
@ -3260,7 +3260,7 @@ LRESULT MsgSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
UpdateToolbar();
|
||||
UpdateStatusbar(true);
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
UpdateTitleBar(hwnd);
|
||||
|
||||
return FALSE;
|
||||
@ -3594,7 +3594,7 @@ LRESULT MsgCopyData(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
UpdateToolbar();
|
||||
UpdateStatusbar(true);
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@ -3664,7 +3664,7 @@ LRESULT MsgContextMenu(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
DocPos const iCurrentPos = SciCall_PositionFromPoint(pt.x, pt.y);
|
||||
DocLn const curLn = SciCall_LineFromPosition(iCurrentPos);
|
||||
int const bitmask = SciCall_MarkerGet(curLn) & OCCURRENCE_MARKER_BITMASK();
|
||||
int const bitmask = SciCall_MarkerGet(curLn) & (OCCURRENCE_MARKER_BITMASK() | BITMASK_GEN(int, SC_MARKNUM_HISTORY_REVERTED_TO_ORIGIN, 4));
|
||||
imenu = (bitmask && ((Settings.FocusViewMarkerMode & FVMM_LN_BACKGR) || !Settings.ShowBookmarkMargin)) ? MNU_MARGIN : MNU_EDIT;
|
||||
|
||||
if (imenu == MNU_EDIT) {
|
||||
@ -4751,7 +4751,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
BeginWaitCursorUID(true, IDS_MUI_SB_RECODING_DOC);
|
||||
if (EditSetNewEncoding(Globals.hwndEdit, iNewEncoding, (s_flagSetEncoding != CPI_NONE))) {
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
SetSaveNeeded();
|
||||
}
|
||||
EndWaitCursor();
|
||||
@ -5651,7 +5651,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
if (!IsWindow(Globals.hwndDlgCustomizeSchemes)) {
|
||||
Style_SetDefaultFont(Globals.hwndEdit, (iLoWParam == IDM_VIEW_FONT));
|
||||
}
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
UpdateUI();
|
||||
break;
|
||||
|
||||
@ -5779,13 +5779,13 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
case IDM_VIEW_LINENUMBERS:
|
||||
Settings.ShowLineNumbers = !Settings.ShowLineNumbers;
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
break;
|
||||
|
||||
|
||||
case IDM_VIEW_BOOKMARK_MARGIN:
|
||||
Settings.ShowBookmarkMargin = !Settings.ShowBookmarkMargin;
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
break;
|
||||
|
||||
case IDM_SET_AUTOCOMPLETEWORDS:
|
||||
@ -5973,7 +5973,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
SciCall_SetChangeHistory(Settings.ShowChangeHistory);
|
||||
Style_SetChangeHistory(Globals.hwndEdit, ((Settings.ShowChangeHistory & ChgHist_ON) && (Settings.ShowChangeHistory & ChgHist_MARGIN)));
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
break;
|
||||
|
||||
|
||||
@ -6192,7 +6192,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
Settings.Bidirectional = SciCall_GetBidirectional();
|
||||
|
||||
if ((prevRT != Settings.RenderingTechnology) || (prevBD != Settings.Bidirectional)) {
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -8230,7 +8230,7 @@ static LRESULT _MsgNotifyFromEdit(HWND hwnd, const SCNotification* const scn)
|
||||
_SplitUndoTransaction();
|
||||
}
|
||||
}
|
||||
UpdateMarginWidth(false);
|
||||
UpdateMargins(false);
|
||||
}
|
||||
if (s_bInMultiEditMode && !(iModType & SC_MULTILINEUNDOREDO)) {
|
||||
if (!Sci_IsMultiSelection()) {
|
||||
@ -8300,7 +8300,7 @@ static LRESULT _MsgNotifyFromEdit(HWND hwnd, const SCNotification* const scn)
|
||||
}
|
||||
}
|
||||
if (iUpd & SC_UPDATE_CONTENT) {
|
||||
UpdateMarginWidth(false);
|
||||
UpdateMargins(false);
|
||||
//~ Style and Marker are out of scope here => using WM_COMMAND -> SCEN_CHANGE instead!
|
||||
//~MarkAllOccurrences(-1, false);
|
||||
//~EditUpdateVisibleIndicators(); // will lead to recursion
|
||||
@ -8432,7 +8432,7 @@ static LRESULT _MsgNotifyFromEdit(HWND hwnd, const SCNotification* const scn)
|
||||
break;
|
||||
|
||||
|
||||
case SCN_MARGINCLICK:
|
||||
case SCN_MARGINCLICK: {
|
||||
switch (scn->margin) {
|
||||
case MARGIN_SCI_FOLDING:
|
||||
EditFoldClick(SciCall_LineFromPosition(scn->position), scn->modifiers);
|
||||
@ -8447,7 +8447,8 @@ static LRESULT _MsgNotifyFromEdit(HWND hwnd, const SCNotification* const scn)
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SCN_MARGINRIGHTCLICK: {
|
||||
@ -8467,7 +8468,7 @@ static LRESULT _MsgNotifyFromEdit(HWND hwnd, const SCNotification* const scn)
|
||||
|
||||
case SCN_ZOOM:
|
||||
UpdateToolbar();
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
@ -9983,10 +9984,10 @@ static void _UpdateStatusbarDelayed(bool bForceRedraw)
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// UpdateMarginWidth()
|
||||
// UpdateMargins()
|
||||
//
|
||||
//
|
||||
void UpdateMarginWidth(const bool bForce)
|
||||
void UpdateMargins(const bool bForce)
|
||||
{
|
||||
static bool bShowLnNums = false;
|
||||
static DocLn prevLineCount = -1LL;
|
||||
@ -10109,7 +10110,7 @@ void UndoRedoRecordingStart()
|
||||
SciCall_SetUndoCollection(true);
|
||||
SetSavePoint();
|
||||
SciCall_SetChangeHistory(SC_CHANGE_HISTORY_ENABLED | Settings.ShowChangeHistory);
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
}
|
||||
|
||||
|
||||
@ -10129,7 +10130,7 @@ void UndoRedoRecordingStop()
|
||||
SciCall_SetChangeHistory(SC_CHANGE_HISTORY_DISABLED);
|
||||
SciCall_SetUndoCollection(false);
|
||||
SciCall_EmptyUndoBuffer();
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
}
|
||||
|
||||
|
||||
@ -10655,7 +10656,7 @@ bool FileLoad(const HPATHL hfile_pth, FileLoadFlags fLoadFlags)
|
||||
|
||||
SetSavePoint();
|
||||
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
UpdateStatusbar(true);
|
||||
UpdateTitleBar(Globals.hwndMain);
|
||||
|
||||
@ -10889,7 +10890,7 @@ bool FileLoad(const HPATHL hfile_pth, FileLoadFlags fLoadFlags)
|
||||
|
||||
UpdateTitleBar(Globals.hwndMain);
|
||||
UpdateToolbar();
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
UpdateStatusbar(true);
|
||||
|
||||
//~Path_Release(hopen_file) ~ already released
|
||||
@ -10955,7 +10956,7 @@ bool FileRevert(const HPATHL hfile_pth, bool bIgnoreCmdLnEnc)
|
||||
}
|
||||
|
||||
SetSavePoint();
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
UpdateStatusbar(true);
|
||||
UpdateToolbar();
|
||||
UpdateTitleBar(Globals.hwndMain);
|
||||
|
||||
@ -130,7 +130,7 @@ void MarkAllOccurrences(const int delay, const bool bForceClear);
|
||||
void UpdateUI();
|
||||
void UpdateToolbar();
|
||||
void UpdateStatusbar(const bool bForceRedraw);
|
||||
void UpdateMarginWidth(const bool bForce);
|
||||
void UpdateMargins(const bool bForce);
|
||||
void UpdateSaveSettingsCmds();
|
||||
void ResetMouseDWellTime();
|
||||
void UpdateTitleBar(const HWND hwnd);
|
||||
|
||||
@ -568,7 +568,7 @@ bool Style_DynamicThemesMenuCmd(int cmd)
|
||||
} else {
|
||||
Style_ResetCurrentLexer(Globals.hwndEdit);
|
||||
}
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
UpdateUI();
|
||||
}
|
||||
return result;
|
||||
@ -1726,7 +1726,7 @@ void Style_SetLexer(HWND hwnd, PEDITLEXER pLexNew)
|
||||
EditToggleView(Globals.hwndEdit);
|
||||
}
|
||||
|
||||
UpdateMarginWidth(true);
|
||||
UpdateMargins(true);
|
||||
|
||||
EndWaitCursor();
|
||||
|
||||
@ -2154,7 +2154,7 @@ void Style_SetMargin(HWND hwnd, LPCWSTR lpszStyle) /// iStyle == STYLE_LINENUMBE
|
||||
|
||||
// --- Change History ---
|
||||
SciCall_SetMarginBackN(MARGIN_SCI_CHGHIST, clrMarginBack);
|
||||
SciCall_SetMarginSensitiveN(MARGIN_SCI_CHGHIST, false);
|
||||
SciCall_SetMarginSensitiveN(MARGIN_SCI_CHGHIST, true);
|
||||
SciCall_MarkerSetBack(SC_MARKNUM_HISTORY_MODIFIED, clrMarginBack);
|
||||
//SciCall_MarkerSetBack(SC_MARKNUM_HISTORY_REVERTED_TO_ORIGIN, clrMarginBack);
|
||||
//SciCall_MarkerSetBack(SC_MARKNUM_HISTORY_SAVED, clrMarginBack);
|
||||
|
||||
@ -366,8 +366,9 @@ typedef enum MARKER_ID {
|
||||
|
||||
|
||||
#define BOOKMARK_BITMASK() BITMASK_GEN(int, MARKER_NP3_BOOKMARK, 1)
|
||||
#define OCCURRENCE_MARKER_BITMASK() BITMASK_GEN(int, 0, MARKER_NP3_8+1)
|
||||
#define ALL_MARKERS_BITMASK() BITMASK_GEN(int, 0, MARKER_NP3_BOOKMARK+1)
|
||||
#define OCC_INVISIBLE_BITMASK() BITMASK_GEN(int, MARKER_NP3_OCCURRENCE, 1)
|
||||
#define OCCURRENCE_MARKER_BITMASK() BITMASK_GEN(int, 0, MARKER_NP3_8 + 1)
|
||||
#define ALL_MARKERS_BITMASK() BITMASK_GEN(int, 0, MARKER_NP3_BOOKMARK + 1)
|
||||
|
||||
extern LPCWSTR WordBookMarks[];
|
||||
|
||||
|
||||
@ -110,7 +110,7 @@
|
||||
#endif
|
||||
#elif (_MSC_VER == 1929)
|
||||
#if (_MSC_FULL_VER >= 192930146)
|
||||
#define VER_CPL MS Visual C++ 2019 v16.11.(17-18)
|
||||
#define VER_CPL MS Visual C++ 2019 v16.11.(17-19)
|
||||
#elif (_MSC_FULL_VER >= 192930145)
|
||||
#define VER_CPL MS Visual C++ 2019 v16 .11.(15-16)
|
||||
#elif (_MSC_FULL_VER >= 192930144)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user