1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #include "conf.h"
26 #include <stdlib.h>
27 #include <ctype.h>
28 #include "io.h"
29
30 struct _Conf
31 {
32 FILE* is;
33 unsigned int line;
34 char buf[1024];
35 char err[128];
36 };
37
38 Conf* Conf_Open(const char* path)
39 {
40 FILE* is;
41 Conf* self;
42
43 mike 1.1 /* Open file */
44 is = Fopen(path, "rb");
45 if (!is)
46 return NULL;
47
48 /* Allocate self object */
49 self = (Conf*)calloc(1, sizeof(Conf));
50 if (!self)
51 {
52 fclose(is);
53 return NULL;
54 }
55
56 /* initialize self */
57 self->is = is;
58
59 return self;
60 }
61
62 int Conf_Read(Conf* self, const char** key, const char** value)
63 {
64 mike 1.1 while (fgets(self->buf, sizeof(self->buf), self->is) != NULL)
65 {
66 char* p = self->buf;
67 char* keyEnd;
68
69 /* Increment line counter */
70 self->line++;
71
72 /* Skip comment lines */
73 if (self->buf[0] == '#')
74 continue;
75
76 /* Skip blank lines */
77 {
78 char* end = p + strlen(p);
79 while (end != p && isspace((unsigned char)end[-1]))
80 *--end = '\0';
81
82 if (p[0] == '\0')
83 continue;
84 }
85 mike 1.1
86 /* Skip leading whitespace */
87 while (*p && isspace((unsigned char)*p))
88 p++;
89
90 /* Expect key */
91 {
92 char* start = p;
93
94 if (!isalpha((unsigned char)*p) && *p != '_')
95 {
96 Snprintf(self->err, sizeof(self->err), "expected keyword");
97 return -1;
98 }
99
100 while (*p && (isalnum((unsigned char)*p) || *p == '_'))
101 p++;
102
103 keyEnd = p;
104
105 if (key)
106 mike 1.1 *key = start;
107 }
108
109 /* Skip whitespace */
110 while (*p && isspace((unsigned char)*p))
111 p++;
112
113 /* Expect '=' character */
114 if (*p != '=')
115 {
116 Snprintf(self->err, sizeof(self->err), "expected '='");
117 return -1;
118 }
119 p++;
120
121 /* Terminate key */
122 *keyEnd = '\0';
123
124 /* Skip whitespace */
125 while (*p && isspace((unsigned char)*p))
126 p++;
127 mike 1.1
128 /* Get value */
129 if (value)
130 *value = p;
131
132 /* return success */
133 return 0;
134 }
135
136 /* End of file */
137 return 1;
138 }
139
140 const char* Conf_Error(Conf* self)
141 {
142 return self->err;
143 }
144
145 unsigned int Conf_Line(Conf* self)
146 {
147 return self->line;
148 mike 1.1 }
149
150 void Conf_Close(Conf* self)
151 {
152 if (self && self->is)
153 {
154 fclose(self->is);
155 free(self);
156 }
157 }
|