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:
Wei Liu authored and Ian Campbell committed 2015-03-18 12:04:56 +00:00
1 parent 711dec6729
commit 1a09c5113a
6 files changed
+174 -80

No files matched your search

+122 -50
View File
@@ -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;
+8 -4
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -54,7 +54,7 @@ typedef union YYSTYPE
#line 25 "libxlu_cfg_y.y"
char *string;
XLU_ConfigSetting *setting;
XLU_ConfigValue *value;
+7 -7
View File
@@ -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 */
+24 -6
View File
@@ -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;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.