Fill in this config system. Next up: Use it.

This commit is contained in:
Alcaro
2016-05-01 16:59:12 +02:00
parent 289971ad78
commit 7d54b5f271
4 changed files with 180 additions and 28 deletions

View File

@@ -845,6 +845,10 @@ int GUIShow(const char * filename)
int main(int argc, char * argv[])
{
canShowGUI=gtk_parse_args(&argc, &argv);
if (canShowGUI)
{
cfg.load_file(get_cfgpath());
}
return flipsmain(argc, argv);
}
#endif

133
flips.cpp
View File

@@ -76,7 +76,8 @@ struct mem file::read()
{
struct mem out;
out.len = len();
out.ptr = (uint8_t*)malloc(out.len);
out.ptr = (uint8_t*)malloc(out.len + sizeof(WCHAR));
memset(out.ptr + out.len, 0, sizeof(WCHAR));
if (!read(out.ptr, 0, out.len))
{
free(out.ptr);
@@ -180,34 +181,146 @@ enum patchtype IdentifyPatch(file* patch)
config::config(struct mem contents)
//this is the most inefficient possible implementation. it works, that's all I care about
void config::init_raw(LPWSTR contents)
{
LPCWSTR header = TEXT("[Flips]\n");
if (wcsncmp(contents, header, wcslen(header)) != 0) return;
contents += wcslen(header);
//I need to somehow ensure that stepping backwards across whitespace doesn't go before the original string.
//This can be done with while (iswspace(*contents)) contents++;, but demanding the header above works just as well.
while (true)
{
LPWSTR key;
LPWSTR keyend;
LPWSTR val;
LPWSTR valend;
LPWSTR nextline = wcschr(contents, '\n');
if (nextline != NULL) valend = nextline;
else valend = wcschr(contents, '\0');
//do not move inside the conditional, it screws up the strchr
while (iswspace(valend[-1])) valend--;
*valend = '\0';
LPWSTR sep = wcschr(contents, '=');
if (sep != NULL)
{
key = contents;
keyend = sep;
val = sep+1;
while (iswspace(key[0])) key++;
while (iswspace(keyend[-1])) keyend--;
*keyend = '\0';
while (iswspace(val[0])) val++;
if (valend>val && keyend>key)
{
set(key, val);
}
}
if (!nextline) break;
contents = nextline+1;
while (contents && iswspace(*contents)) contents++;
}
}
config::config(LPCWSTR filename)
void config::init_file(LPCWSTR filename)
{
struct mem data = file::read(filename);
if (data.len > 0 && data.len%sizeof(WCHAR) == 0)
{
this->init_raw((LPWSTR)(data.ptr));
}
free(data.ptr);
this->filename = wcsdup(filename);
}
void config::setbin(const char * name, struct mem value)
void config::set(LPCWSTR name, LPCWSTR value)
{
//printf("(%s)(%s)\n",name,value);
for (size_t i=0;i<this->numentries;i++)
{
if (!wcscmp(name, this->names[i]))
{
free(this->values[i]);
this->values[i] = wcsdup(value);
return;
}
}
this->numentries++;
this->names = (LPWSTR*)realloc(this->names, sizeof(LPWSTR)*this->numentries);
this->values = (LPWSTR*)realloc(this->values, sizeof(LPWSTR)*this->numentries);
this->names[this->numentries-1] = wcsdup(name);
this->values[this->numentries-1] = wcsdup(value);
}
struct mem config::getbin(const char * name)
LPCWSTR config::get(LPCWSTR name)
{
for (size_t i=0;i<this->numentries;i++)
{
if (!wcscmp(name, this->names[i]))
{
return this->values[i];
}
}
return NULL;
}
struct mem config::flatten()
LPWSTR config::flatten()
{
LPCWSTR header = TEXT("[Flips]\n");
size_t len = wcslen(header);
for (size_t i=0;i<this->numentries;i++)
{
len += wcslen(this->names[i]) + 1 + wcslen(this->values[i]) + 1;
}
LPWSTR ret = (LPWSTR)malloc((len+1)*sizeof(WCHAR));
LPWSTR at = ret;
at += wsprintf(at, "%s", header);
for (size_t i=0;i<this->numentries;i++)
{
at += wsprintf(at, "%s=%s\n", this->names[i], this->values[i]);
}
return ret;
}
config::~config()
{
if (this->filename) filewrite::write(this->filename, this->contents);
free(this->filename);
free(this->contents.ptr);
if (this->filename)
{
LPWSTR data = this->flatten();
//puts(data);
filewrite::write(this->filename, (struct mem){ (uint8_t*)data, wcslen(data)*sizeof(WCHAR) });
free(data);
free(this->filename);
}
for (size_t i=0;i<this->numentries;i++)
{
//printf("#(%s)(%s)\n",this->names[i],this->values[i]);
free(this->names[i]);
free(this->values[i]);
}
free(this->names);
free(this->values);
}
config cfg;

70
flips.h
View File

@@ -34,7 +34,7 @@
//#define EXTERN_C
//#endif
#define flipsversion "Flips v1.32"
#define flipsversion "Flips v1.40"
#if defined(FLIPS_WINDOWS)
@@ -53,6 +53,7 @@
#include <wchar.h>
#include <stdio.h>
#include <commctrl.h>
#include <ctype.h>
#define wcsicmp _wcsicmp//wcsicmp deprecated? fuck that, I use what I want. I do not add underlines to a few randomly chosen functions.
#define wcsdup _wcsdup
@@ -65,15 +66,17 @@
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
//Flips uses Windows type names internally, since it's easier to #define them to Linux types than
//defining "const char *" to anything else, and since I use char* at some places (mainly libips/etc)
//and really don't want to try to split them. Inventing my own typedefs seems counterproductive as
//defining "const char *" to anything else. Inventing my own typedefs seems counterproductive as
//well; they would bring no advantage over Windows typenames except not being Windows typenames, and
//I don't see that as a valid argument.
#define LPCWSTR const char *
#define LPWSTR char *
#define WCHAR char
#define wcscpy strcpy
#define wcscat strcat
#define wcschr strchr
@@ -85,15 +88,32 @@
#define wcsicmp strcasecmp
//#define wcsnicmp strncasecmp
#define wprintf printf
#define wsprintf sprintf
#define iswalnum isalnum
#define iswalpha isalpha
#define iswascii isascii
#define iswblank isblank
#define iswcntrl iscntrl
#define iswdigit isdigit
#define iswgraph isgraph
#define iswlower islower
#define iswprint isprint
#define iswpunct ispunct
#define iswspace isspace
#define iswupper isupper
#define iswxdigit isxdigit
#define TEXT(text) text
//EXTERN_C int strcasecmp(const char *s1, const char *s2);
//some platforms define strdup, some don't.
#define strdup strdup_flips
static inline char* strdup(const char * in)
{
size_t len=strlen(in);
char * ret=(char*)malloc(len+1);
strcpy(ret, in);
memcpy(ret, in, len+1);
return ret;
}
#endif
@@ -157,29 +177,43 @@ bool shouldRemoveHeader(LPCWSTR romname, size_t romlen);
class config
{
LPWSTR filename;
struct mem contents;
size_t numentries;
LPWSTR * names;
LPWSTR * values;
//stupid c++, why is there no sane way to get the implementation out of the headers
bool parse(LPCWSTR contents);
public:
config(struct mem contents);
config(LPCWSTR filename);
void set(const char * name, LPCWSTR value)
config()
{
setbin(name, (struct mem){(uint8_t*)value, (wcslen(value)+1)*sizeof(WCHAR)});
numentries = 0;
names = NULL;
values = NULL;
}
void setbin(const char * name, struct mem value);
// free() these three when you're done with them.
LPWSTR get(const char * name)
{
return (LPWSTR)(getbin(name).ptr);
}
struct mem getbin(const char * name);
//This ends up writing a really ugly format on Windows: UTF-16, no BOM, LF endings.
// I can't do anything else without adding a #ifdef, and that would reward Microsoft for being
// dickbutts and not supporting UTF-8 properly.
//I could use CRLF instead, but I want the file broken in Notepad; if I use CRLF, it adds a BOM,
// and there's no way to get rid of that without a ifdef. If I break the file, people won't try.
//If the input is invalid, the object will ignore the invalid parts and remain valid.
//In particular, failing to initialize from a file will update the file on destruction.
//Only init once.
void init_file(LPCWSTR filename);
void init_raw(LPWSTR contents); // Modifies the contents.
struct mem flatten();
//Neither of those may have leading or trailing whitespace, or contain a \n. \r isn't recommended either.
//Additionally, the name may not contain =.
void set(LPCWSTR name, LPCWSTR value);
LPCWSTR get(LPCWSTR name);
~config();
LPWSTR flatten(); // free() this when you're done.
~config(); // If you used init_file, this saves automatically.
};
extern config cfg;
struct mem GetRomList();
void SetRomList(struct mem data);

View File

@@ -33,6 +33,7 @@ public:
virtual size_t len() = 0;
virtual bool read(uint8_t* target, size_t start, size_t len) = 0;
//these two add sizeof(WCHAR) 00s after the actual data, so you can cast it to LPCWSTR (assuming it's aligned)
static struct mem read(LPCWSTR filename); // provided by Flips core
struct mem read(); // provided by Flips core