Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * config file parser
  3  *
  4  */
  5 
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <string.h>
  9 #include "parseconfig.h"
 10 
 11 struct CFG_ENTRIES {
 12     int  ent_count;
 13     char **ent_names;
 14     char **ent_values;
 15     int  **ent_seen;
 16 };
 17 
 18 struct CFG_SECTIONS {
 19     int                 sec_count;
 20     char                **sec_names;
 21     struct CFG_ENTRIES  **sec_entries;
 22 };
 23 
 24 /* ------------------------------------------------------------------------ */
 25 
 26 static struct CFG_SECTIONS *c;
 27 
 28 /* ------------------------------------------------------------------------ */
 29 
 30 #define ALLOC_SIZE 16
 31 
 32 static struct CFG_SECTIONS*
 33 cfg_init_sections(void)
 34 {
 35     struct CFG_SECTIONS *c;
 36     c = malloc(sizeof(struct CFG_SECTIONS));
 37     memset(c,0,sizeof(struct CFG_SECTIONS));
 38     c->sec_names      = malloc(ALLOC_SIZE*sizeof(char*));
 39     c->sec_names[0]   = NULL;
 40     c->sec_entries    = malloc(ALLOC_SIZE*sizeof(struct CFG_ENTRIES*));
 41     c->sec_entries[0] = NULL;
 42     return c;
 43 }
 44 
 45 static struct CFG_ENTRIES*
 46 cfg_init_entries(void)
 47 {
 48     struct CFG_ENTRIES *e;
 49     e = malloc(sizeof(struct CFG_ENTRIES));
 50     memset(e,0,sizeof(struct CFG_ENTRIES));
 51     e->ent_names     = malloc(ALLOC_SIZE*sizeof(char*));
 52     e->ent_names[0]  = NULL;
 53     e->ent_values    = malloc(ALLOC_SIZE*sizeof(char*));
 54     e->ent_values[0] = NULL;
 55     e->ent_seen      = malloc(ALLOC_SIZE*sizeof(int*));
 56     e->ent_seen[0]   = 0;
 57     return e;
 58 }
 59 
 60 static struct CFG_ENTRIES*
 61 cfg_find_section(struct CFG_SECTIONS *c, char *name)
 62 {
 63     struct CFG_ENTRIES* e;
 64     int i;
 65 
 66     for (i = 0; i < c->sec_count; i++)
 67         if (0 == strcasecmp(c->sec_names[i],name))
 68             return c->sec_entries[i];
 69 
 70     /* 404 not found => create a new one */
 71     if ((c->sec_count % ALLOC_SIZE) == (ALLOC_SIZE-2)) {
 72         c->sec_names   = realloc(c->sec_names,(c->sec_count+2+ALLOC_SIZE)*sizeof(char*));
 73         c->sec_entries = realloc(c->sec_entries,(c->sec_count+2+ALLOC_SIZE)*sizeof(struct CFG_ENTRIES*));
 74     }
 75     e = cfg_init_entries();
 76     c->sec_names[c->sec_count]   = strdup(name);
 77     c->sec_entries[c->sec_count] = e;
 78     c->sec_count++;    
 79     c->sec_names[c->sec_count]   = NULL;
 80     c->sec_entries[c->sec_count] = NULL;
 81     return e;
 82 }
 83 
 84 static void
 85 cfg_set_entry(struct CFG_ENTRIES *e, char *name, char *value)
 86 {
 87     int i;
 88 
 89     for (i = 0; i < e->ent_count; i++)
 90         if (0 == strcasecmp(e->ent_names[i],name))
 91             break;
 92     if (i == e->ent_count) {
 93         /* 404 not found => create a new one */
 94         if ((e->ent_count % ALLOC_SIZE) == (ALLOC_SIZE-2)) {
 95             e->ent_names  = realloc(e->ent_names,(e->ent_count+2+ALLOC_SIZE)*sizeof(char*));
 96             e->ent_values = realloc(e->ent_values,(e->ent_count+2+ALLOC_SIZE)*sizeof(char*));
 97             e->ent_seen   = realloc(e->ent_seen,(e->ent_count+2+ALLOC_SIZE)*sizeof(int*));
 98         }
 99         e->ent_count++;    
100         e->ent_names[e->ent_count]  = NULL;
101         e->ent_values[e->ent_count] = NULL;
102         e->ent_seen[e->ent_count]   = 0;
103     }
104     e->ent_names[i]  = strdup(name);
105     e->ent_values[i] = strdup(value);
106 }
107 
108 /* ------------------------------------------------------------------------ */
109 
110 int
111 cfg_parse_file(char *filename)
112 {
113     struct CFG_ENTRIES *e = NULL;
114     char line[256],tag[64],value[192];
115     FILE *fp;
116     int nr;
117     
118     if (NULL == c)
119         c = cfg_init_sections();
120     if (NULL == (fp = fopen(filename,"r")))
121         return -1;
122 
123     nr = 0;
124     while (NULL != fgets(line,255,fp)) {
125         nr++;
126         if (line[0] == '\n' || line[0] == '#' || line[0] == '%')
127             continue;
128         if (1 == sscanf(line,"[%99[^]]]",value)) {
129             /* [section] */
130             e = cfg_find_section(c,value);
131         } else if (2 == sscanf(line," %63[^= ] = %191[^\n]",tag,value)) {
132             /* foo = bar */
133             if (NULL == e) {
134                 fprintf(stderr,"%s:%d: error: no section\n",filename,nr);
135             } else {
136                 char *c = value + strlen(value)-1;
137                 while (c > value  &&  (*c == ' ' || *c == '\t'))
138                     *(c--) = 0;
139                 cfg_set_entry(e,tag,value);
140             }
141         } else {
142             /* Huh ? */
143             fprintf(stderr,"%s:%d: syntax error\n",filename,nr);
144         }
145     }
146     fclose(fp);
147     return 0;
148 }
149 
150 /* ------------------------------------------------------------------------ */
151 
152 void
153 cfg_parse_option(char *section, char *tag, char *value)
154 {
155     struct CFG_ENTRIES *e = NULL;
156     
157     if (NULL == c)
158         c = cfg_init_sections();
159     e = cfg_find_section(c,section);
160     cfg_set_entry(e,tag,value);
161 }
162 
163 void
164 cfg_parse_options(int *argc, char **argv)
165 {
166     char section[64], tag[64];
167     int i,j;
168 
169     for (i = 1; i+1 < *argc;) {
170         if (2 == sscanf(argv[i],"-%63[^:]:%63s",section,tag)) {
171             cfg_parse_option(section,tag,argv[i+1]);
172             for (j = i; j < *argc-1; j++)
173                 argv[j] = argv[j+2];
174             (*argc) -= 2;
175         } else {
176             i++;
177         }
178     }
179 }
180 
181 /* ------------------------------------------------------------------------ */
182 
183 char**
184 cfg_list_sections()
185 {
186     return c->sec_names;
187 }
188 
189 char**
190 cfg_list_entries(char *name)
191 {
192     int i;
193 
194     if (NULL == c)
195         return NULL;
196     for (i = 0; i < c->sec_count; i++)
197         if (0 == strcasecmp(c->sec_names[i],name))
198             return c->sec_entries[i]->ent_names;
199     return NULL;
200 }
201 
202 char*
203 cfg_get_str(char *sec, char *ent)
204 {
205     struct CFG_ENTRIES* e = NULL;
206     char *v = NULL;
207     int i;
208     
209     for (i = 0; i < c->sec_count; i++)
210         if (0 == strcasecmp(c->sec_names[i],sec))
211             e = c->sec_entries[i];
212     if (NULL == e)
213         return NULL;
214     for (i = 0; i < e->ent_count; i++)
215         if (0 == strcasecmp(e->ent_names[i],ent)) {
216             v = e->ent_values[i];
217             e->ent_seen[i]++;
218         }
219     return v;
220 }
221 
222 int
223 cfg_get_int(char *sec, char *ent)
224 {
225     char *val;
226 
227     val = cfg_get_str(sec,ent);
228     if (NULL == val)
229         return -1;
230     return atoi(val);
231 }
232 
233 int
234 cfg_get_signed_int(char *sec, char *ent)
235 {
236     char *val;
237 
238     val = cfg_get_str(sec,ent);
239     if (NULL == val)
240         return 0;
241     return atoi(val);
242 }
243 
244 float
245 cfg_get_float(char *sec, char *ent)
246 {
247     char *val;
248 
249     val = cfg_get_str(sec,ent);
250     if (NULL == val)
251         return -1;
252     return atof(val);
253 }
254 
  This page was automatically generated by the LXR engine.