summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2023-06-17 18:54:44 +0200
committercbdev <cb@cbcdn.com>2023-06-17 18:54:44 +0200
commit336a336e45c90851dcc8430f7f8eeabc9f3399e1 (patch)
tree325f98644648548cb463922f1307705349c023b0
parent9fbad1544764c515cb1f22bc552f33bb41206e92 (diff)
downloadnfcommander-336a336e45c90851dcc8430f7f8eeabc9f3399e1.tar.gz
nfcommander-336a336e45c90851dcc8430f7f8eeabc9f3399e1.tar.bz2
nfcommander-336a336e45c90851dcc8430f7f8eeabc9f3399e1.zip
Implement configuration parser
-rw-r--r--Makefile1
-rw-r--r--config.c193
2 files changed, 186 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index 9cb714b..b5a9e02 100644
--- a/Makefile
+++ b/Makefile
@@ -18,3 +18,4 @@ nfcommander: nfcommander.c nfcommander.h $(CORE_OBJS)
clean:
$(RM) nfcommander
$(RM) $(CORE_OBJS)
+ $(RM) $(PLUGINS)
diff --git a/config.c b/config.c
index f11bbb6..306e578 100644
--- a/config.c
+++ b/config.c
@@ -1,29 +1,206 @@
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include "nfcommander.h"
#include "config.h"
+typedef struct /*_config_section*/ {
+ char* name;
+ size_t entries;
+ char** keys;
+ char** values;
+} config_section_t;
+
+size_t nsections = 0, current_section = 0;
+config_section_t* sections = NULL;
+
+static int config_section(char* section){
+ size_t n = 0;
+
+ //check if section already exists
+ for(n = 0; n < nsections; n++){
+ if(!strcmp(sections[n].name, section)){
+ current_section = n;
+ return 0;
+ }
+ }
+
+ //create new section
+ sections = realloc(sections, (nsections + 1) * sizeof(config_section_t));
+ if(!sections){
+ nsections = 0;
+ printf("Failed to allocate memory\n");
+ return -1;
+ }
+
+ memset(sections + nsections, 0, sizeof(config_section_t));
+ sections[nsections].name = strdup(section);
+ if(!sections[nsections].name){
+ printf("Failed to allocate memory\n");
+ return -1;
+ }
+
+ current_section = nsections;
+ nsections++;
+ return 0;
+}
+
+static int config_set(char* key, char* value){
+ size_t n = 0;
+ if(!sections || !nsections){
+ printf("Assignment outside of section\n");
+ return 1;
+ }
+
+ //check if property already present
+ for(n = 0; n < sections[current_section].entries; n++){
+ if(!strcmp(sections[current_section].keys[n], key)){
+ printf("Overriding previous value of %s.%s with %s\n",
+ sections[current_section].name,
+ key, value);
+ free(sections[current_section].values[n]);
+ sections[current_section].values[n] = strdup(value);
+ return 0;
+ }
+ }
+
+ //add property
+ sections[current_section].keys = realloc(sections[current_section].keys, (sections[current_section].entries + 1) * sizeof(char*));
+ sections[current_section].values = realloc(sections[current_section].values, (sections[current_section].entries + 1) * sizeof(char*));
+
+ if(!sections[current_section].keys || !sections[current_section].values){
+ printf("Filed to allocate memory\n");
+ sections[current_section].entries = 0;
+ return 1;
+ }
+
+ sections[current_section].keys[sections[current_section].entries] = strdup(key);
+ sections[current_section].values[sections[current_section].entries] = strdup(value);
+ sections[current_section].entries++;
+ return 0;
+}
+
+static int config_handle_line(char* line){
+ char* next_token = NULL;
+ size_t len = 0;
+
+ //ignore comments
+ if(line[0] == ';'){
+ return 0;
+ }
+
+ //select or create section
+ if(line[0] == '['){
+ next_token = strchr(line, ']');
+ if(!next_token){
+ printf("Unterminated start of section\n");
+ return 1;
+ }
+
+ *next_token = 0;
+ return config_section(line + 1);
+ }
+
+ next_token = strchr(line, '=');
+ if(!next_token){
+ printf("Not an assignment: %s\n", line);
+ return 1;
+ }
+
+ *next_token = 0;
+ next_token++;
+
+ //rtrim line
+ len = strlen(line);
+ for(; len && !isgraph(line[len]); len--){
+ line[len] = 0;
+ }
+
+ //ltrim value
+ for(; *next_token && !isgraph(*next_token); next_token++){
+ }
+
+ if(len && strlen(next_token)){
+ return config_set(line, next_token);
+ }
+ printf("Invalid assignment\n");
+ return 1;
+}
+
int config_read(char* path){
- //TODO
+ ssize_t line_len = 0;
+ size_t line_alloc = 0, line_number = 1;
+ char* line = NULL;
+ FILE* input = fopen(path, "r");
+ if(!input){
+ printf("Failed to open %s as configuration file\n", path);
+ return 1;
+ }
+
printf("Reading config file %s\n", path);
+ for(line_len = getline(&line, &line_alloc, input); line_len >= 0; line_len = getline(&line, &line_alloc, input)){
+ //right-trim
+ for(; line_len && !isgraph(line[line_len]); line_len--){
+ line[line_len] = 0;
+ }
+
+ if(!line_len){
+ continue;
+ }
+ if(config_handle_line(line)){
+ printf("Failed parsing %s at line %lu\n", path, line_number);
+ return 1;
+ }
+ line_number++;
+ }
+
+ free(line);
+ fclose(input);
return 0;
}
char* config_get(char* section, char* property){
- //TODO
- printf("Querying for config property %s->%s\n", section, property);
+ size_t n = 0, p = 0;
+
+ //find section
+ for(n = 0; n < nsections; n++){
+ if(!strcmp(section, sections[n].name)){
+ break;
+ }
+ }
+
+ if(n == nsections){
+ printf("Requested config section %s not found\n", section);
+ return NULL;
+ }
- //TEMP
- if(!strcmp(property, "reader")){
- return "yhy";
+ //find key
+ for(p = 0; p < sections[n].entries; p++){
+ if(!strcmp(sections[n].keys[p], property)){
+ return sections[n].values[p];
+ }
}
+ printf("Requested property %s.%s not configured\n", section, property);
return NULL;
}
void config_free(){
- //TODO
- printf("Cleaning up config data\n");
+ size_t n = 0, p = 0;
+
+ for(n = 0; n < nsections; n++){
+ free(sections[n].name);
+ for(p = 0; p < sections[n].entries; p++){
+ free(sections[n].keys[p]);
+ free(sections[n].values[p]);
+ }
+ free(sections[n].keys);
+ free(sections[n].values);
+ }
+
+ free(sections);
+ sections = NULL;
+ nsections = 0;
}