mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
libxlu: rework internal representation of setting
This patches does following things: 1. Properly define a XLU_ConfigList type. Originally it was defined to be XLU_ConfigSetting. 2. Define XLU_ConfigValue type, which can be either a string or a list of XLU_ConfigValue. 3. ConfigSetting now references XLU_ConfigValue. Originally it only worked with **string. 4. Properly construct list where necessary, see changes to .y file. To achieve above changes: 1. xlu__cfg_set_mk and xlu__cfg_set_add are deleted, because they are no more needed in the new code. 2. Introduce xlu__cfg_string_mk to make a XLU_ConfigSetting that points to a XLU_ConfigValue that wraps a string. 3. Introduce xlu__cfg_list_mk to make a XLU_ConfigSetting that points to XLU_ConfigValue that is a list. 4. The parser now generates XLU_ConfigValue instead of XLU_ConfigSetting when construct values, which enables us to recursively generate list of lists. 5. XLU_ConfigSetting is generated in xlu__cfg_set_store. 6. Adapt other functions to use new types. No change to public API. Xl compiles without problem and 'xl create -n guest.cfg' is valgrind clean. This patch is needed because we're going to implement nested list support, which requires support for list of list. Signed-off-by: Wei Liu <wei.liu2@citrix.com> Cc: Ian Jackson <ian.jackson@eu.citrix.com> Cc: Ian Campbell <ian.campbell@citrix.com> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
This commit is contained in:
1 parent
711dec6729
commit
1a09c5113a
6 files changed
+174
-80
No files matched your search
+122
-50
@@ -131,14 +131,28 @@ int xlu_cfg_readdata(XLU_Config *cfg, const char *data, int length) {
|
||||
return ctx.err;
|
||||
}
|
||||
|
||||
void xlu__cfg_set_free(XLU_ConfigSetting *set) {
|
||||
void xlu__cfg_value_free(XLU_ConfigValue *value)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
switch (value->type) {
|
||||
case XLU_STRING:
|
||||
free(value->u.string);
|
||||
break;
|
||||
case XLU_LIST:
|
||||
for (i = 0; i < value->u.list.nvalues; i++)
|
||||
xlu__cfg_value_free(value->u.list.values[i]);
|
||||
free(value->u.list.values);
|
||||
}
|
||||
free(value);
|
||||
}
|
||||
|
||||
void xlu__cfg_set_free(XLU_ConfigSetting *set) {
|
||||
if (!set) return;
|
||||
free(set->name);
|
||||
for (i=0; i<set->nvalues; i++)
|
||||
free(set->values[i]);
|
||||
free(set->values);
|
||||
xlu__cfg_value_free(set->value);
|
||||
free(set);
|
||||
}
|
||||
|
||||
@@ -173,7 +187,7 @@ static int find_atom(const XLU_Config *cfg, const char *n,
|
||||
set= find(cfg,n);
|
||||
if (!set) return ESRCH;
|
||||
|
||||
if (set->avalues!=1) {
|
||||
if (set->value->type!=XLU_STRING) {
|
||||
if (!dont_warn)
|
||||
fprintf(cfg->report,
|
||||
"%s:%d: warning: parameter `%s' is"
|
||||
@@ -191,7 +205,7 @@ int xlu_cfg_get_string(const XLU_Config *cfg, const char *n,
|
||||
int e;
|
||||
|
||||
e= find_atom(cfg,n,&set,dont_warn); if (e) return e;
|
||||
*value_r= set->values[0];
|
||||
*value_r= set->value->u.string;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -202,7 +216,7 @@ int xlu_cfg_replace_string(const XLU_Config *cfg, const char *n,
|
||||
|
||||
e= find_atom(cfg,n,&set,dont_warn); if (e) return e;
|
||||
free(*value_r);
|
||||
*value_r= strdup(set->values[0]);
|
||||
*value_r= strdup(set->value->u.string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -214,7 +228,7 @@ int xlu_cfg_get_long(const XLU_Config *cfg, const char *n,
|
||||
char *ep;
|
||||
|
||||
e= find_atom(cfg,n,&set,dont_warn); if (e) return e;
|
||||
errno= 0; l= strtol(set->values[0], &ep, 0);
|
||||
errno= 0; l= strtol(set->value->u.string, &ep, 0);
|
||||
e= errno;
|
||||
if (errno) {
|
||||
e= errno;
|
||||
@@ -226,7 +240,7 @@ int xlu_cfg_get_long(const XLU_Config *cfg, const char *n,
|
||||
cfg->config_source, set->lineno, n, strerror(e));
|
||||
return e;
|
||||
}
|
||||
if (*ep || ep==set->values[0]) {
|
||||
if (*ep || ep==set->value->u.string) {
|
||||
if (!dont_warn)
|
||||
fprintf(cfg->report,
|
||||
"%s:%d: warning: parameter `%s' is not a valid number\n",
|
||||
@@ -253,7 +267,7 @@ int xlu_cfg_get_list(const XLU_Config *cfg, const char *n,
|
||||
XLU_ConfigList **list_r, int *entries_r, int dont_warn) {
|
||||
XLU_ConfigSetting *set;
|
||||
set= find(cfg,n); if (!set) return ESRCH;
|
||||
if (set->avalues==1) {
|
||||
if (set->value->type!=XLU_LIST) {
|
||||
if (!dont_warn) {
|
||||
fprintf(cfg->report,
|
||||
"%s:%d: warning: parameter `%s' is a single value"
|
||||
@@ -262,8 +276,8 @@ int xlu_cfg_get_list(const XLU_Config *cfg, const char *n,
|
||||
}
|
||||
return EINVAL;
|
||||
}
|
||||
if (list_r) *list_r= set;
|
||||
if (entries_r) *entries_r= set->nvalues;
|
||||
if (list_r) *list_r= &set->value->u.list;
|
||||
if (entries_r) *entries_r= set->value->u.list.nvalues;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -290,72 +304,130 @@ int xlu_cfg_get_list_as_string_list(const XLU_Config *cfg, const char *n,
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *xlu_cfg_get_listitem(const XLU_ConfigList *set, int entry) {
|
||||
if (entry < 0 || entry >= set->nvalues) return 0;
|
||||
return set->values[entry];
|
||||
const char *xlu_cfg_get_listitem(const XLU_ConfigList *list, int entry) {
|
||||
if (entry < 0 || entry >= list->nvalues) return 0;
|
||||
if (list->values[entry]->type != XLU_STRING) return 0;
|
||||
return list->values[entry]->u.string;
|
||||
}
|
||||
|
||||
|
||||
XLU_ConfigSetting *xlu__cfg_set_mk(CfgParseContext *ctx,
|
||||
int alloc, char *atom) {
|
||||
XLU_ConfigSetting *set= 0;
|
||||
XLU_ConfigValue *xlu__cfg_string_mk(CfgParseContext *ctx, char *atom)
|
||||
{
|
||||
XLU_ConfigValue *value = NULL;
|
||||
|
||||
if (ctx->err) goto x;
|
||||
assert(!!alloc == !!atom);
|
||||
|
||||
set= malloc(sizeof(*set));
|
||||
if (!set) goto xe;
|
||||
value = malloc(sizeof(*value));
|
||||
if (!value) goto xe;
|
||||
value->type = XLU_STRING;
|
||||
value->u.string = atom;
|
||||
|
||||
set->name= 0; /* tbd */
|
||||
set->avalues= alloc;
|
||||
|
||||
if (!alloc) {
|
||||
set->nvalues= 0;
|
||||
set->values= 0;
|
||||
} else {
|
||||
set->values= malloc(sizeof(*set->values) * alloc);
|
||||
if (!set->values) goto xe;
|
||||
|
||||
set->nvalues= 1;
|
||||
set->values[0]= atom;
|
||||
}
|
||||
return set;
|
||||
return value;
|
||||
|
||||
xe:
|
||||
ctx->err= errno;
|
||||
x:
|
||||
free(set);
|
||||
free(value);
|
||||
free(atom);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xlu__cfg_set_add(CfgParseContext *ctx, XLU_ConfigSetting *set,
|
||||
char *atom) {
|
||||
XLU_ConfigValue *xlu__cfg_list_mk(CfgParseContext *ctx, char *atom)
|
||||
{
|
||||
XLU_ConfigValue *value = NULL;
|
||||
XLU_ConfigValue **values = NULL;
|
||||
XLU_ConfigValue *val = NULL;
|
||||
|
||||
if (ctx->err) goto x;
|
||||
|
||||
val = malloc(sizeof(*val));
|
||||
if (!val) goto xe;
|
||||
val->type = XLU_STRING;
|
||||
val->u.string = atom;
|
||||
|
||||
values = malloc(sizeof(*values));
|
||||
if (!values) goto xe;
|
||||
values[0] = val;
|
||||
|
||||
value = malloc(sizeof(*value));
|
||||
if (!value) goto xe;
|
||||
value->type = XLU_LIST;
|
||||
value->u.list.nvalues = 1;
|
||||
value->u.list.avalues = 1;
|
||||
value->u.list.values = values;
|
||||
|
||||
return value;
|
||||
|
||||
xe:
|
||||
ctx->err= errno;
|
||||
x:
|
||||
free(value);
|
||||
free(values);
|
||||
free(val);
|
||||
free(atom);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xlu__cfg_list_append(CfgParseContext *ctx,
|
||||
XLU_ConfigValue *list,
|
||||
char *atom)
|
||||
{
|
||||
XLU_ConfigValue *val = NULL;
|
||||
if (ctx->err) return;
|
||||
|
||||
assert(atom);
|
||||
assert(list->type == XLU_LIST);
|
||||
|
||||
if (set->nvalues >= set->avalues) {
|
||||
if (list->u.list.nvalues >= list->u.list.avalues) {
|
||||
int new_avalues;
|
||||
char **new_values;
|
||||
XLU_ConfigValue **new_values = NULL;
|
||||
|
||||
if (set->avalues > INT_MAX / 100) { ctx->err= ERANGE; return; }
|
||||
new_avalues= set->avalues * 4;
|
||||
new_values= realloc(set->values,
|
||||
sizeof(*new_values) * new_avalues);
|
||||
if (!new_values) { ctx->err= errno; free(atom); return; }
|
||||
set->values= new_values;
|
||||
set->avalues= new_avalues;
|
||||
if (list->u.list.avalues > INT_MAX / 100) {
|
||||
ctx->err = ERANGE;
|
||||
free(atom);
|
||||
return;
|
||||
}
|
||||
|
||||
new_avalues = list->u.list.avalues * 4;
|
||||
new_values = realloc(list->u.list.values,
|
||||
sizeof(*new_values) * new_avalues);
|
||||
if (!new_values) {
|
||||
ctx->err = errno;
|
||||
free(atom);
|
||||
return;
|
||||
}
|
||||
|
||||
list->u.list.avalues = new_avalues;
|
||||
list->u.list.values = new_values;
|
||||
}
|
||||
set->values[set->nvalues++]= atom;
|
||||
|
||||
val = malloc(sizeof(*val));
|
||||
if (!val) {
|
||||
ctx->err = errno;
|
||||
free(atom);
|
||||
return;
|
||||
}
|
||||
|
||||
val->type = XLU_STRING;
|
||||
val->u.string = atom;
|
||||
list->u.list.values[list->u.list.nvalues] = val;
|
||||
list->u.list.nvalues++;
|
||||
}
|
||||
|
||||
void xlu__cfg_set_store(CfgParseContext *ctx, char *name,
|
||||
XLU_ConfigSetting *set, int lineno) {
|
||||
XLU_ConfigValue *val, int lineno) {
|
||||
XLU_ConfigSetting *set;
|
||||
|
||||
if (ctx->err) return;
|
||||
|
||||
assert(name);
|
||||
set = malloc(sizeof(*set));
|
||||
if (!set) {
|
||||
ctx->err = errno;
|
||||
return;
|
||||
}
|
||||
set->name= name;
|
||||
set->value = val;
|
||||
set->lineno= lineno;
|
||||
set->next= ctx->cfg->settings;
|
||||
ctx->cfg->settings= set;
|
||||
|
||||
@@ -23,11 +23,15 @@
|
||||
#include "libxlu_cfg_y.h"
|
||||
|
||||
void xlu__cfg_set_free(XLU_ConfigSetting *set);
|
||||
XLU_ConfigSetting *xlu__cfg_set_mk(CfgParseContext*, int alloc, char *atom);
|
||||
void xlu__cfg_set_add(CfgParseContext*, XLU_ConfigSetting *set, char *atom);
|
||||
void xlu__cfg_set_store(CfgParseContext*, char *name,
|
||||
XLU_ConfigSetting *set, int lineno);
|
||||
|
||||
XLU_ConfigValue *val, int lineno);
|
||||
XLU_ConfigValue *xlu__cfg_string_mk(CfgParseContext *ctx,
|
||||
char *atom);
|
||||
XLU_ConfigValue *xlu__cfg_list_mk(CfgParseContext *ctx, char *atom);
|
||||
void xlu__cfg_list_append(CfgParseContext *ctx,
|
||||
XLU_ConfigValue *list,
|
||||
char *atom);
|
||||
void xlu__cfg_value_free(XLU_ConfigValue *value);
|
||||
char *xlu__cfgl_strdup(CfgParseContext*, const char *src);
|
||||
char *xlu__cfgl_dequote(CfgParseContext*, const char *src);
|
||||
|
||||
|
||||
+12
-12
@@ -126,7 +126,7 @@ typedef union YYSTYPE
|
||||
#line 25 "libxlu_cfg_y.y"
|
||||
|
||||
char *string;
|
||||
XLU_ConfigSetting *setting;
|
||||
XLU_ConfigValue *value;
|
||||
|
||||
|
||||
|
||||
@@ -1148,7 +1148,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, ctx)
|
||||
|
||||
/* Line 1391 of yacc.c */
|
||||
#line 43 "libxlu_cfg_y.y"
|
||||
{ xlu__cfg_set_free((yyvaluep->setting)); };
|
||||
{ xlu__cfg_value_free((yyvaluep->value)); };
|
||||
|
||||
/* Line 1391 of yacc.c */
|
||||
#line 1155 "libxlu_cfg_y.c"
|
||||
@@ -1166,7 +1166,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, ctx)
|
||||
|
||||
/* Line 1391 of yacc.c */
|
||||
#line 43 "libxlu_cfg_y.y"
|
||||
{ xlu__cfg_set_free((yyvaluep->setting)); };
|
||||
{ xlu__cfg_value_free((yyvaluep->value)); };
|
||||
|
||||
/* Line 1391 of yacc.c */
|
||||
#line 1173 "libxlu_cfg_y.c"
|
||||
@@ -1175,7 +1175,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, ctx)
|
||||
|
||||
/* Line 1391 of yacc.c */
|
||||
#line 43 "libxlu_cfg_y.y"
|
||||
{ xlu__cfg_set_free((yyvaluep->setting)); };
|
||||
{ xlu__cfg_value_free((yyvaluep->value)); };
|
||||
|
||||
/* Line 1391 of yacc.c */
|
||||
#line 1182 "libxlu_cfg_y.c"
|
||||
@@ -1508,21 +1508,21 @@ yyreduce:
|
||||
|
||||
/* Line 1806 of yacc.c */
|
||||
#line 57 "libxlu_cfg_y.y"
|
||||
{ xlu__cfg_set_store(ctx,(yyvsp[(1) - (3)].string),(yyvsp[(3) - (3)].setting),(yylsp[(3) - (3)]).first_line); }
|
||||
{ xlu__cfg_set_store(ctx,(yyvsp[(1) - (3)].string),(yyvsp[(3) - (3)].value),(yylsp[(3) - (3)]).first_line); }
|
||||
break;
|
||||
|
||||
case 12:
|
||||
|
||||
/* Line 1806 of yacc.c */
|
||||
#line 62 "libxlu_cfg_y.y"
|
||||
{ (yyval.setting)= xlu__cfg_set_mk(ctx,1,(yyvsp[(1) - (1)].string)); }
|
||||
{ (yyval.value)= xlu__cfg_string_mk(ctx,(yyvsp[(1) - (1)].string)); }
|
||||
break;
|
||||
|
||||
case 13:
|
||||
|
||||
/* Line 1806 of yacc.c */
|
||||
#line 63 "libxlu_cfg_y.y"
|
||||
{ (yyval.setting)= (yyvsp[(3) - (4)].setting); }
|
||||
{ (yyval.value)= (yyvsp[(3) - (4)].value); }
|
||||
break;
|
||||
|
||||
case 14:
|
||||
@@ -1543,35 +1543,35 @@ yyreduce:
|
||||
|
||||
/* Line 1806 of yacc.c */
|
||||
#line 68 "libxlu_cfg_y.y"
|
||||
{ (yyval.setting)= xlu__cfg_set_mk(ctx,0,0); }
|
||||
{ (yyval.value)= xlu__cfg_list_mk(ctx,NULL); }
|
||||
break;
|
||||
|
||||
case 17:
|
||||
|
||||
/* Line 1806 of yacc.c */
|
||||
#line 69 "libxlu_cfg_y.y"
|
||||
{ (yyval.setting)= (yyvsp[(1) - (1)].setting); }
|
||||
{ (yyval.value)= (yyvsp[(1) - (1)].value); }
|
||||
break;
|
||||
|
||||
case 18:
|
||||
|
||||
/* Line 1806 of yacc.c */
|
||||
#line 70 "libxlu_cfg_y.y"
|
||||
{ (yyval.setting)= (yyvsp[(1) - (3)].setting); }
|
||||
{ (yyval.value)= (yyvsp[(1) - (3)].value); }
|
||||
break;
|
||||
|
||||
case 19:
|
||||
|
||||
/* Line 1806 of yacc.c */
|
||||
#line 72 "libxlu_cfg_y.y"
|
||||
{ (yyval.setting)= xlu__cfg_set_mk(ctx,2,(yyvsp[(1) - (2)].string)); }
|
||||
{ (yyval.value)= xlu__cfg_list_mk(ctx,(yyvsp[(1) - (2)].string)); }
|
||||
break;
|
||||
|
||||
case 20:
|
||||
|
||||
/* Line 1806 of yacc.c */
|
||||
#line 73 "libxlu_cfg_y.y"
|
||||
{ xlu__cfg_set_add(ctx,(yyvsp[(1) - (5)].setting),(yyvsp[(4) - (5)].string)); (yyval.setting)= (yyvsp[(1) - (5)].setting); }
|
||||
{ xlu__cfg_list_append(ctx,(yyvsp[(1) - (5)].value),(yyvsp[(4) - (5)].string)); (yyval.value)= (yyvsp[(1) - (5)].value); }
|
||||
break;
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ typedef union YYSTYPE
|
||||
#line 25 "libxlu_cfg_y.y"
|
||||
|
||||
char *string;
|
||||
XLU_ConfigSetting *setting;
|
||||
XLU_ConfigValue *value;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
%union {
|
||||
char *string;
|
||||
XLU_ConfigSetting *setting;
|
||||
XLU_ConfigValue *value;
|
||||
}
|
||||
|
||||
%locations
|
||||
@@ -39,8 +39,8 @@
|
||||
%type <string> atom
|
||||
%destructor { free($$); } atom IDENT STRING NUMBER
|
||||
|
||||
%type <setting> value valuelist values
|
||||
%destructor { xlu__cfg_set_free($$); } value valuelist values
|
||||
%type <value> value valuelist values
|
||||
%destructor { xlu__cfg_value_free($$); } value valuelist values
|
||||
|
||||
%%
|
||||
|
||||
@@ -59,18 +59,18 @@ assignment: IDENT '=' value { xlu__cfg_set_store(ctx,$1,$3,@3.first_line); }
|
||||
endstmt: NEWLINE
|
||||
| ';'
|
||||
|
||||
value: atom { $$= xlu__cfg_set_mk(ctx,1,$1); }
|
||||
value: atom { $$= xlu__cfg_string_mk(ctx,$1); }
|
||||
| '[' nlok valuelist ']' { $$= $3; }
|
||||
|
||||
atom: STRING { $$= $1; }
|
||||
| NUMBER { $$= $1; }
|
||||
|
||||
valuelist: /* empty */ { $$= xlu__cfg_set_mk(ctx,0,0); }
|
||||
valuelist: /* empty */ { $$= xlu__cfg_list_mk(ctx,NULL); }
|
||||
| values { $$= $1; }
|
||||
| values ',' nlok { $$= $1; }
|
||||
|
||||
values: atom nlok { $$= xlu__cfg_set_mk(ctx,2,$1); }
|
||||
| values ',' nlok atom nlok { xlu__cfg_set_add(ctx,$1,$4); $$= $1; }
|
||||
values: atom nlok { $$= xlu__cfg_list_mk(ctx,$1); }
|
||||
| values ',' nlok atom nlok { xlu__cfg_list_append(ctx,$1,$4); $$= $1; }
|
||||
|
||||
nlok:
|
||||
/* nothing */
|
||||
|
||||
@@ -23,17 +23,35 @@
|
||||
#include <assert.h>
|
||||
#include <regex.h>
|
||||
|
||||
#define XLU_ConfigList XLU_ConfigSetting
|
||||
|
||||
#include "libxlutil.h"
|
||||
|
||||
struct XLU_ConfigSetting { /* transparent */
|
||||
enum XLU_ConfigValueType {
|
||||
XLU_STRING,
|
||||
XLU_LIST,
|
||||
};
|
||||
|
||||
typedef struct XLU_ConfigValue XLU_ConfigValue;
|
||||
|
||||
typedef struct XLU_ConfigList {
|
||||
int avalues; /* available slots */
|
||||
int nvalues; /* actual occupied slots */
|
||||
XLU_ConfigValue **values;
|
||||
} XLU_ConfigList;
|
||||
|
||||
struct XLU_ConfigValue {
|
||||
enum XLU_ConfigValueType type;
|
||||
union {
|
||||
char *string;
|
||||
XLU_ConfigList list;
|
||||
} u;
|
||||
};
|
||||
|
||||
typedef struct XLU_ConfigSetting { /* transparent */
|
||||
struct XLU_ConfigSetting *next;
|
||||
char *name;
|
||||
int nvalues, avalues; /* lists have avalues>1 */
|
||||
char **values;
|
||||
XLU_ConfigValue *value;
|
||||
int lineno;
|
||||
};
|
||||
} XLU_ConfigSetting;
|
||||
|
||||
struct XLU_Config {
|
||||
XLU_ConfigSetting *settings;
|
||||
|
||||