tizen 2.3.1 release
[kernel/api/system-resource.git] / src / common / config-parser.c
1 /*
2  * resourced
3  *
4  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdio.h>
20 #include <string.h>
21 #include <errno.h>
22 #include "trace.h"
23 #include "config-parser.h"
24
25 #define MAX_LINE        128
26 #define MAX_SECTION     64
27 #define WHITESPACE      " \t"
28 #define NEWLINE         "\n\r"
29 #define COMMENT         '#'
30
31 static inline char *trim_str(char *s)
32 {
33         char *t;
34         /* left trim */
35         s += strspn(s, WHITESPACE);
36
37         /* right trim */
38         for (t = strchr(s, 0); t > s; t--)
39                 if (!strchr(WHITESPACE, t[-1]))
40                         break;
41         *t = 0;
42         return s;
43 }
44
45 int config_parse(const char *file_name, int cb(struct parse_result *result,
46     void *user_data), void *user_data)
47 {
48         FILE *f = NULL;
49         struct parse_result result;
50         /* use stack for parsing */
51         char line[MAX_LINE];
52         char section[MAX_SECTION];
53         char *start, *end, *name, *value;
54         int lineno = 0, ret = 0;
55
56         if (!file_name || !cb) {
57                 ret = -EINVAL;
58                 goto error;
59         }
60
61         /* open conf file */
62         f = fopen(file_name, "r");
63         if (!f) {
64                 _E("Failed to open file %s", file_name);
65                 ret = -EIO;
66                 goto error;
67         }
68
69         /* parsing line by line */
70         while (fgets(line, MAX_LINE, f) != NULL) {
71                 lineno++;
72
73                 start = line;
74                 start[strcspn(start, NEWLINE)] = '\0';
75                 start = trim_str(start);
76
77                 if (*start == COMMENT) {
78                         continue;
79                 } else if (*start == '[') {
80                         /* parse section */
81                         end = strchr(start, ']');
82                         if (!end || *end != ']') {
83                                 ret = -EBADMSG;
84                                 goto error;
85                         }
86
87                         *end = '\0';
88                         strncpy(section, start + 1, sizeof(section));
89                         section[MAX_SECTION-1] = '\0';
90                 } else if (*start) {
91                         /* parse name & value */
92                         end = strchr(start, '=');
93                         if (!end || *end != '=') {
94                                 ret = -EBADMSG;
95                                 goto error;
96                         }
97                         *end = '\0';
98                         name = trim_str(start);
99                         value = trim_str(end + 1);
100                         end = strchr(value, COMMENT);
101                         if (end && *end == COMMENT) {
102                                 *end = '\0';
103                                 value = trim_str(value);
104                         }
105
106                         result.section = section;
107                         result.name = name;
108                         result.value = value;
109                         /* callback with parse result */
110                         ret = cb(&result, user_data);
111                         if (ret < 0) {
112                                 ret = -EBADMSG;
113                                 goto error;
114                         }
115                 }
116         }
117         _D("Success to load %s", file_name);
118         fclose(f);
119         return 0;
120
121 error:
122         if (f)
123                 fclose(f);
124         _E("Failed to read %s:%d!", file_name, lineno);
125         return ret;
126 }
127