Remove stale comment
[platform/upstream/weston.git] / shared / configparser.c
1 /*
2  * Copyright © 2011 Intel Corporation
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 #include <string.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <assert.h>
27
28 #include "configparser.h"
29
30 static int
31 handle_key(const struct config_key *key, const char *value)
32 {
33         char *end, *s;
34         int i, len;
35         
36         switch (key->type) {
37         case CONFIG_KEY_INTEGER:
38                 i = strtol(value, &end, 0);
39                 if (*end != '\n') {
40                         fprintf(stderr, "invalid integer: %s\n", value);
41                         return -1;
42                 }
43                 *(int *)key->data = i;
44                 return 0;
45
46         case CONFIG_KEY_STRING:
47                 len = strlen(value);
48                 s = malloc(len);
49                 if (s == NULL)
50                         return -1;
51                 memcpy(s, value, len - 1);
52                 s[len - 1] = '\0';
53                 *(char **)key->data = s;
54                 return 0;
55
56         case CONFIG_KEY_BOOLEAN:
57                 if (strcmp(value, "false\n") == 0)
58                         *(int *)key->data = 0;
59                 else if (strcmp(value, "true\n") == 0)
60                         *(int *)key->data = 1;
61                 else {
62                         fprintf(stderr, "invalid bool: %s\n", value);
63                         return -1;
64                 }
65                 return 0;
66
67         default:
68                 assert(0);
69                 break;
70         }
71 }
72
73 int
74 parse_config_file(const char *path,
75                   const struct config_section *sections, int num_sections,
76                   void *data)
77 {
78         FILE *fp;
79         char line[512], *p;
80         const struct config_section *current = NULL;
81         int i;
82
83         fp = fopen(path, "r");
84         if (fp == NULL) {
85                 fprintf(stderr, "couldn't open %s\n", path);
86                 return -1;
87         }
88
89         while (fgets(line, sizeof line, fp)) {
90                 if (line[0] == '#' || line[0] == '\n') {
91                         continue;
92                 } if (line[0] == '[') {
93                         p = strchr(&line[1], ']');
94                         if (!p || p[1] != '\n') {
95                                 fprintf(stderr, "malformed "
96                                         "section header: %s\n", line);
97                                 fclose(fp);
98                                 return -1;
99                         }
100                         if (current && current->done)
101                                 current->done(data);
102                         p[0] = '\0';
103                         for (i = 0; i < num_sections; i++) {
104                                 if (strcmp(sections[i].name, &line[1]) == 0) {
105                                         current = &sections[i];
106                                         break;
107                                 }
108                         }
109                         if (i == num_sections)
110                                 current = NULL;
111                 } else if (p = strchr(line, '='), p != NULL) {
112                         if (current == NULL)
113                                 continue;
114                         p[0] = '\0';
115                         for (i = 0; i < current->num_keys; i++) {
116                                 if (strcmp(current->keys[i].name, line) == 0) {
117                                         if (handle_key(&current->keys[i], &p[1]) < 0) {
118                                                 fclose(fp);
119                                                 return -1;
120                                         }
121                                         break;
122                                 }
123                         }
124                 } else {
125                         fprintf(stderr, "malformed config line: %s\n", line);
126                         fclose(fp);
127                         return -1;
128                 }
129         }
130
131         if (current && current->done)
132                 current->done(data);
133
134         fclose(fp);
135
136         return 0;
137 }
138
139 char *
140 config_file_path(const char *name)
141 {
142         const char dotconf[] = "/.config/";
143         const char *config_dir;
144         const char *home_dir;
145         char *path;
146         size_t size;
147
148         config_dir = getenv("XDG_CONFIG_HOME");
149         if (!config_dir) {
150                 home_dir = getenv("HOME");
151                 if (!home_dir) {
152                         fprintf(stderr, "HOME is not set, using cwd.\n");
153                         return strdup(name);
154                 }
155
156                 size = strlen(home_dir) + sizeof dotconf + strlen(name);
157                 path = malloc(size);
158                 if (!path)
159                         return NULL;
160
161                 snprintf(path, size, "%s%s%s", home_dir, dotconf, name);
162                 return path;
163         }
164
165         size = strlen(config_dir) + 1 + strlen(name) + 1;
166         path = malloc(size);
167         if (!path)
168                 return NULL;
169
170         snprintf(path, size, "%s/%s", config_dir, name);
171         return path;
172 }