debuggers.hg

view tools/libxl/libxlu_cfg.c @ 21067:b4a1832a916f

Update Xen version to 4.0.0-rc6
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 09 18:18:05 2010 +0000 (2010-03-09)
parents 71af69a9d393
children 3ffdb094c2c0
line source
2 #include "libxlu_internal.h"
3 #include "libxlu_cfg_y.h"
4 #include "libxlu_cfg_l.h"
5 #include "libxlu_cfg_i.h"
7 XLU_Config *xlu_cfg_init(FILE *report, const char *report_filename) {
8 XLU_Config *cfg;
10 cfg= malloc(sizeof(*cfg));
11 if (!cfg) return 0;
13 cfg->report= report;
14 cfg->filename= strdup(report_filename);
15 if (!cfg->filename) { free(cfg); return 0; }
17 cfg->settings= 0;
18 return cfg;
19 }
21 int xlu_cfg_readfile(XLU_Config *cfg, const char *real_filename) {
22 CfgParseContext ctx;
23 FILE *f;
24 int e, r;
26 ctx.cfg= cfg;
27 ctx.err= 0;
28 ctx.lexerrlineno= -1;
30 f= fopen(real_filename, "r");
31 if (!f) {
32 e= errno;
33 fprintf(cfg->report,"%s: unable to open configuration file: %s\n",
34 real_filename, strerror(e));
35 return e;
36 }
38 e= xlu__cfg_yylex_init_extra(&ctx, &ctx.scanner);
39 if (e) {
40 fprintf(cfg->report,"%s: unable to create scanner: %s\n",
41 cfg->filename, strerror(e));
42 return e;
43 }
45 xlu__cfg_yyrestart(f, ctx.scanner);
47 r= xlu__cfg_yyparse(&ctx);
48 if (r) assert(ctx.err);
50 xlu__cfg_yylex_destroy(ctx.scanner);
51 fclose(f);
53 return ctx.err;
54 }
56 void xlu__cfg_set_free(XLU_ConfigSetting *set) {
57 free(set->name);
58 free(set->values);
59 free(set);
60 }
62 void xlu_cfg_destroy(XLU_Config *cfg) {
63 XLU_ConfigSetting *set, *set_next;
65 for (set= cfg->settings;
66 set;
67 set= set_next) {
68 set_next= set->next;
69 xlu__cfg_set_free(set);
70 }
71 free(cfg->filename);
72 free(cfg);
73 }
75 static XLU_ConfigSetting *find(const XLU_Config *cfg, const char *n) {
76 XLU_ConfigSetting *set;
78 for (set= cfg->settings;
79 set;
80 set= set->next)
81 if (!strcmp(set->name, n))
82 return set;
83 return 0;
84 }
86 static int find_atom(const XLU_Config *cfg, const char *n,
87 XLU_ConfigSetting **set_r) {
88 XLU_ConfigSetting *set;
90 set= find(cfg,n);
91 if (!set) return ESRCH;
93 if (set->avalues!=1) {
94 fprintf(cfg->report,
95 "%s:%d: warning: parameter `%s' is"
96 " a list but should be a single value\n",
97 cfg->filename, set->lineno, n);
98 return EINVAL;
99 }
100 *set_r= set;
101 return 0;
102 }
104 int xlu_cfg_get_string(const XLU_Config *cfg, const char *n,
105 const char **value_r) {
106 XLU_ConfigSetting *set;
107 int e;
109 e= find_atom(cfg,n,&set); if (e) return e;
110 *value_r= set->values[0];
111 return 0;
112 }
114 int xlu_cfg_get_long(const XLU_Config *cfg, const char *n,
115 long *value_r) {
116 long l;
117 XLU_ConfigSetting *set;
118 int e;
119 char *ep;
121 e= find_atom(cfg,n,&set); if (e) return e;
122 errno= 0; l= strtol(set->values[0], &ep, 0);
123 e= errno;
124 if (errno) {
125 e= errno;
126 assert(e==EINVAL || e==ERANGE);
127 fprintf(cfg->report,
128 "%s:%d: warning: parameter `%s' could not be parsed"
129 " as a number: %s\n",
130 cfg->filename, set->lineno, n, strerror(e));
131 return e;
132 }
133 if (*ep || ep==set->values[0]) {
134 fprintf(cfg->report,
135 "%s:%d: warning: parameter `%s' is not a valid number\n",
136 cfg->filename, set->lineno, n);
137 return EINVAL;
138 }
139 *value_r= l;
140 return 0;
141 }
144 int xlu_cfg_get_list(const XLU_Config *cfg, const char *n,
145 XLU_ConfigList **list_r, int *entries_r) {
146 XLU_ConfigSetting *set;
147 set= find(cfg,n); if (!set) return ESRCH;
148 if (set->avalues==1) {
149 fprintf(cfg->report,
150 "%s:%d: warning: parameter `%s' is a single value"
151 " but should be a list\n",
152 cfg->filename, set->lineno, n);
153 return EINVAL;
154 }
155 if (list_r) *list_r= set;
156 if (entries_r) *entries_r= set->nvalues;
157 return 0;
158 }
160 const char *xlu_cfg_get_listitem(const XLU_ConfigList *set, int entry) {
161 if (entry < 0 || entry >= set->nvalues) return 0;
162 return set->values[entry];
163 }
166 XLU_ConfigSetting *xlu__cfg_set_mk(CfgParseContext *ctx,
167 int alloc, char *atom) {
168 XLU_ConfigSetting *set= 0;
170 if (ctx->err) goto x;
171 assert(!!alloc == !!atom);
173 set= malloc(sizeof(*set));
174 if (!set) goto xe;
176 set->name= 0; /* tbd */
177 set->avalues= alloc;
179 if (!alloc) {
180 set->nvalues= 0;
181 set->values= 0;
182 } else {
183 set->values= malloc(sizeof(*set->values) * alloc);
184 if (!set->values) goto xe;
186 set->nvalues= 1;
187 set->values[0]= atom;
188 }
189 return set;
191 xe:
192 ctx->err= errno;
193 x:
194 free(set);
195 free(atom);
196 return 0;
197 }
199 void xlu__cfg_set_add(CfgParseContext *ctx, XLU_ConfigSetting *set,
200 char *atom) {
201 if (ctx->err) return;
203 assert(atom);
205 if (set->nvalues >= set->avalues) {
206 int new_avalues;
207 char **new_values;
209 if (set->avalues > INT_MAX / 100) { ctx->err= ERANGE; return; }
210 new_avalues= set->avalues * 4;
211 new_values= realloc(set->values,
212 sizeof(*new_values) * new_avalues);
213 if (!new_values) { ctx->err= errno; free(atom); return; }
214 set->values= new_values;
215 set->avalues= new_avalues;
216 }
217 set->values[set->nvalues++]= atom;
218 }
220 void xlu__cfg_set_store(CfgParseContext *ctx, char *name,
221 XLU_ConfigSetting *set, int lineno) {
222 if (ctx->err) return;
224 assert(name);
225 set->name= name;
226 set->lineno= lineno;
227 set->next= ctx->cfg->settings;
228 ctx->cfg->settings= set;
229 }
231 char *xlu__cfgl_strdup(CfgParseContext *ctx, const char *src) {
232 char *result;
234 if (ctx->err) return 0;
235 result= strdup(src);
236 if (!result) ctx->err= errno;
237 return result;
238 }
240 char *xlu__cfgl_dequote(CfgParseContext *ctx, const char *src) {
241 char *result;
242 const char *p;
243 char *q;
244 int len, c, nc;
246 if (ctx->err) return 0;
248 len= strlen(src);
249 assert(len>=2 && src[0]==src[len-1]);
251 result= malloc(len-1);
252 if (!result) { ctx->err= errno; return 0; }
254 q= result;
256 for (p= src+1;
257 p < src+len-1;
258 ) {
259 c= *p++;
260 if (c=='\\') {
261 assert(p < src+len-1);
262 nc= *p++;
263 if (nc=='"' || nc=='\'' || nc=='\\') {
264 *q++= nc;
265 } else if (nc=='a') { *q++= '\007';
266 } else if (nc=='b') { *q++= '\010';
267 } else if (nc=='f') { *q++= '\014';
268 } else if (nc=='n') { *q++= '\n';
269 } else if (nc=='r') { *q++= '\r';
270 } else if (nc=='t') { *q++= '\t';
271 } else if (nc=='v') { *q++= '\013';
272 } else if (nc=='x') {
274 #define NUMERIC_CHAR(minlen,maxlen,base,basetext) do{ \
275 char numbuf[(maxlen)+1], *ep; \
276 unsigned long val; \
277 \
278 strncpy(numbuf,p,(maxlen)); \
279 numbuf[(maxlen)]= 0; \
280 val= strtoul(numbuf, &ep, (base)); \
281 if (ep <= numbuf+(minlen)) { \
282 xlu__cfgl_lexicalerror(ctx,"invalid digit after" \
283 " backslash " basetext "numerical character escape" \
284 " in quoted string"); \
285 ctx->err= EINVAL; \
286 goto x; \
287 } \
288 p += (ep - numbuf); \
289 }while(0)
291 p++;
292 NUMERIC_CHAR(2,2,16,"hex");
293 } else if (nc>='0' && nc<='7') {
294 NUMERIC_CHAR(1,3,10,"octal");
295 }
296 assert(p <= src+len-1);
297 } else {
298 *q++= c;
299 }
300 }
302 x:
303 *q++= 0;
304 return result;
305 }
307 void xlu__cfgl_lexicalerror(CfgParseContext *ctx, char const *msg) {
308 YYLTYPE loc;
309 loc.first_line= xlu__cfg_yyget_lineno(ctx->scanner);
310 xlu__cfg_yyerror(&loc, ctx, msg);
311 ctx->lexerrlineno= loc.first_line;
312 }
314 void xlu__cfg_yyerror(YYLTYPE *loc, CfgParseContext *ctx, char const *msg) {
315 const char *text, *newline;
316 int len, lineno;
318 lineno= loc->first_line;
319 if (lineno <= ctx->lexerrlineno) return;
321 text= xlu__cfg_yyget_text(ctx->scanner);
322 len= xlu__cfg_yyget_leng(ctx->scanner);
323 newline= "";
324 if (len>0 && text[len-1]=='\n') {
325 len--;
326 lineno--;
327 if (!len) {
328 newline= "<newline>";
329 }
330 }
331 while (len>0 && (text[len-1]=='\t' || text[len-1]==' ')) {
332 len--;
333 }
335 fprintf(ctx->cfg->report,
336 "%s:%d: config parsing error near %s%.*s%s%s: %s\n",
337 ctx->cfg->filename, lineno,
338 len?"`":"", len, text, len?"'":"", newline,
339 msg);
340 if (!ctx->err) ctx->err= EINVAL;
341 }