added support for OpenGL extensions, vendor, version
[libgliar] / src / cfg.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include "cfg.h"
6
7 static char *stripspace(char *s);
8
9
10 struct cfgopt *gliar_load_cfg(const char *fname)
11 {
12         FILE *fp;
13         char buf[512];
14         struct cfgopt *optlist = 0;
15         struct cfgopt *opt = 0;
16
17         if(!(fp = fopen(fname, "r"))) {
18                 return 0;
19         }
20
21         while(fgets(buf, sizeof buf, fp)) {
22                 char *line = stripspace(buf);
23
24                 if(!*line || *line == '#') {
25                         continue;
26                 }
27
28                 if(*line == '[') {
29                         char *end = strrchr(line, ']');
30                         if(!end) {
31                                 fprintf(stderr, "invalid config %s: %s\n", fname, line);
32                                 continue;
33                         }
34                         line++;
35                         *end = 0;
36
37                         if(opt) {
38                                 opt->next = optlist;
39                                 optlist = opt;
40                         }
41
42                         if((opt = malloc(sizeof *opt))) {
43                                 if((opt->key = malloc(strlen(line) + 1))) {
44                                         strcpy(opt->key, line);
45                                         opt->val = 0;
46                                 } else {
47                                         free(opt);
48                                         opt = 0;
49                                 }
50                         }
51                 } else {
52                         char *tmp;
53                         int prev_len = opt->val ? strlen(opt->val) : 0;
54
55                         if(opt && (tmp = realloc(opt->val, prev_len + strlen(line) + 2))) {
56                                 opt->val = tmp;
57                                 if(prev_len) {
58                                         strcat(opt->val, " ");
59                                         strcat(opt->val, line);
60                                 } else {
61                                         strcpy(opt->val, line);
62                                 }
63                         }
64                 }
65         }
66
67         if(opt) {
68                 opt->next = optlist;
69                 optlist = opt;
70         }
71
72         fclose(fp);
73         return optlist;
74 }
75
76 const char *gliar_find_opt(struct cfgopt *list, const char *name)
77 {
78         if(!list || !name) {
79                 return 0;
80         }
81
82         while(list) {
83                 if(strcmp(list->key, name) == 0) {
84                         return list->val;
85                 }
86                 list = list->next;
87         }
88         return 0;
89 }
90
91 void gliar_print_opt(struct cfgopt *list)
92 {
93         printf("OPTIONS\n");
94         while(list) {
95                 printf("\"%s\" -> \"%s\"\n", list->key, list->val);
96                 list = list->next;
97         }
98 }
99
100 static char *stripspace(char *s)
101 {
102         char *end = s + strlen(s) - 1;
103
104         while(isspace(*s)) s++;
105
106         while(isspace(*end)) {
107                 *end-- = 0;
108         }
109         return s;
110 }