mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Core: INI_INT64, INI_INT and INI_INT64 now understand hex and K, M, G, T suffixes
git-svn-id: svn://ultimatepp.org/upp/trunk@5183 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
b445e09358
commit
cf0ee3a247
4 changed files with 356 additions and 262 deletions
|
|
@ -30,8 +30,8 @@ options(XGNU) -ffunction-sections;
|
|||
link(SOLARIS) "-Wl,-R -Wl,/usr/local/lib";
|
||||
|
||||
file
|
||||
config.h,
|
||||
Core.h,
|
||||
config.h,
|
||||
Defs.h,
|
||||
Cpu.cpp optimize_speed,
|
||||
Mt.h,
|
||||
|
|
@ -68,6 +68,7 @@ file
|
|||
Log.cpp,
|
||||
Debug.cpp,
|
||||
Util.h,
|
||||
Ini.cpp,
|
||||
Util.cpp optimize_speed,
|
||||
mathutil.cpp optimize_speed,
|
||||
Random.cpp,
|
||||
|
|
|
|||
316
uppsrc/Core/Ini.cpp
Normal file
316
uppsrc/Core/Ini.cpp
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
#include "Core.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
VectorMap<String, String> LoadIniStream(Stream &sin) {
|
||||
Stream *in = &sin;
|
||||
FileIn fin;
|
||||
VectorMap<String, String> key;
|
||||
int c;
|
||||
if((c = in->Get()) < 0) return key;
|
||||
for(;;) {
|
||||
String k, v;
|
||||
for(;;) {
|
||||
if(IsAlNum(c) || c == '_')
|
||||
k.Cat(c);
|
||||
else
|
||||
break;
|
||||
if((c = in->Get()) < 0) return key;
|
||||
}
|
||||
for(;;) {
|
||||
if(c != '=' && c != ' ') break;
|
||||
if((c = in->Get()) < 0) return key;
|
||||
}
|
||||
for(;;) {
|
||||
if(c < ' ') break;
|
||||
v.Cat(c);
|
||||
if((c = in->Get()) < 0) break;
|
||||
}
|
||||
if(!k.IsEmpty())
|
||||
key.Add(k, v);
|
||||
if(k == "LINK") {
|
||||
if(in == &fin)
|
||||
fin.Close();
|
||||
if(!fin.Open(v) || (c = in->Get()) < 0) return key;
|
||||
in = &fin;
|
||||
}
|
||||
else
|
||||
for(;;) {
|
||||
if(IsAlNum(c) || c == '_') break;
|
||||
if((c = in->Get()) < 0) return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorMap<String, String> LoadIniFile(const char *filename) {
|
||||
FileIn in(filename);
|
||||
if(!in) return VectorMap<String, String>();
|
||||
return LoadIniStream(in);
|
||||
}
|
||||
|
||||
static StaticMutex sMtx;
|
||||
static char sIniFile[256];
|
||||
static bool s_ini_loaded;
|
||||
|
||||
void ReloadIniFile()
|
||||
{
|
||||
s_ini_loaded = false;
|
||||
}
|
||||
|
||||
void SetIniFile(const char *name) {
|
||||
Mutex::Lock __(sMtx);
|
||||
strcpy(sIniFile, name);
|
||||
ReloadIniFile();
|
||||
}
|
||||
|
||||
String GetIniKey(const char *id, const String& def) {
|
||||
Mutex::Lock __(sMtx);
|
||||
static VectorMap<String, String> key;
|
||||
if(!s_ini_loaded) {
|
||||
s_ini_loaded = true;
|
||||
key = LoadIniFile(*sIniFile ? sIniFile : ~ConfigFile("q.ini"));
|
||||
#ifdef PLATFORM_WIN32
|
||||
if(key.GetCount() == 0)
|
||||
key = LoadIniFile(~GetExeDirFile("q.ini"));
|
||||
if(key.GetCount() == 0)
|
||||
key = LoadIniFile("c:\\q.ini");
|
||||
#endif
|
||||
#ifdef PLATFORM_POSIX
|
||||
if(key.GetCount() == 0)
|
||||
key = LoadIniFile(GetHomeDirFile("q.ini"));
|
||||
#endif
|
||||
}
|
||||
return key.Get(id, def);
|
||||
}
|
||||
|
||||
String GetIniKey(const char *id)
|
||||
{
|
||||
return GetIniKey(id, String());
|
||||
}
|
||||
|
||||
IniString::operator String()
|
||||
{
|
||||
ONCELOCK_(loaded) {
|
||||
static Array<String> ss;
|
||||
String& x = ss.Add();
|
||||
x = TrimBoth(GetIniKey(id));
|
||||
if(IsNull(x))
|
||||
x = (*def)();
|
||||
value = &x;
|
||||
}
|
||||
return *value;
|
||||
}
|
||||
|
||||
String IniString::operator=(const String& s)
|
||||
{
|
||||
operator String();
|
||||
*value = s;
|
||||
return s;
|
||||
}
|
||||
|
||||
String IniString::ToString() const
|
||||
{
|
||||
return (String)const_cast<IniString&>(*this);
|
||||
}
|
||||
|
||||
int64 ReadIniInt(const char *id)
|
||||
{
|
||||
String s = GetIniKey(id);
|
||||
CParser p(s);
|
||||
int64 num;
|
||||
int sgn = 1;
|
||||
if(p.Char('-'))
|
||||
sgn = -1;
|
||||
else
|
||||
p.Char('+');
|
||||
if(p.Char2('0', 'x') || p.Char2('0', 'X'))
|
||||
num = p.ReadNumber64(16);
|
||||
else
|
||||
if(p.IsNumber())
|
||||
num = p.ReadNumber();
|
||||
else
|
||||
return Null;
|
||||
num = sgn * num;
|
||||
if(p.Char('K'))
|
||||
num <<= 10;
|
||||
else
|
||||
if(p.Char('M'))
|
||||
num <<= 20;
|
||||
else
|
||||
if(p.Char('G'))
|
||||
num <<= 30;
|
||||
else
|
||||
if(p.Char('T'))
|
||||
num <<= 40;
|
||||
return num;
|
||||
}
|
||||
|
||||
IniInt::operator int() {
|
||||
ONCELOCK_(loaded) {
|
||||
value = (int)ReadIniInt(id);
|
||||
if(IsNull(value))
|
||||
value = (*def)();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int IniInt::operator=(int b) {
|
||||
ONCELOCK_(loaded) {}
|
||||
return value = b;
|
||||
}
|
||||
|
||||
String IniInt::ToString() const
|
||||
{
|
||||
return AsString((int)const_cast<IniInt&>(*this));
|
||||
}
|
||||
|
||||
IniInt64::operator int64()
|
||||
{
|
||||
ONCELOCK_(loaded) {
|
||||
value = ReadIniInt(id);
|
||||
if(IsNull(value))
|
||||
value = (*def)();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int64 IniInt64::operator=(int64 b)
|
||||
{
|
||||
ONCELOCK_(loaded) {}
|
||||
return value = b;
|
||||
}
|
||||
|
||||
String IniInt64::ToString() const
|
||||
{
|
||||
return AsString((int64)const_cast<IniInt64&>(*this));
|
||||
}
|
||||
|
||||
IniDouble::operator double()
|
||||
{
|
||||
ONCELOCK_(loaded) {
|
||||
value = ScanDouble(TrimBoth(ToLower(GetIniKey(id))));
|
||||
if(IsNull(value))
|
||||
value = (*def)();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
double IniDouble::operator=(double b)
|
||||
{
|
||||
ONCELOCK_(loaded) {}
|
||||
return value = b;
|
||||
}
|
||||
|
||||
String IniDouble::ToString() const
|
||||
{
|
||||
return AsString((double)const_cast<IniDouble&>(*this));
|
||||
}
|
||||
|
||||
IniBool::operator bool() {
|
||||
ONCELOCK_(loaded) {
|
||||
String h = TrimBoth(ToLower(GetIniKey(id)));
|
||||
if(h.GetCount())
|
||||
value = h == "1" || h == "yes" || h == "true" || h == "y";
|
||||
else
|
||||
value = (*def)();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool IniBool::operator=(bool b) {
|
||||
ONCELOCK_(loaded) {}
|
||||
return value = b;
|
||||
}
|
||||
|
||||
String IniBool::ToString() const
|
||||
{
|
||||
return AsString((bool)const_cast<IniBool&>(*this));
|
||||
}
|
||||
|
||||
|
||||
Array<IniInfo>& sIniInfo()
|
||||
{
|
||||
static Array<IniInfo> s;
|
||||
return s;
|
||||
}
|
||||
|
||||
void AddIniInfo(const char *id, String (*current)(), String (*def)(), const char *info)
|
||||
{
|
||||
IniInfo& f = sIniInfo().Add();
|
||||
f.id = id;
|
||||
f.current = current;
|
||||
f.def = def;
|
||||
f.info = info;
|
||||
}
|
||||
|
||||
const Array<IniInfo> GetIniInfo()
|
||||
{
|
||||
return sIniInfo();
|
||||
}
|
||||
|
||||
String GetIniInfoFormatted()
|
||||
{
|
||||
String r;
|
||||
for(int i = 0; i < sIniInfo().GetCount(); i++) {
|
||||
IniInfo& f = sIniInfo()[i];
|
||||
r << f.id << " = " << (*f.current)() << " [default: " << (*f.def)() << "]\r\n"
|
||||
<< " " << f.info << "\r\n";
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void TextSettings::Load(const char *filename)
|
||||
{
|
||||
FileIn in(filename);
|
||||
int themei = 0;
|
||||
settings.Add("");
|
||||
while(!in.IsEof()) {
|
||||
String ln = in.GetLine();
|
||||
const char *s = ln;
|
||||
if(*s == '[') {
|
||||
s++;
|
||||
String theme;
|
||||
while(*s && *s != ']')
|
||||
theme.Cat(*s++);
|
||||
themei = settings.FindAdd(theme);
|
||||
}
|
||||
else {
|
||||
if(themei >= 0) {
|
||||
String key;
|
||||
while(*s && *s != '=') {
|
||||
key.Cat(*s++);
|
||||
}
|
||||
if(*s == '=') s++;
|
||||
String value;
|
||||
while(*s) {
|
||||
value.Cat(*s++);
|
||||
}
|
||||
if(!IsEmpty(key))
|
||||
settings[themei].GetAdd(TrimBoth(key)) = TrimBoth(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String TextSettings::Get(const char *group, const char *key) const
|
||||
{
|
||||
int itemi = settings.Find(group);
|
||||
return itemi < 0 ? Null : settings.Get(group).Get(key, Null);
|
||||
}
|
||||
|
||||
String TextSettings::Get(int groupIndex, const char *key) const
|
||||
{
|
||||
return groupIndex >= 0 && groupIndex < settings.GetCount() ?
|
||||
settings[groupIndex].Get(key, Null) : Null;
|
||||
}
|
||||
|
||||
String TextSettings::Get(int groupIndex, int keyIndex) const
|
||||
{
|
||||
if (groupIndex >= 0 && groupIndex < settings.GetCount())
|
||||
return keyIndex >= 0 && keyIndex < settings[groupIndex].GetCount() ?
|
||||
settings[groupIndex][keyIndex] : Null;
|
||||
else
|
||||
return Null;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -342,263 +342,6 @@ WString Join(const Vector<WString>& im, const WString& delim) {
|
|||
}
|
||||
return r;
|
||||
}
|
||||
// ---------------------------
|
||||
|
||||
VectorMap<String, String> LoadIniStream(Stream &sin) {
|
||||
Stream *in = &sin;
|
||||
FileIn fin;
|
||||
VectorMap<String, String> key;
|
||||
int c;
|
||||
if((c = in->Get()) < 0) return key;
|
||||
for(;;) {
|
||||
String k, v;
|
||||
for(;;) {
|
||||
if(IsAlNum(c) || c == '_')
|
||||
k.Cat(c);
|
||||
else
|
||||
break;
|
||||
if((c = in->Get()) < 0) return key;
|
||||
}
|
||||
for(;;) {
|
||||
if(c != '=' && c != ' ') break;
|
||||
if((c = in->Get()) < 0) return key;
|
||||
}
|
||||
for(;;) {
|
||||
if(c < ' ') break;
|
||||
v.Cat(c);
|
||||
if((c = in->Get()) < 0) break;
|
||||
}
|
||||
if(!k.IsEmpty())
|
||||
key.Add(k, v);
|
||||
if(k == "LINK") {
|
||||
if(in == &fin)
|
||||
fin.Close();
|
||||
if(!fin.Open(v) || (c = in->Get()) < 0) return key;
|
||||
in = &fin;
|
||||
}
|
||||
else
|
||||
for(;;) {
|
||||
if(IsAlNum(c) || c == '_') break;
|
||||
if((c = in->Get()) < 0) return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorMap<String, String> LoadIniFile(const char *filename) {
|
||||
FileIn in(filename);
|
||||
if(!in) return VectorMap<String, String>();
|
||||
return LoadIniStream(in);
|
||||
}
|
||||
|
||||
static StaticMutex sMtx;
|
||||
static char sIniFile[256];
|
||||
static bool s_ini_loaded;
|
||||
|
||||
void ReloadIniFile()
|
||||
{
|
||||
s_ini_loaded = false;
|
||||
}
|
||||
|
||||
void SetIniFile(const char *name) {
|
||||
Mutex::Lock __(sMtx);
|
||||
strcpy(sIniFile, name);
|
||||
ReloadIniFile();
|
||||
}
|
||||
|
||||
String GetIniKey(const char *id, const String& def) {
|
||||
Mutex::Lock __(sMtx);
|
||||
static VectorMap<String, String> key;
|
||||
if(!s_ini_loaded) {
|
||||
s_ini_loaded = true;
|
||||
key = LoadIniFile(*sIniFile ? sIniFile : ~ConfigFile("q.ini"));
|
||||
#ifdef PLATFORM_WIN32
|
||||
if(key.GetCount() == 0)
|
||||
key = LoadIniFile(~GetExeDirFile("q.ini"));
|
||||
if(key.GetCount() == 0)
|
||||
key = LoadIniFile("c:\\q.ini");
|
||||
#endif
|
||||
#ifdef PLATFORM_POSIX
|
||||
if(key.GetCount() == 0)
|
||||
key = LoadIniFile(GetHomeDirFile("q.ini"));
|
||||
#endif
|
||||
}
|
||||
return key.Get(id, def);
|
||||
}
|
||||
|
||||
String GetIniKey(const char *id)
|
||||
{
|
||||
return GetIniKey(id, String());
|
||||
}
|
||||
|
||||
IniString::operator String()
|
||||
{
|
||||
ONCELOCK_(loaded) {
|
||||
static Array<String> ss;
|
||||
String& x = ss.Add();
|
||||
x = Nvl(TrimBoth(GetIniKey(id)), (*def)());
|
||||
value = &x;
|
||||
}
|
||||
return *value;
|
||||
}
|
||||
|
||||
String IniString::operator=(const String& s)
|
||||
{
|
||||
operator String();
|
||||
*value = s;
|
||||
return s;
|
||||
}
|
||||
|
||||
String IniString::ToString() const
|
||||
{
|
||||
return (String)const_cast<IniString&>(*this);
|
||||
}
|
||||
|
||||
IniInt::operator int() {
|
||||
ONCELOCK_(loaded) {
|
||||
value = ScanInt(TrimBoth(ToLower(GetIniKey(id))));
|
||||
if(IsNull(value))
|
||||
value = (*def)();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int IniInt::operator=(int b) {
|
||||
ONCELOCK_(loaded) {}
|
||||
return value = b;
|
||||
}
|
||||
|
||||
String IniInt::ToString() const
|
||||
{
|
||||
return AsString((int)const_cast<IniInt&>(*this));
|
||||
}
|
||||
|
||||
IniDouble::operator double()
|
||||
{
|
||||
ONCELOCK_(loaded) {
|
||||
value = ScanDouble(TrimBoth(ToLower(GetIniKey(id))));
|
||||
if(IsNull(value))
|
||||
value = (*def)();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
double IniDouble::operator=(double b)
|
||||
{
|
||||
ONCELOCK_(loaded) {}
|
||||
return value = b;
|
||||
}
|
||||
|
||||
String IniDouble::ToString() const
|
||||
{
|
||||
return AsString((double)const_cast<IniDouble&>(*this));
|
||||
}
|
||||
|
||||
IniBool::operator bool() {
|
||||
ONCELOCK_(loaded) {
|
||||
String h = TrimBoth(ToLower(GetIniKey(id)));
|
||||
value = h.GetCount() ? h == "1" || h == "yes" || h == "true" || h == "y" : (*def)();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool IniBool::operator=(bool b) {
|
||||
ONCELOCK_(loaded) {}
|
||||
return value = b;
|
||||
}
|
||||
|
||||
String IniBool::ToString() const
|
||||
{
|
||||
return AsString((bool)const_cast<IniBool&>(*this));
|
||||
}
|
||||
|
||||
|
||||
Array<IniInfo>& sIniInfo()
|
||||
{
|
||||
static Array<IniInfo> s;
|
||||
return s;
|
||||
}
|
||||
|
||||
void AddIniInfo(const char *id, String (*current)(), String (*def)(), const char *info)
|
||||
{
|
||||
IniInfo& f = sIniInfo().Add();
|
||||
f.id = id;
|
||||
f.current = current;
|
||||
f.def = def;
|
||||
f.info = info;
|
||||
}
|
||||
|
||||
const Array<IniInfo> GetIniInfo()
|
||||
{
|
||||
return sIniInfo();
|
||||
}
|
||||
|
||||
String GetIniInfoFormatted()
|
||||
{
|
||||
String r;
|
||||
for(int i = 0; i < sIniInfo().GetCount(); i++) {
|
||||
IniInfo& f = sIniInfo()[i];
|
||||
r << f.id << " = " << (*f.current)() << " [default: " << (*f.def)() << "]\r\n"
|
||||
<< " " << f.info << "\r\n";
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void TextSettings::Load(const char *filename)
|
||||
{
|
||||
FileIn in(filename);
|
||||
int themei = 0;
|
||||
settings.Add("");
|
||||
while(!in.IsEof()) {
|
||||
String ln = in.GetLine();
|
||||
const char *s = ln;
|
||||
if(*s == '[') {
|
||||
s++;
|
||||
String theme;
|
||||
while(*s && *s != ']')
|
||||
theme.Cat(*s++);
|
||||
themei = settings.FindAdd(theme);
|
||||
}
|
||||
else {
|
||||
if(themei >= 0) {
|
||||
String key;
|
||||
while(*s && *s != '=') {
|
||||
key.Cat(*s++);
|
||||
}
|
||||
if(*s == '=') s++;
|
||||
String value;
|
||||
while(*s) {
|
||||
value.Cat(*s++);
|
||||
}
|
||||
if(!IsEmpty(key))
|
||||
settings[themei].GetAdd(TrimBoth(key)) = TrimBoth(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String TextSettings::Get(const char *group, const char *key) const
|
||||
{
|
||||
int itemi = settings.Find(group);
|
||||
return itemi < 0 ? Null : settings.Get(group).Get(key, Null);
|
||||
}
|
||||
|
||||
String TextSettings::Get(int groupIndex, const char *key) const
|
||||
{
|
||||
return groupIndex >= 0 && groupIndex < settings.GetCount() ?
|
||||
settings[groupIndex].Get(key, Null) : Null;
|
||||
}
|
||||
|
||||
String TextSettings::Get(int groupIndex, int keyIndex) const
|
||||
{
|
||||
if (groupIndex >= 0 && groupIndex < settings.GetCount())
|
||||
return keyIndex >= 0 && keyIndex < settings[groupIndex].GetCount() ?
|
||||
settings[groupIndex][keyIndex] : Null;
|
||||
else
|
||||
return Null;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
|
||||
String timeFormat(double s) {
|
||||
if(s < 0.000001) return Sprintf("%5.2f ns", s * 1.0e9);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ struct IniString {
|
|||
String (*def)();
|
||||
bool loaded;
|
||||
String *value;
|
||||
|
||||
// "public:"
|
||||
operator String();
|
||||
String operator=(const String& s);
|
||||
String ToString() const;
|
||||
|
|
@ -47,19 +47,31 @@ struct IniInt {
|
|||
int (*def)();
|
||||
bool loaded;
|
||||
int value;
|
||||
|
||||
// "public:"
|
||||
operator int();
|
||||
int operator=(int b);
|
||||
String ToString() const;
|
||||
};
|
||||
|
||||
struct IniInt64 {
|
||||
// "private":
|
||||
const char *id;
|
||||
int64 (*def)();
|
||||
bool loaded;
|
||||
int64 value;
|
||||
// "public:"
|
||||
operator int64();
|
||||
int64 operator=(int64 b);
|
||||
String ToString() const;
|
||||
};
|
||||
|
||||
struct IniDouble {
|
||||
// "private":
|
||||
const char *id;
|
||||
double (*def)();
|
||||
bool loaded;
|
||||
double value;
|
||||
|
||||
// "public:"
|
||||
operator double();
|
||||
double operator=(double b);
|
||||
String ToString() const;
|
||||
|
|
@ -71,7 +83,7 @@ struct IniBool {
|
|||
bool (*def)();
|
||||
bool loaded;
|
||||
bool value;
|
||||
|
||||
// "public:"
|
||||
operator bool();
|
||||
bool operator=(bool b);
|
||||
String ToString() const;
|
||||
|
|
@ -89,6 +101,20 @@ struct IniInfo {
|
|||
const Array<IniInfo> GetIniInfo();
|
||||
String GetIniInfoFormatted();
|
||||
|
||||
#define INI_TYPE(var, def, info, type, decl)\
|
||||
type DefIni_##var() { return def; }\
|
||||
decl var = { #var, DefIni_##var };\
|
||||
String AsStringIniCurrent_##var() { return AsString(var); } \
|
||||
String AsStringIniDefault_##var() { return AsString(DefIni_##var()); } \
|
||||
INITBLOCK { AddIniInfo(#var, AsStringIniCurrent_##var, AsStringIniDefault_##var, info); }
|
||||
|
||||
#define INI_BOOL(var, def, info) INI_TYPE(var, def, info, bool, IniBool);
|
||||
#define INI_STRING(var, def, info) INI_TYPE(var, def, info, String, IniString);
|
||||
#define INI_INT(var, def, info) INI_TYPE(var, def, info, int, IniInt);
|
||||
#define INI_INT64(var, def, info) INI_TYPE(var, def, info, int64, IniInt64);
|
||||
#define INI_DOUBLE(var, def, info) INI_TYPE(var, def, info, double, IniDouble);
|
||||
|
||||
/*
|
||||
#define INI_BOOL(var, def, info)\
|
||||
bool DefIni_##var() { return def; }\
|
||||
IniBool var = { #var, DefIni_##var };\
|
||||
|
|
@ -110,12 +136,20 @@ String AsStringIniCurrent_##var() { return AsString(var); } \
|
|||
String AsStringIniDefault_##var() { return AsString(DefIni_##var()); } \
|
||||
INITBLOCK { AddIniInfo(#var, AsStringIniCurrent_##var, AsStringIniDefault_##var, info); }
|
||||
|
||||
#define INI_INT64(var, def, info)\
|
||||
int64 DefIni_##var() { return def; }\
|
||||
Ini64Int var = { #var, DefIni_##var };\
|
||||
String AsStringIniCurrent_##var() { return AsString(var); } \
|
||||
String AsStringIniDefault_##var() { return AsString(DefIni_##var()); } \
|
||||
INITBLOCK { AddIniInfo(#var, AsStringIniCurrent_##var, AsStringIniDefault_##var, info); }
|
||||
|
||||
#define INI_DOUBLE(var, def, info)\
|
||||
double DefIni_##var() { return def; }\
|
||||
IniDouble var = { #var, DefIni_##var };\
|
||||
String AsStringIniCurrent_##var() { return AsString(var); } \
|
||||
String AsStringIniDefault_##var() { return AsString(DefIni_##var()); } \
|
||||
INITBLOCK { AddIniInfo(#var, AsStringIniCurrent_##var, AsStringIniDefault_##var, info); }
|
||||
*/
|
||||
|
||||
VectorMap<String, String> LoadIniStream(Stream &in);
|
||||
VectorMap<String, String> LoadIniFile(const char *filename);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue