essence-os/shared/ini.h

66 lines
1.8 KiB
C

bool EsINIParse(EsINIState *s) {
#define INI_READ(destination, counter, c1, c2) \
s->destination = s->buffer, s->counter = 0; \
while (s->bytes && *s->buffer != c1 && *s->buffer != c2) s->counter++, s->buffer++, s->bytes--; \
if (s->bytes && *s->buffer == c1) s->buffer++, s->bytes--;
while (s->bytes) {
char c = *s->buffer;
if (c == ' ' || c == '\n' || c == '\r') {
s->buffer++, s->bytes--;
continue;
} else if (c == ';') {
s->valueBytes = 0;
INI_READ(key, keyBytes, '\n', 0);
} else if (c == '[') {
s->keyBytes = s->valueBytes = 0;
s->buffer++, s->bytes--;
INI_READ(section, sectionBytes, ']', 0);
} else {
INI_READ(key, keyBytes, '=', '\n');
INI_READ(value, valueBytes, '\n', 0);
}
return true;
}
return false;
}
bool EsINIPeek(EsINIState *s) {
char *oldBuffer = s->buffer;
size_t oldBytes = s->bytes;
bool result = EsINIParse(s);
s->buffer = oldBuffer;
s->bytes = oldBytes;
return result;
}
size_t EsINIFormat(EsINIState *s, char *buffer, size_t bytes) {
#define INI_WRITE(x, b) for (uintptr_t i = 0; i < b; i++) if (bytes) *buffer = x[i], buffer++, bytes--
char *start = buffer;
if (s->keyBytes || s->valueBytes) {
if (s->key[0] == '[') return 0;
INI_WRITE(s->key, s->keyBytes);
if (s->key[0] != ';') INI_WRITE("=", 1);
INI_WRITE(s->value, s->valueBytes);
INI_WRITE("\n", 1);
} else {
INI_WRITE("\n[", 2);
INI_WRITE(s->section, s->sectionBytes);
INI_WRITE("]\n", 2);
}
return buffer - start;
}
void EsINIZeroTerminate(EsINIState *s) {
static char emptyString = 0;
if (s->sectionBytes) s->section[s->sectionBytes] = 0; else s->section = &emptyString;
if (s->keyBytes) s->key[s->keyBytes] = 0; else s->key = &emptyString;
if (s->valueBytes) s->value[s->valueBytes] = 0; else s->value = &emptyString;
}