2 libgliar - a library that can fake the OpenGL context info returned by
5 Copyright (C) 2013 Canonical Ltd
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 Author: Eleni Maria Stea <elene.mst@gmail.com>
29 static char *stripspace(char *s);
30 static void concat_values(struct cfgopt *opt);
32 /* linked list of valid value filters */
33 static struct cfgopt *valid_vals;
35 /* adds a new filter set of valid values for the key "key" */
36 void gliar_value_set(const char *key, char **valid, int vcount)
41 if(!(node = malloc(sizeof *node))) {
44 if(!(node->key = malloc(strlen(key) + 1))) {
48 strcpy(node->key, key);
50 if(!(node->str_val = malloc(vcount * sizeof *node->str_val))) {
55 for(i=0; i<vcount; i++) {
56 if(!(node->str_val[i] = malloc(strlen(valid[i]) + 1))) {
58 free(node->str_val[i]);
64 strcpy(node->str_val[i], valid[i]);
67 node->str_count = vcount;
69 node->next = valid_vals;
73 struct cfgopt *gliar_load_cfg(const char *fname)
77 struct cfgopt *optlist = 0;
78 struct cfgopt *opt = 0;
79 const struct cfgopt *filter;
81 if(!(fp = fopen(fname, "r"))) {
85 while(fgets(buf, sizeof buf, fp)) {
86 char *line = stripspace(buf);
88 if(!*line || *line == '#') {
94 char *end = strrchr(line, ']');
96 fprintf(stderr, "invalid config %s: %s\n", fname, line);
108 /* find the valid values for this particular key (if any) */
109 filter = gliar_find_opt(valid_vals, line);
111 if((opt = malloc(sizeof *opt))) {
112 if((opt->key = malloc(strlen(line) + 1))) {
113 strcpy(opt->key, line);
117 opt->type = GLIAR_STRING;
124 /* found a value for the current key (opt->key) */
125 int i, num, new_sz = opt->str_count + 1;
130 for(i=0; i<filter->str_count; i++) {
131 if(strcmp(line, filter->str_val[i]) == 0) {
136 if(i == filter->str_count) {
137 /* the string is not in the valid list, ignore it */
138 fprintf(stderr, "GLIAR: extension %s not supported, ignoring\n", line);
143 num = strtol(line, &end, 10);
146 opt->type = GLIAR_NUMBER;
149 if(opt && (tmp = realloc(opt->str_val, new_sz * sizeof(char*)))) {
151 if((opt->str_val[new_sz - 1] = malloc(strlen(line) + 1))) {
152 strcpy(opt->str_val[new_sz -1], line);
153 opt->str_count = new_sz;
158 opt->type = GLIAR_STRING;
173 const struct cfgopt *gliar_find_opt(struct cfgopt *list, const char *name)
180 if(strcmp(list->key, name) == 0) {
188 void gliar_print_opt(struct cfgopt *list)
192 if(list->type == GLIAR_NUMBER) {
193 printf("\"%s\" -> %d\n", list->key, list->num_val);
197 for(i=0; i<list->str_count; i++) {
198 printf("\"%s\" -> \"%s\"\n", list->key, list->str_val[i]);
205 static char *stripspace(char *s)
207 char *end = s + strlen(s) - 1;
209 while(isspace(*s)) s++;
211 while(isspace(*end)) {
217 static void concat_values(struct cfgopt *opt)
220 int sz = opt->str_count - 1;
222 if(!opt->str_count) {
227 for(i=0; i<opt->str_count; i++) {
228 sz += strlen(opt->str_val[i]);
231 if(!(opt->conc_vals = malloc(sz + 1))) {
236 for(i=0; i<opt->str_count - 1; i++) {
237 strcat(opt->conc_vals, opt->str_val[i]);
238 strcat(opt->conc_vals, " ");
240 strcat(opt->conc_vals, opt->str_val[i]);