Add confreader library
This commit is contained in:
parent
b3c353e389
commit
da909e4f79
18
apps/test-conf.c
Normal file
18
apps/test-conf.c
Normal file
@ -0,0 +1,18 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <toaru/confreader.h>
|
||||
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
confreader_t * conf = confreader_load("/etc/demo.conf");
|
||||
|
||||
fprintf(stderr, "test 1\n");
|
||||
assert(confreader_get(conf, "", "test") != NULL);
|
||||
assert(!strcmp(confreader_get(conf, "", "test"),"hello"));
|
||||
|
||||
fprintf(stderr, "test 2\n");
|
||||
assert(!strcmp(confreader_get(conf,"sec","tion"),"test"));
|
||||
|
||||
return 0;
|
||||
}
|
7
base/etc/demo.conf
Normal file
7
base/etc/demo.conf
Normal file
@ -0,0 +1,7 @@
|
||||
; this is a comment
|
||||
test=hello
|
||||
|
||||
[sec]
|
||||
tion=test
|
||||
|
||||
; this is also a comment
|
18
base/usr/include/toaru/confreader.h
Normal file
18
base/usr/include/toaru/confreader.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <toaru/hashmap.h>
|
||||
|
||||
typedef struct {
|
||||
hashmap_t * sections;
|
||||
} confreader_t;
|
||||
|
||||
confreader_t * confreader_load(const char * file);
|
||||
char * confreader_get(confreader_t * ctx, char * section, char * value);
|
||||
char * confreader_getd(confreader_t * ctx, char * section, char * value, char * def);
|
||||
int confreader_int(confreader_t * ctx, char * section, char * value);
|
||||
int confreader_intd(confreader_t * ctx, char * section, char * value, int def);
|
||||
void confreader_free(confreader_t * conf);
|
||||
|
147
lib/confreader.c
Normal file
147
lib/confreader.c
Normal file
@ -0,0 +1,147 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2018 K. Lange
|
||||
*
|
||||
* Configuration File Reader
|
||||
*
|
||||
* Reads an implementation of the INI "standard". Note that INI
|
||||
* isn't actually a standard. We support the following:
|
||||
* - ; comments
|
||||
* - foo=bar keyword assignment
|
||||
* - [sections]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <toaru/hashmap.h>
|
||||
#include <toaru/confreader.h>
|
||||
|
||||
#define TRACE_APP_NAME "confreader"
|
||||
#define TRACE(...)
|
||||
//#include <toaru/trace.h>
|
||||
|
||||
static void free_hashmap(void * h) {
|
||||
hashmap_free(h);
|
||||
free(h);
|
||||
}
|
||||
|
||||
confreader_t * confreader_load(const char * file) {
|
||||
|
||||
confreader_t * out = malloc(sizeof(confreader_t));
|
||||
|
||||
out->sections = hashmap_create(10);
|
||||
|
||||
FILE * f = fopen(file, "r");
|
||||
|
||||
hashmap_t * current_section = hashmap_create(10);
|
||||
current_section->hash_val_free = free_hashmap;
|
||||
|
||||
hashmap_set(out->sections, "", current_section);
|
||||
|
||||
if (!f) {
|
||||
/* File does not exist, no configuration values, but continue normally. */
|
||||
return out;
|
||||
}
|
||||
|
||||
char tmp[1024];
|
||||
char tmp2[1024];
|
||||
|
||||
while (!feof(f)) {
|
||||
char c = fgetc(f);
|
||||
tmp[0] = '\0';
|
||||
tmp2[0] = '\0';
|
||||
if (c == ';') {
|
||||
TRACE("Comment");
|
||||
while (!feof(f) && fgetc(f) != '\n');
|
||||
TRACE("Done");
|
||||
} else if (c == '\n' || c == EOF) {
|
||||
TRACE("blank line or EOF: %d", c);
|
||||
continue;
|
||||
} else if (c == '[') {
|
||||
TRACE("section");
|
||||
char * foo = tmp;
|
||||
int i;
|
||||
while ((i = fgetc(f)) >= 0) {
|
||||
if (i == ']') break;
|
||||
*foo = i;
|
||||
foo++;
|
||||
*foo = '\0';
|
||||
}
|
||||
while (!feof(f) && fgetc(f) != '\n');
|
||||
current_section = hashmap_create(10);
|
||||
TRACE("adding section %s", tmp);
|
||||
hashmap_set(out->sections, tmp, current_section);
|
||||
TRACE("section is over");
|
||||
} else {
|
||||
TRACE("value");
|
||||
char * foo = tmp;
|
||||
*foo = c;
|
||||
foo++;
|
||||
int i;
|
||||
while ((i = fgetc(f)) >= 0) {
|
||||
if (i == '=') break;
|
||||
*foo = i;
|
||||
foo++;
|
||||
*foo = '\0';
|
||||
}
|
||||
if (i != '=') {
|
||||
TRACE("no equals sign");
|
||||
while (!feof(f) && fgetc(f) != '\n');
|
||||
continue;
|
||||
}
|
||||
TRACE("=");
|
||||
foo = tmp2;
|
||||
while ((i = fgetc(f)) >= 0) {
|
||||
if (i == '\n') break;
|
||||
*foo = i;
|
||||
foo++;
|
||||
*foo = '\0';
|
||||
}
|
||||
TRACE("setting value %s to %s", tmp, tmp2);
|
||||
hashmap_set(current_section, tmp, strdup(tmp2));
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
TRACE("done reading");
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void confreader_free(confreader_t * conf) {
|
||||
free_hashmap(conf->sections);
|
||||
free(conf);
|
||||
}
|
||||
|
||||
char * confreader_get(confreader_t * ctx, char * section, char * value) {
|
||||
if (!ctx) return NULL;
|
||||
|
||||
hashmap_t * s = hashmap_get(ctx->sections, section);
|
||||
|
||||
if (!s) {
|
||||
TRACE("section doesn't exist: %s", section);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hashmap_get(s, value);
|
||||
}
|
||||
|
||||
char * confreader_getd(confreader_t * ctx, char * section, char * value, char * def) {
|
||||
char * result = confreader_get(ctx, section, value);
|
||||
return result ? result : def;
|
||||
}
|
||||
|
||||
int confreader_int(confreader_t * ctx, char * section, char * value) {
|
||||
char * result = confreader_get(ctx, section, value);
|
||||
if (!result) return 0;
|
||||
return atoi(result);
|
||||
}
|
||||
|
||||
int confreader_intd(confreader_t * ctx, char * section, char * value, int def) {
|
||||
char * result = confreader_get(ctx, section, value);
|
||||
if (!result) return def;
|
||||
return atoi(result);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user