cfg: Reimplement ConfigFile using C++ maps and strings

This commit is contained in:
Jan Holthuis 2015-08-18 19:36:19 +02:00 committed by Stefanos Kornilios Mitsis Poiitidis
parent f065bc5289
commit 7a5c90ccca
3 changed files with 255 additions and 284 deletions

View File

@ -28,13 +28,13 @@ void savecfgf()
printf("Error : Unable to open file for saving \n"); printf("Error : Unable to open file for saving \n");
else else
{ {
cfgdb.SaveFile(cfgfile); cfgdb.save(cfgfile);
fclose(cfgfile); fclose(cfgfile);
} }
} }
void cfgSaveStr(const wchar * Section, const wchar * Key, const wchar * String) void cfgSaveStr(const wchar * Section, const wchar * Key, const wchar * String)
{ {
cfgdb.GetEntry(Section)->SetEntry(Key,String,CEM_SAVE); cfgdb.set(string(Section), string(Key), string(String));
savecfgf(); savecfgf();
//WritePrivateProfileString(Section,Key,String,cfgPath); //WritePrivateProfileString(Section,Key,String,cfgPath);
} }
@ -42,7 +42,7 @@ void cfgSaveStr(const wchar * Section, const wchar * Key, const wchar * String)
/* /*
I want config to be really flexible .. so , here is the new implementation : I want config to be really flexible .. so , here is the new implementation :
Functions : Functions :
cfgLoadInt : Load an int , if it does not exist save the default value to it and return it cfgLoadInt : Load an int , if it does not exist save the default value to it and return it
cfgSaveInt : Save an int cfgSaveInt : Save an int
@ -84,28 +84,28 @@ bool cfgOpen()
FILE* cfgfile = fopen(cfgPath.c_str(),"r"); FILE* cfgfile = fopen(cfgPath.c_str(),"r");
if(!cfgfile) { if(!cfgfile) {
cfgfile = fopen(cfgPath.c_str(),"wt"); cfgfile = fopen(cfgPath.c_str(),"wt");
if(!cfgfile) if(!cfgfile)
printf("Unable to open the config file for reading or writing\nfile : %s\n",cfgPath.c_str()); printf("Unable to open the config file for reading or writing\nfile : %s\n",cfgPath.c_str());
else else
{ {
fseek(cfgfile,0,SEEK_SET); fseek(cfgfile,0,SEEK_SET);
fclose(cfgfile); fclose(cfgfile);
cfgfile = fopen(cfgPath.c_str(),"r"); cfgfile = fopen(cfgPath.c_str(),"r");
if(!cfgfile) if(!cfgfile)
printf("Unable to open the config file for reading\nfile : %s\n",cfgPath.c_str()); printf("Unable to open the config file for reading\nfile : %s\n",cfgPath.c_str());
} }
} }
cfgdb.ParseFile(cfgfile); cfgdb.parse(cfgfile);
for (size_t i=0;i<vlist.size();i++) /*for (size_t i=0;i<vlist.size();i++)
{ {
cfgdb.GetEntry(vlist[i].s)->SetEntry(vlist[i].n,vlist[i].v,CEM_VIRTUAL); cfgdb.GetEntry(vlist[i].s)->SetEntry(vlist[i].n,vlist[i].v,CEM_VIRTUAL);
} }*/
if (cfgfile) if (cfgfile)
{ {
cfgdb.SaveFile(cfgfile); cfgdb.save(cfgfile);
fclose(cfgfile); fclose(cfgfile);
} }
return true; return true;
@ -119,32 +119,48 @@ bool cfgOpen()
//2 : found section & key //2 : found section & key
s32 cfgExists(const wchar * Section, const wchar * Key) s32 cfgExists(const wchar * Section, const wchar * Key)
{ {
return cfgdb.Exists(Section, Key); if(cfgdb.has_entry(string(Section), string(Key)))
{
return 2;
}
else
{
return (cfgdb.has_section(string(Section)) ? 1 : 0);
}
} }
void cfgLoadStr(const wchar * Section, const wchar * Key, wchar * Return,const wchar* Default) void cfgLoadStr(const wchar * Section, const wchar * Key, wchar * Return,const wchar* Default)
{ {
return cfgdb.LoadStr(Section, Key, Return, Default); string value = cfgdb.get(Section, Key, Default);
strcpy(Return, value.c_str());
} }
string cfgLoadStr(const wchar * Section, const wchar * Key, const wchar* Default) string cfgLoadStr(const wchar * Section, const wchar * Key, const wchar* Default)
{ {
return cfgdb.LoadStr(Section, Key, Default); if(!cfgdb.has_entry(string(Section), string(Key)))
{
cfgSaveStr(Section, Key, Default);
}
return cfgdb.get(string(Section), string(Key), string(Default));
} }
//These are helpers , mainly :) //These are helpers , mainly :)
s32 cfgLoadInt(const wchar * Section, const wchar * Key,s32 Default)
{
return cfgdb.LoadInt(Section, Key, Default);
}
void cfgSaveInt(const wchar * Section, const wchar * Key, s32 Int) void cfgSaveInt(const wchar * Section, const wchar * Key, s32 Int)
{ {
wchar tmp[32]; return cfgdb.set_int(string(Section), string(Key), Int);
sprintf(tmp,"%d", Int);
cfgSaveStr(Section,Key,tmp);
} }
s32 cfgLoadInt(const wchar * Section, const wchar * Key,s32 Default)
{
if(!cfgdb.has_entry(string(Section), string(Key)))
{
cfgSaveInt(Section, Key, Default);
}
return cfgdb.get_int(string(Section), string(Key), Default);
}
void cfgSetVirtual(const wchar * Section, const wchar * Key, const wchar * String) void cfgSetVirtual(const wchar * Section, const wchar * Key, const wchar * String)
{ {
vlist.push_back(vitem(Section,Key,String)); //vlist.push_back(vitem(Section,Key,String));
//cfgdb.GetEntry(Section,CEM_VIRTUAL)->SetEntry(Key,String,CEM_VIRTUAL); //cfgdb.GetEntry(Section,CEM_VIRTUAL)->SetEntry(Key,String,CEM_VIRTUAL);
} }

