[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 18/19] libxlutil: nested list support
This is done with three major changes: 1. Rework internal representation of setting. 2. Extend grammar of parser. 3. Introduce new APIs. New APIs introduced: 1. xlu_cfg_value_type 2. xlu_cfg_value_get_string 3. xlu_cfg_value_get_list 4. xlu_cfg_get_listitem2 Previous APIs work as before. Nested list will be used to represent two dimensional array used to specify distances among different vNUMA nodes. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> --- tools/libxl/libxlu_cfg.c | 180 +++++++++++++++++++++++++---------------- tools/libxl/libxlu_cfg_i.h | 15 +++- tools/libxl/libxlu_cfg_y.c | 110 +++++++++++-------------- tools/libxl/libxlu_cfg_y.h | 2 +- tools/libxl/libxlu_cfg_y.y | 19 +++-- tools/libxl/libxlu_internal.h | 24 ++++-- tools/libxl/libxlutil.h | 11 ++- 7 files changed, 208 insertions(+), 153 deletions(-) diff --git a/tools/libxl/libxlu_cfg.c b/tools/libxl/libxlu_cfg.c index 22adcb0..db26c34 100644 --- a/tools/libxl/libxlu_cfg.c +++ b/tools/libxl/libxlu_cfg.c @@ -132,13 +132,9 @@ int xlu_cfg_readdata(XLU_Config *cfg, const char *data, int length) { } void xlu__cfg_set_free(XLU_ConfigSetting *set) { - int i; - if (!set) return; + xlu__cfg_value_free(set->value); free(set->name); - for (i=0; i<set->nvalues; i++) - free(set->values[i]); - free(set->values); free(set); } @@ -173,7 +169,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" @@ -185,13 +181,30 @@ static int find_atom(const XLU_Config *cfg, const char *n, return 0; } +enum XLU_ConfigValueType xlu_cfg_value_type(const XLU_ConfigValue *value) +{ + return value->type; +} + +const char *xlu_cfg_value_get_string(const XLU_ConfigValue *value) +{ + assert(value->type == XLU_STRING); + return value->u.string; +} + +const XLU_ConfigList *xlu_cfg_value_get_list(const XLU_ConfigValue *value) +{ + assert(value->type == XLU_LIST); + return &value->u.list; +} + int xlu_cfg_get_string(const XLU_Config *cfg, const char *n, const char **value_r, int dont_warn) { XLU_ConfigSetting *set; 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 +215,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 +227,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 +239,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 +266,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 +275,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 +303,29 @@ 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; - - if (ctx->err) goto x; - assert(!!alloc == !!atom); - - set= malloc(sizeof(*set)); - if (!set) goto xe; - - 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; - - xe: - ctx->err= errno; - x: - free(set); - free(atom); - return 0; -} - -void xlu__cfg_set_add(CfgParseContext *ctx, XLU_ConfigSetting *set, - char *atom) { - if (ctx->err) return; - - assert(atom); - - if (set->nvalues >= set->avalues) { - int new_avalues; - char **new_values; - - 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; - } - set->values[set->nvalues++]= atom; +const XLU_ConfigValue *xlu_cfg_get_listitem2(const XLU_ConfigList *list, + int entry) +{ + if (entry < 0 || entry >= list->nvalues) return NULL; + return list->values[entry]; } 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)); + assert(set); set->name= name; + set->value = val; set->lineno= lineno; set->next= ctx->cfg->settings; ctx->cfg->settings= set; @@ -473,6 +443,76 @@ void xlu__cfg_yyerror(YYLTYPE *loc, CfgParseContext *ctx, char const *msg) { if (!ctx->err) ctx->err= EINVAL; } +XLU_ConfigValue *xlu__cfg_make_string(CfgParseContext *ctx, + char *src) +{ + XLU_ConfigValue *ret; + + ret = malloc(sizeof(*ret)); + assert(ret); + ret->type = XLU_STRING; + ret->u.string = src; + + return ret; +} + +XLU_ConfigValue *xlu__cfg_make_list(CfgParseContext *ctx, + XLU_ConfigValue *val) +{ + XLU_ConfigValue *ret; + + ret = malloc(sizeof(*ret)); + assert(ret); + ret->type = XLU_LIST; + ret->u.list.nvalues = 1; + ret->u.list.values = malloc(sizeof(*ret->u.list.values)); + ret->u.list.values[0] = val; + + return ret; +} + +XLU_ConfigValue *xlu__cfg_list_append(CfgParseContext *ctx, + XLU_ConfigValue *list, + XLU_ConfigValue *val) +{ + XLU_ConfigValue **new_val; + + assert(list->type == XLU_LIST); + + new_val = realloc(list->u.list.values, + sizeof(*new_val) * (list->u.list.nvalues+1)); + if (!new_val) { + ctx->err = errno; + xlu__cfg_value_free(val); + return list; + } + + list->u.list.values = new_val; + list->u.list.values[list->u.list.nvalues] = val; + list->u.list.nvalues++; + + return list; +} + +void xlu__cfg_value_free(XLU_ConfigValue *val) +{ + int i; + + if (!val) return; + + switch (val->type) { + case XLU_STRING: + free(val->u.string); + break; + case XLU_LIST: + for (i = 0; i < val->u.list.nvalues; i++) { + xlu__cfg_value_free(val->u.list.values[i]); + } + free(val->u.list.values); + } + free(val); +} + /* * Local variables: * mode: C diff --git a/tools/libxl/libxlu_cfg_i.h b/tools/libxl/libxlu_cfg_i.h index 54d033c..89cef9a 100644 --- a/tools/libxl/libxlu_cfg_i.h +++ b/tools/libxl/libxlu_cfg_i.h @@ -23,10 +23,8 @@ #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); char *xlu__cfgl_strdup(CfgParseContext*, const char *src); char *xlu__cfgl_dequote(CfgParseContext*, const char *src); @@ -36,7 +34,18 @@ void xlu__cfgl_lexicalerror(CfgParseContext*, char const *msg); void xlu__cfgl_likely_python(CfgParseContext *ctx); +XLU_ConfigValue *xlu__cfg_make_string(CfgParseContext*, char *src); +XLU_ConfigValue *xlu__cfg_make_list(CfgParseContext*, + XLU_ConfigValue *val); + + + +XLU_ConfigValue *xlu__cfg_list_append(CfgParseContext *ctx, + XLU_ConfigValue *list, + XLU_ConfigValue *val); + +void xlu__cfg_value_free(struct XLU_ConfigValue *val); /* Why oh why does bison not declare this in its autogenerated .h ? */ int xlu__cfg_yyparse(CfgParseContext *ctx); diff --git a/tools/libxl/libxlu_cfg_y.c b/tools/libxl/libxlu_cfg_y.c index 07b5a1d..bc2b81e 100644 --- a/tools/libxl/libxlu_cfg_y.c +++ b/tools/libxl/libxlu_cfg_y.c @@ -126,7 +126,7 @@ typedef union YYSTYPE #line 25 "libxlu_cfg_y.y" char *string; - XLU_ConfigSetting *setting; + XLU_ConfigValue *value; @@ -377,14 +377,14 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 24 +#define YYLAST 26 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 12 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 11 /* YYNRULES -- Number of rules. */ -#define YYNRULES 22 +#define YYNRULES 21 /* YYNRULES -- Number of states. */ #define YYNSTATES 30 @@ -433,8 +433,8 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint8 yyprhs[] = { 0, 0, 3, 5, 8, 9, 12, 15, 17, 20, - 24, 26, 28, 30, 35, 37, 39, 40, 42, 46, - 49, 55, 56 + 24, 26, 28, 30, 32, 34, 36, 41, 42, 45, + 51, 52 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ @@ -443,17 +443,17 @@ static const yytype_int8 yyrhs[] = 13, 0, -1, 14, -1, 14, 16, -1, -1, 14, 15, -1, 16, 17, -1, 17, -1, 1, 6, -1, 3, 7, 18, -1, 6, -1, 8, -1, 19, -1, - 9, 22, 20, 10, -1, 4, -1, 5, -1, -1, - 21, -1, 21, 11, 22, -1, 19, 22, -1, 21, - 11, 22, 19, 22, -1, -1, 22, 6, -1 + 20, -1, 4, -1, 5, -1, 9, 22, 21, 10, + -1, -1, 18, 22, -1, 21, 11, 22, 18, 22, + -1, -1, 22, 6, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 47, 47, 48, 50, 51, 53, 54, 55, 57, - 59, 60, 62, 63, 65, 66, 68, 69, 70, 72, - 73, 75, 77 + 59, 60, 62, 63, 65, 66, 68, 70, 71, 72, + 74, 76 }; #endif @@ -464,7 +464,7 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "IDENT", "STRING", "NUMBER", "NEWLINE", "'='", "';'", "'['", "']'", "','", "$accept", "file", "stmts", "stmt", - "assignment", "endstmt", "value", "atom", "valuelist", "values", "nlok", 0 + "assignment", "endstmt", "value", "atom", "list", "values", "nlok", 0 }; #endif @@ -482,16 +482,16 @@ static const yytype_uint16 yytoknum[] = static const yytype_uint8 yyr1[] = { 0, 12, 13, 13, 14, 14, 15, 15, 15, 16, - 17, 17, 18, 18, 19, 19, 20, 20, 20, 21, - 21, 22, 22 + 17, 17, 18, 18, 19, 19, 20, 21, 21, 21, + 22, 22 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 2, 0, 2, 2, 1, 2, 3, - 1, 1, 1, 4, 1, 1, 0, 1, 3, 2, - 5, 0, 2 + 1, 1, 1, 1, 1, 1, 4, 0, 2, 5, + 0, 2 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -500,32 +500,32 @@ static const yytype_uint8 yyr2[] = static const yytype_uint8 yydefact[] = { 4, 0, 0, 1, 0, 0, 10, 11, 5, 3, - 7, 8, 0, 6, 14, 15, 21, 9, 12, 16, - 22, 21, 0, 17, 19, 13, 21, 18, 21, 20 + 7, 8, 0, 6, 14, 15, 20, 9, 12, 13, + 17, 21, 20, 0, 18, 16, 20, 0, 20, 19 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 1, 2, 8, 9, 10, 17, 18, 22, 23, - 19 + -1, 1, 2, 8, 9, 10, 17, 18, 19, 23, + 20 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -18 +#define YYPACT_NINF -19 static const yytype_int8 yypact[] = { - -18, 4, 0, -18, -1, 6, -18, -18, -18, 3, - -18, -18, 11, -18, -18, -18, -18, -18, -18, 13, - -18, -18, 12, 10, 17, -18, -18, 13, -18, 17 + -19, 20, 0, -19, 15, 16, -19, -19, -19, 4, + -19, -19, 13, -19, -19, -19, -19, -19, -19, -19, + 10, -19, -19, -6, 18, -19, -19, 10, -19, 18 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -18, -18, -18, -18, -18, 15, -18, -17, -18, -18, - -14 + -19, -19, -19, -19, -19, 17, -18, -19, -19, -19, + -15 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -534,22 +534,22 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -3 static const yytype_int8 yytable[] = { - -2, 4, 21, 5, 3, 11, 6, 24, 7, 6, - 28, 7, 27, 12, 29, 14, 15, 14, 15, 20, - 16, 26, 25, 20, 13 + -2, 4, 22, 5, 25, 26, 6, 24, 7, 28, + 6, 27, 7, 29, 14, 15, 21, 14, 15, 16, + 3, 11, 16, 12, 21, 0, 13 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-18)) + ((yystate) == (-19)) #define yytable_value_is_error(yytable_value) \ YYID (0) -static const yytype_uint8 yycheck[] = +static const yytype_int8 yycheck[] = { - 0, 1, 19, 3, 0, 6, 6, 21, 8, 6, - 27, 8, 26, 7, 28, 4, 5, 4, 5, 6, - 9, 11, 10, 6, 9 + 0, 1, 20, 3, 10, 11, 6, 22, 8, 27, + 6, 26, 8, 28, 4, 5, 6, 4, 5, 9, + 0, 6, 9, 7, 6, -1, 9 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -557,8 +557,8 @@ static const yytype_uint8 yycheck[] = static const yytype_uint8 yystos[] = { 0, 13, 14, 0, 1, 3, 6, 8, 15, 16, - 17, 6, 7, 17, 4, 5, 9, 18, 19, 22, - 6, 19, 20, 21, 22, 10, 11, 22, 19, 22 + 17, 6, 7, 17, 4, 5, 9, 18, 19, 20, + 22, 6, 18, 21, 22, 10, 11, 22, 18, 22 }; #define yyerrok (yyerrstatus = 0) @@ -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" @@ -1162,11 +1162,11 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, ctx) /* Line 1391 of yacc.c */ #line 1164 "libxlu_cfg_y.c" break; - case 20: /* "valuelist" */ + case 20: /* "list" */ /* 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,14 @@ 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)); } - break; - - case 13: - -/* Line 1806 of yacc.c */ -#line 63 "libxlu_cfg_y.y" - { (yyval.setting)= (yyvsp[(3) - (4)].setting); } + { (yyval.value)= xlu__cfg_make_string(ctx,(yyvsp[(1) - (1)].string)); } break; case 14: @@ -1543,41 +1536,34 @@ yyreduce: /* Line 1806 of yacc.c */ #line 68 "libxlu_cfg_y.y" - { (yyval.setting)= xlu__cfg_set_mk(ctx,0,0); } + { (yyval.value)= (yyvsp[(3) - (4)].value); } break; case 17: /* Line 1806 of yacc.c */ -#line 69 "libxlu_cfg_y.y" - { (yyval.setting)= (yyvsp[(1) - (1)].setting); } +#line 70 "libxlu_cfg_y.y" + { (yyval.value)= xlu__cfg_make_list(ctx,NULL); } break; case 18: /* Line 1806 of yacc.c */ -#line 70 "libxlu_cfg_y.y" - { (yyval.setting)= (yyvsp[(1) - (3)].setting); } +#line 71 "libxlu_cfg_y.y" + { (yyval.value)= xlu__cfg_make_list(ctx,(yyvsp[(1) - (2)].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)); } - 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)].value)); (yyval.value)= (yyvsp[(1) - (5)].value);} break; /* Line 1806 of yacc.c */ -#line 1581 "libxlu_cfg_y.c" +#line 1567 "libxlu_cfg_y.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires diff --git a/tools/libxl/libxlu_cfg_y.h b/tools/libxl/libxlu_cfg_y.h index d7dfaf2..37e8213 100644 --- a/tools/libxl/libxlu_cfg_y.h +++ b/tools/libxl/libxlu_cfg_y.h @@ -54,7 +54,7 @@ typedef union YYSTYPE #line 25 "libxlu_cfg_y.y" char *string; - XLU_ConfigSetting *setting; + XLU_ConfigValue *value; diff --git a/tools/libxl/libxlu_cfg_y.y b/tools/libxl/libxlu_cfg_y.y index 5acd438..cd0d494 100644 --- a/tools/libxl/libxlu_cfg_y.y +++ b/tools/libxl/libxlu_cfg_y.y @@ -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 list values +%destructor { xlu__cfg_value_free($$); } value list values %% @@ -59,18 +59,17 @@ assignment: IDENT '=' value { xlu__cfg_set_store(ctx,$1,$3,@3.first_line); } endstmt: NEWLINE | ';' -value: atom { $$= xlu__cfg_set_mk(ctx,1,$1); } - | '[' nlok valuelist ']' { $$= $3; } +value: atom { $$= xlu__cfg_make_string(ctx,$1); } + | list atom: STRING { $$= $1; } | NUMBER { $$= $1; } -valuelist: /* empty */ { $$= xlu__cfg_set_mk(ctx,0,0); } - | values { $$= $1; } - | values ',' nlok { $$= $1; } +list: '[' nlok values ']' { $$= $3; } -values: atom nlok { $$= xlu__cfg_set_mk(ctx,2,$1); } - | values ',' nlok atom nlok { xlu__cfg_set_add(ctx,$1,$4); $$= $1; } +values: /* empty */ { $$= xlu__cfg_make_list(ctx,NULL); } + | value nlok { $$= xlu__cfg_make_list(ctx,$1); } + | values ',' nlok value nlok { xlu__cfg_list_append(ctx,$1,$4); $$= $1;} nlok: /* nothing */ diff --git a/tools/libxl/libxlu_internal.h b/tools/libxl/libxlu_internal.h index 7579158..66eec28 100644 --- a/tools/libxl/libxlu_internal.h +++ b/tools/libxl/libxlu_internal.h @@ -23,17 +23,29 @@ #include <assert.h> #include <regex.h> -#define XLU_ConfigList XLU_ConfigSetting - #include "libxlutil.h" -struct XLU_ConfigSetting { /* transparent */ +typedef struct XLU_ConfigValue XLU_ConfigValue; + +typedef struct XLU_ConfigList { + int nvalues; + XLU_ConfigValue **values; +} XLU_ConfigList; + +typedef struct XLU_ConfigValue { + enum XLU_ConfigValueType type; + union { + char *string; + XLU_ConfigList list; + } u; +} XLU_ConfigValue; + +typedef struct XLU_ConfigSetting { /* transparent */ struct XLU_ConfigSetting *next; char *name; - int nvalues, avalues; /* lists have avalues>1 */ - char **values; + struct XLU_ConfigValue *value; int lineno; -}; +} XLU_ConfigSetting; struct XLU_Config { XLU_ConfigSetting *settings; diff --git a/tools/libxl/libxlutil.h b/tools/libxl/libxlutil.h index 0333e55..37d9549 100644 --- a/tools/libxl/libxlutil.h +++ b/tools/libxl/libxlutil.h @@ -23,6 +23,15 @@ /* Unless otherwise stated, all functions return an errno value. */ typedef struct XLU_Config XLU_Config; typedef struct XLU_ConfigList XLU_ConfigList; +typedef struct XLU_ConfigValue XLU_ConfigValue; +enum XLU_ConfigValueType { + XLU_STRING, + XLU_LIST, +}; + +enum XLU_ConfigValueType xlu_cfg_value_type(const XLU_ConfigValue *value); +const char *xlu_cfg_value_get_string(const XLU_ConfigValue *value); +const XLU_ConfigList *xlu_cfg_value_get_list(const XLU_ConfigValue *value); XLU_Config *xlu_cfg_init(FILE *report, const char *report_filename); /* 0 means we got ENOMEM. */ @@ -65,7 +74,7 @@ int xlu_cfg_get_list_as_string_list(const XLU_Config *cfg, const char *n, const char *xlu_cfg_get_listitem(const XLU_ConfigList*, int entry); /* xlu_cfg_get_listitem cannot fail, except that if entry is * out of range it returns 0 (not setting errno) */ - +const XLU_ConfigValue *xlu_cfg_get_listitem2(const XLU_ConfigList*, int entry); /* * Disk specification parsing. -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |