X-Git-Url: http://git.mutantstargoat.com?a=blobdiff_plain;f=src%2Fcfg.c;h=c721ecba20208dfcbbdb0288273124fafc1048ea;hb=00bfdd4a8d29cac26588295e8d115cd1463b2a44;hp=4f317d2818531c7d42bc0338a66bcb67d5ab755b;hpb=b82d60137dc0b16ef451936fcc97fa8f25fe7b33;p=libgliar
diff --git a/src/cfg.c b/src/cfg.c
index 4f317d2..c721ecb 100644
--- a/src/cfg.c
+++ b/src/cfg.c
@@ -1,3 +1,25 @@
+/*
+libgliar - a library that can fake the OpenGL context info returned by
+the glGet OpenGL calls
+
+Copyright (C) 2013 Canonical Ltd
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+
+Author: Eleni Maria Stea
+*/
+
#include
#include
#include
@@ -5,7 +27,48 @@
#include "cfg.h"
static char *stripspace(char *s);
+static void concat_values(struct cfgopt *opt);
+
+/* linked list of valid value filters */
+static struct cfgopt *valid_vals;
+
+/* adds a new filter set of valid values for the key "key" */
+void gliar_value_set(const char *key, char **valid, int vcount)
+{
+ int i;
+ struct cfgopt *node;
+
+ if(!(node = malloc(sizeof *node))) {
+ return;
+ }
+ if(!(node->key = malloc(strlen(key) + 1))) {
+ free(node);
+ return;
+ }
+ strcpy(node->key, key);
+
+ if(!(node->str_val = malloc(vcount * sizeof *node->str_val))) {
+ free(node->key);
+ free(node);
+ return;
+ }
+ for(i=0; istr_val[i] = malloc(strlen(valid[i]) + 1))) {
+ for(; i>=0; i--) {
+ free(node->str_val[i]);
+ free(node->key);
+ free(node);
+ return;
+ }
+ }
+ strcpy(node->str_val[i], valid[i]);
+ }
+ node->str_count = vcount;
+
+ node->next = valid_vals;
+ valid_vals = node;
+}
struct cfgopt *gliar_load_cfg(const char *fname)
{
@@ -13,6 +76,7 @@ struct cfgopt *gliar_load_cfg(const char *fname)
char buf[512];
struct cfgopt *optlist = 0;
struct cfgopt *opt = 0;
+ const struct cfgopt *filter;
if(!(fp = fopen(fname, "r"))) {
return 0;
@@ -26,6 +90,7 @@ struct cfgopt *gliar_load_cfg(const char *fname)
}
if(*line == '[') {
+ /* found a new key */
char *end = strrchr(line, ']');
if(!end) {
fprintf(stderr, "invalid config %s: %s\n", fname, line);
@@ -37,43 +102,75 @@ struct cfgopt *gliar_load_cfg(const char *fname)
if(opt) {
opt->next = optlist;
optlist = opt;
+ concat_values(opt);
}
+ /* find the valid values for this particular key (if any) */
+ filter = gliar_find_opt(valid_vals, line);
+
if((opt = malloc(sizeof *opt))) {
if((opt->key = malloc(strlen(line) + 1))) {
strcpy(opt->key, line);
- opt->val = 0;
+ opt->str_val = 0;
+ opt->num_val = 0;
+ opt->str_count = 0;
+ opt->type = GLIAR_STRING;
} else {
free(opt);
opt = 0;
}
}
} else {
- char *tmp;
- int prev_len = opt->val ? strlen(opt->val) : 0;
-
- if(opt && (tmp = realloc(opt->val, prev_len + strlen(line) + 2))) {
- opt->val = tmp;
- if(prev_len) {
- strcat(opt->val, " ");
- strcat(opt->val, line);
- } else {
- strcpy(opt->val, line);
+ /* found a value for the current key (opt->key) */
+ int i, num, new_sz = opt->str_count + 1;
+ char **tmp;
+ char *end;
+
+ if(filter) {
+ for(i=0; istr_count; i++) {
+ if(strcmp(line, filter->str_val[i]) == 0) {
+ break;
+ }
+ }
+
+ if(i == filter->str_count) {
+ /* the string is not in the valid list, ignore it */
+ fprintf(stderr, "GLIAR: extension %s not supported, ignoring\n", line);
+ continue;
+ }
+ }
+
+ num = strtol(line, &end, 10);
+ if(!*end) {
+ opt->num_val = num;
+ opt->type = GLIAR_NUMBER;
+ }
+
+ if(opt && (tmp = realloc(opt->str_val, new_sz * sizeof(char*)))) {
+ opt->str_val = tmp;
+ if((opt->str_val[new_sz - 1] = malloc(strlen(line) + 1))) {
+ strcpy(opt->str_val[new_sz -1], line);
+ opt->str_count = new_sz;
}
}
+
+ if(new_sz > 1) {
+ opt->type = GLIAR_STRING;
+ }
}
}
if(opt) {
opt->next = optlist;
optlist = opt;
+ concat_values(opt);
}
fclose(fp);
return optlist;
}
-const char *gliar_find_opt(struct cfgopt *list, const char *name)
+const struct cfgopt *gliar_find_opt(struct cfgopt *list, const char *name)
{
if(!list || !name) {
return 0;
@@ -81,7 +178,7 @@ const char *gliar_find_opt(struct cfgopt *list, const char *name)
while(list) {
if(strcmp(list->key, name) == 0) {
- return list->val;
+ return list;
}
list = list->next;
}
@@ -92,7 +189,15 @@ void gliar_print_opt(struct cfgopt *list)
{
printf("OPTIONS\n");
while(list) {
- printf("\"%s\" -> \"%s\"\n", list->key, list->val);
+ if(list->type == GLIAR_NUMBER) {
+ printf("\"%s\" -> %d\n", list->key, list->num_val);
+ }
+ else {
+ int i;
+ for(i=0; istr_count; i++) {
+ printf("\"%s\" -> \"%s\"\n", list->key, list->str_val[i]);
+ }
+ }
list = list->next;
}
}
@@ -108,3 +213,29 @@ static char *stripspace(char *s)
}
return s;
}
+
+static void concat_values(struct cfgopt *opt)
+{
+ int i;
+ int sz = opt->str_count - 1;
+
+ if(!opt->str_count) {
+ opt->conc_vals = 0;
+ return;
+ }
+
+ for(i=0; istr_count; i++) {
+ sz += strlen(opt->str_val[i]);
+ }
+
+ if(!(opt->conc_vals = malloc(sz + 1))) {
+ return;
+ }
+
+ *opt->conc_vals = 0;
+ for(i=0; istr_count - 1; i++) {
+ strcat(opt->conc_vals, opt->str_val[i]);
+ strcat(opt->conc_vals, " ");
+ }
+ strcat(opt->conc_vals, opt->str_val[i]);
+}