View File

@ -1,299 +1,252 @@
#include "ini.h" #include "ini.h"
#include <sstream>
wchar* trim_ws(wchar* str); wchar* trim_ws(wchar* str);
ConfigEntry::ConfigEntry(ConfigEntry* pp) /* ConfigEntry */
string ConfigEntry::get_string()
{ {
next=pp; return this->value;
flags=0;
} }
void ConfigEntry::SaveFile(FILE* file) int ConfigEntry::get_int()
{ {
if (flags & CEM_SAVE) if (strstr(this->value.c_str(), "0x") != NULL)
fprintf(file,"%s=%s\n",name.c_str(),value.c_str());
}
string ConfigEntry::GetValue()
{
if (flags&CEM_VIRTUAL)
return valueVirtual;
else
return value;
}
ConfigSection::ConfigSection(ConfigSection* pp)
{
next=pp;
flags=0;
entrys=0;
}
ConfigEntry* ConfigSection::FindEntry(string name)
{
ConfigEntry* c= entrys;
while(c)
{ {
if (stricmp(name.c_str(),c->name.c_str())==0) return strtol(this->value.c_str(), NULL, 16);
return c;
c=c->next;
}
return 0;
}
void ConfigSection::SetEntry(string name,string value,u32 eflags)
{
ConfigEntry* c=FindEntry(name);
if (c)
{
//readonly is read only =)
if (c->flags & CEM_READONLY)
return;
//virtual : save only if different value
if (c->flags & CEM_VIRTUAL)
{
if(stricmp(c->valueVirtual.c_str(),value.c_str())==0)
return;
c->flags&=~CEM_VIRTUAL;
}
} }
else else
{ {
entrys=c= new ConfigEntry(entrys); return atoi(this->value.c_str());
c->name=name;
} }
}
verify(!(c->flags&(CEM_VIRTUAL|CEM_READONLY))); bool ConfigEntry::get_bool()
//Virtual {
//Virtual | ReadOnly if (strcmp(this->value.c_str(), "yes") == 0 ||
//Save strcmp(this->value.c_str(), "true") == 0 ||
if (eflags & CEM_VIRTUAL) strcmp(this->value.c_str(), "on") == 0 ||
strcmp(this->value.c_str(), "1") == 0)
{ {
verify(!(eflags & CEM_SAVE)); return true;
c->flags|=eflags;
c->valueVirtual=value;
}
else if (eflags & CEM_SAVE)
{
verify(!(eflags & (CEM_VIRTUAL|CEM_READONLY)));
flags|=CEM_SAVE;
c->flags|=CEM_SAVE;
c->value=value;
} }
else else
{ {
die("Invalid eflags value"); return false;
} }
} }
ConfigSection::~ConfigSection() /* ConfigSection */
bool ConfigSection::has_entry(string name)
{ {
ConfigEntry* n=entrys; return (this->entries.count(name) == 1);
};
while(n)
ConfigEntry* ConfigSection::get_entry(string name)
{
if(this->has_entry(name))
{ {
ConfigEntry* p=n; return &this->entries[name];
n=n->next;
delete p;
} }
return NULL;
};
void ConfigSection::set(string name, string value, int flags)
{
ConfigEntry new_entry = { value, flags };
this->entries[name] = new_entry;
};
/* ConfigFile */
bool ConfigFile::has_section(string name)
{
return (this->sections.count(name) == 1);
};
bool ConfigFile::has_entry(string section_name, string entry_name)
{
ConfigSection* section = this->get_section(section_name);
return ((section == NULL) ? false : section->has_entry(entry_name));
} }
void ConfigSection::SaveFile(FILE* file) ConfigSection* ConfigFile::add_section(string name)
{ {
if (flags&CEM_SAVE) ConfigSection new_section;
this->sections.insert(std::make_pair(name, new_section));
return &this->sections[name];
};
ConfigSection* ConfigFile::get_section(string name)
{
if(this->has_section(name))
{ {
fprintf(file,"[%s]\n",name.c_str()); return &this->sections[name];
vector<ConfigEntry*> stuff;
ConfigEntry* n=entrys;
while(n)
{
stuff.push_back(n);
n=n->next;
}
for (int i=stuff.size()-1;i>=0;i--)
{
stuff[i]->SaveFile(file);
}
fprintf(file,"\n");
} }
} return NULL;
};
ConfigSection* ConfigFile::FindSection(string name) ConfigEntry* ConfigFile::get_entry(string section_name, string entry_name)
{ {
ConfigSection* c= entrys; ConfigSection* section = this->get_section(section_name);
while(c) if(section == NULL)
{ {
if (stricmp(name.c_str(),c->name.c_str())==0) return NULL;
return c;
c=c->next;
} }
return 0; return section->get_entry(entry_name);
} }
ConfigSection* ConfigFile::GetEntry(string name) string ConfigFile::get(string section_name, string entry_name, string default_value)
{ {
ConfigSection* c=FindSection(name); ConfigEntry* entry = this->get_entry(section_name, entry_name);
if (!c) if (entry == NULL)
{ {
entrys=c= new ConfigSection(entrys); return default_value;
c->name=name;
} }
else
return c;
}
ConfigFile::~ConfigFile()
{
ConfigSection* n=entrys;
while(n)
{ {
ConfigSection* p=n; return entry->get_string();
n=n->next;
delete p;
} }
} }
void ConfigFile::ParseFile(FILE* file) int ConfigFile::get_int(string section_name, string entry_name, int default_value)
{ {
wchar line[512]; ConfigEntry* entry = this->get_entry(section_name, entry_name);
wchar cur_sect[512]={0}; if (entry == NULL)
int cline=0; {
return default_value;
}
else
{
return entry->get_int();
}
}
bool ConfigFile::get_bool(string section_name, string entry_name, bool default_value)
{
ConfigEntry* entry = this->get_entry(section_name, entry_name);
if (entry == NULL)
{
return default_value;
}
else
{
return entry->get_bool();
}
}
void ConfigFile::set(string section_name, string entry_name, string value, int flags)
{
ConfigSection* section = this->get_section(section_name);
if(section == NULL)
{
section = this->add_section(section_name);
}
section->set(entry_name, value, flags);
};
void ConfigFile::set_int(string section_name, string entry_name, int value, int flags)
{
std::stringstream str_value;
str_value << value;
this->set(section_name, entry_name, str_value.str());
}
void ConfigFile::set_bool(string section_name, string entry_name, bool value, int flags)
{
string str_value = (value ? "yes" : "no");
this->set(section_name, entry_name, str_value);
}
void ConfigFile::parse(FILE* file)
{
if(file == NULL)
{
return;
}
char line[512];
char current_section[512] = { '\0' };
int cline = 0;
while(file && !feof(file)) while(file && !feof(file))
{ {
fgets(line,512,file); fgets(line, 512, file);
if (feof(file)) if (feof(file))
{
break; break;
}
cline++; cline++;
if (strlen(line)<3) if (strlen(line) < 3)
continue;
if (line[strlen(line)-1]=='\r' || line[strlen(line)-1]=='\n')
line[strlen(line)-1]=0;
wchar* tl=trim_ws(line);
if (tl[0]=='[' && tl[strlen(tl)-1]==']')
{ {
tl[strlen(tl)-1]=0; continue;
strcpy(cur_sect,tl+1); }
trim_ws(cur_sect);
if (line[strlen(line)-1] == '\r' ||
line[strlen(line)-1] == '\n')
{
line[strlen(line)-1] = '\0';
}
char* tl = trim_ws(line);
if (tl[0] == '[' && tl[strlen(tl)-1] == ']')
{
tl[strlen(tl)-1] = '\0';
strcpy(current_section, tl+1);
trim_ws(current_section);
} }
else else
{ {
if (cur_sect[0]==0) if (strlen(current_section) == 0)
continue;//no open section
wchar* str1=strstr(tl,"=");
if (!str1)
{ {
printf("Malformed entry on config - ignoring @ %d(%s)\n",cline,tl); continue; //no open section
}
char* separator = strstr(tl, "=");
if (!separator)
{
printf("Malformed entry on config - ignoring @ %d(%s)\n",cline, tl);
continue; continue;
} }
*str1=0;
str1++; *separator = '\0';
wchar* v=trim_ws(str1);
wchar* k=trim_ws(tl); char* name = trim_ws(tl);
if (v && k) char* value = trim_ws(separator + 1);
if (name == NULL || value == NULL)
{ {
ConfigSection*cs=this->GetEntry(cur_sect); printf("Malformed entry on config - ignoring @ %d(%s)\n",cline, tl);
continue;
//if (!cs->FindEntry(k))
cs->SetEntry(k,v,CEM_SAVE|CEM_LOAD);
} }
else else
{ {
printf("Malformed entry on config - ignoring @ %d(%s)\n",cline,tl); this->set(string(current_section), string(name), string(value));
} }
} }
} }
} }
void ConfigFile::SaveFile(FILE* file) void ConfigFile::save(FILE* file)
{ {
vector<ConfigSection*> stuff; for(std::map<string, ConfigSection>::iterator section_it = this->sections.begin();
section_it != this->sections.end(); section_it++)
ConfigSection* n=entrys;
while(n)
{ {
stuff.push_back(n); string section_name = section_it->first;
n=n->next; ConfigSection section = section_it->second;
} fprintf(file, "[%s]\n", section_name.c_str());
for (int i=stuff.size()-1;i>=0;i--) for(std::map<string, ConfigEntry>::iterator entry_it = section.entries.begin();
{ entry_it != section.entries.end(); entry_it++)
if (stuff[i]->name!="emu") {
stuff[i]->SaveFile(file); string entry_name = entry_it->first;
} ConfigEntry entry = entry_it->second;
} fprintf(file, "%s = %s\n", entry_name.c_str(), entry.get_string().c_str());
}
s32 ConfigFile::Exists(const wchar * Section, const wchar * Key)
{ fputs("\n", file);
if (Section==0)
return -1;
//return cfgRead(Section,Key,0);
ConfigSection*cs= this->FindSection(Section);
if (cs == 0)
return 0;
if (Key==0)
return 1;
ConfigEntry* ce=cs->FindEntry(Key);
if (ce!=0)
return 2;
else
return 0;
}
void ConfigFile::LoadStr(const wchar * Section, const wchar * Key, wchar * Return,const wchar* Default)
{
verify(Return!=0);
string value = this->LoadStr(Section, Key, Default);
strcpy(Return, value.c_str());
}
string ConfigFile::LoadStr(const wchar * Section, const wchar * Key, const wchar* Default)
{
verify(Section != 0 && strlen(Section) != 0);
verify(Key != 0 && strlen(Key) != 0);
if (Default == 0)
Default = "";
ConfigSection* cs = this->GetEntry(Section);
ConfigEntry* ce = cs->FindEntry(Key);
if (!ce)
{
cs->SetEntry(Key, Default, CEM_SAVE);
return Default;
}
else
{
return ce->GetValue();
}
}
s32 ConfigFile::LoadInt(const wchar * Section, const wchar * Key,s32 Default)
{
wchar temp_d[30];
wchar temp_o[30];
sprintf(temp_d,"%d",Default);
this->LoadStr(Section,Key,temp_o,temp_d);
if (strstr(temp_o, "0x") != NULL)
{
return strtol(temp_o, NULL, 16);
}
else
{
return atoi(temp_o);
} }
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "types.h" #include "types.h"
#include <map>
//A config remains virtual only as long as a write at it //A config remains virtual only as long as a write at it
//doesn't override the virtual value.While a config is virtual, a copy of its 'real' value is held and preserved //doesn't override the virtual value.While a config is virtual, a copy of its 'real' value is held and preserved
@ -7,47 +8,48 @@
//Is this a virtual entry ? //Is this a virtual entry ?
#define CEM_VIRTUAL 1 #define CEM_VIRTUAL 1
//Should the value be saved ? //Should the value be saved ?
#define CEM_SAVE 2 #define CEM_SAVE 2
//is this entry readonly ? //is this entry readonly ?
#define CEM_READONLY 4 #define CEM_READONLY 4
//the move is from loading ? //the move is from loading ?
#define CEM_LOAD 8 #define CEM_LOAD 8
struct ConfigEntry struct ConfigEntry {
{
u32 flags;
string name;
string value; string value;
string valueVirtual; int flags; //TODO: These have no effect right now
ConfigEntry* next; string get_string();
ConfigEntry(ConfigEntry*); int get_int();
string GetValue(); bool get_bool();
void SaveFile(FILE*);
}; };
struct ConfigSection struct ConfigSection {
{ std::map<string, ConfigEntry> entries;
u32 flags; bool has_entry(string name);
string name; void set(string name, string value, int flags);
ConfigEntry* entrys; ConfigEntry* get_entry(string name);
ConfigSection* next;
~ConfigSection();
ConfigSection(ConfigSection*);
ConfigEntry* FindEntry(string);
void SetEntry(string, string, u32);
void SaveFile(FILE*);
}; };
struct ConfigFile struct ConfigFile {
{ private:
ConfigSection* entrys; std::map<string, ConfigSection> sections;
~ConfigFile(); ConfigSection* add_section(string name);
void ParseFile(FILE*); ConfigSection* get_section(string name);
void SaveFile(FILE*); ConfigEntry* get_entry(string section_name, string entry_name);
ConfigSection* FindSection(string);
ConfigSection* GetEntry(string);
s32 Exists(const wchar *, const wchar *); public:
void LoadStr(const wchar *, const wchar *, wchar *,const wchar*); bool has_section(string name);
string LoadStr(const wchar *, const wchar *, const wchar*); bool has_entry(string section_name, string entry_name);
s32 LoadInt(const wchar *, const wchar *,s32);
}; void parse(FILE* fd);
void save(FILE* fd);
/* getting values */
string get(string section_name, string entry_name, string default_value = "");
int get_int(string section_name, string entry_name, int default_value = 0);
bool get_bool(string section_name, string entry_name, bool default_value = false);
/* setting values */
void set(string section_name, string entry_name, string value, int flags = 0);
void set_int(string section_name, string entry_name, int value, int flags = 0);
void set_bool(string section_name, string entry_name, bool value, int flags = 0);
};