From a3e22a3f45b43b71f6ff586036fc66f64d9b2ced Mon Sep 17 00:00:00 2001 From: Aggelos Economopoulos Date: Sun, 23 May 2010 15:44:36 +0300 Subject: [PATCH] libevtr: add support for string literals --- lib/libevtr/evtr.c | 2 - lib/libevtr/internal.h | 3 + lib/libevtr/ktrfmt.l | 31 +++++++- lib/libevtr/ktrfmt.tab.c | 128 +++++++++++++++++++-------------- lib/libevtr/ktrfmt.y | 66 ++++++++++------- lib/libevtr/ktrfmt.yy.c | 150 ++++++++++++++++++++++++--------------- 6 files changed, 241 insertions(+), 139 deletions(-) diff --git a/lib/libevtr/evtr.c b/lib/libevtr/evtr.c index 235bff04b0..c49cbab749 100644 --- a/lib/libevtr/evtr.c +++ b/lib/libevtr/evtr.c @@ -692,7 +692,6 @@ strhash_insert(struct hashtab_str *strtab, const char *str, uint16_t *id) return 0; } -static struct symtab * symtab_new(void) { @@ -704,7 +703,6 @@ symtab_new(void) return symtab; } -static void symtab_destroy(struct symtab *symtab) { diff --git a/lib/libevtr/internal.h b/lib/libevtr/internal.h index 5acfeb4646..2344777d83 100644 --- a/lib/libevtr/internal.h +++ b/lib/libevtr/internal.h @@ -35,8 +35,11 @@ enum debug_flags { TAILQ_HEAD(evtr_value_list, evtr_variable_value); typedef struct evtr_value_list *evtr_value_list_t; +struct symtab *symtab_new(void); struct evtr_variable * symtab_find(const struct symtab *, const char *); int symtab_insert(struct symtab *, const char *, struct evtr_variable *); +void symtab_destroy(struct symtab *); + int parse_string(evtr_event_t, struct symtab *, const char *); int parse_var(const char *, struct symtab *, struct evtr_variable **); diff --git a/lib/libevtr/ktrfmt.l b/lib/libevtr/ktrfmt.l index 336e58578c..d830a58577 100644 --- a/lib/libevtr/ktrfmt.l +++ b/lib/libevtr/ktrfmt.l @@ -12,6 +12,7 @@ enum { static struct token tokens[NR_TOKENS]; static int curr_tok; +static struct symtab *strtab; struct token * tok_new(void) @@ -33,6 +34,24 @@ tok_free(struct token *tok) --curr_tok; } +/* + * We keep track of strings we've seen before so string comparison + * can be done w/ a simple pointer comparison + */ +static +char * +newstr(const char *s) +{ + void *r; + if (!strtab) + strtab = symtab_new(); /* XXX: oom */ + if ((r = symtab_find(strtab, s))) + return r; + r = strdup(s); + symtab_insert(strtab, r, r); + return r; +} + %} %option prefix="__ktrfmt" @@ -47,11 +66,21 @@ ID [a-zA-Z_$][a-zA-Z0-9_]* %% {WHITE}+ { /* ignore */ } +\"(\\\"|[^"\n])+\" { + size_t len; + yylval->tok = tok_new(); + yylval->tok->type = TOK_STR; + len = strlen(yytext); + yytext[len - 1] = '\0'; /* kill trailing quote */ + yylval->tok->str = newstr(yytext + 1); + printd(LEX, "TOK_STR\n"); + return TOK_STR; + } {ID} { yylval->tok = tok_new(); yylval->tok->type = TOK_ID; printd(LEX, "tok %p TOK_ID %p:%s\n", yylval->tok, yytext, yytext); - yylval->tok->str = strdup(yytext); + yylval->tok->str = strdup(yytext); /* XXX: oom */ return TOK_ID; } {INT} { diff --git a/lib/libevtr/ktrfmt.tab.c b/lib/libevtr/ktrfmt.tab.c index 664394bada..a45b883527 100644 --- a/lib/libevtr/ktrfmt.tab.c +++ b/lib/libevtr/ktrfmt.tab.c @@ -412,7 +412,7 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 13 +#define YYFINAL 12 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 14 @@ -421,9 +421,9 @@ union yyalloc /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 9 /* YYNRULES -- Number of rules. */ -#define YYNRULES 13 +#define YYNRULES 14 /* YYNRULES -- Number of states. */ -#define YYNSTATES 18 +#define YYNSTATES 20 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 @@ -470,23 +470,23 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint8 yyprhs[] = { 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, - 22, 24, 26, 30 + 22, 26, 28, 30, 34 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 11, 0, -1, 12, -1, 16, -1, 18, -1, 4, - -1, 5, -1, 3, -1, 13, -1, 3, 7, 15, - 8, -1, 14, -1, 15, -1, 16, 6, 13, -1, - 17, -1 + -1, 5, -1, 3, -1, 13, -1, 14, 7, 15, + 8, -1, 14, 9, 3, -1, 14, -1, 15, -1, + 16, 6, 13, -1, 17, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 88, 88, 90, 93, 95, 104, 118, 131, 135, - 182, 186, 190, 198 + 193, 196, 200, 204, 212 }; #endif @@ -515,14 +515,14 @@ static const yytype_uint16 yytoknum[] = static const yytype_uint8 yyr1[] = { 0, 10, 11, 12, 12, 13, 13, 14, 14, 15, - 15, 16, 17, 18 + 15, 15, 16, 17, 18 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 1, 1, 1, 1, 1, 4, - 1, 1, 3, 1 + 3, 1, 1, 3, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -530,8 +530,8 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 7, 5, 6, 0, 2, 8, 10, 11, 3, - 13, 4, 0, 1, 0, 0, 12, 9 + 0, 7, 5, 6, 0, 2, 8, 11, 12, 3, + 14, 4, 1, 0, 0, 0, 0, 10, 13, 9 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -545,14 +545,14 @@ static const yytype_int8 yydefgoto[] = #define YYPACT_NINF -6 static const yytype_int8 yypact[] = { - -3, -2, -6, -6, 6, -6, -6, -6, -6, 1, - -6, -6, -3, -6, -1, 0, -6, -6 + -3, -6, -6, -6, 4, -6, -6, -4, -6, 3, + -6, -6, -6, -3, 5, 2, 6, -6, -6, -6 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -6, -6, -6, -5, -6, 2, -6, -6, -6 + -6, -6, -6, -5, -6, -2, -6, -6, -6 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -562,14 +562,14 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 1, 2, 3, 2, 3, 12, 13, 14, 17, 16, - 0, 0, 0, 0, 15 + 1, 2, 3, 13, 12, 14, 2, 3, 17, 15, + 18, 16, 0, 0, 19 }; static const yytype_int8 yycheck[] = { - 3, 4, 5, 4, 5, 7, 0, 6, 8, 14, - -1, -1, -1, -1, 12 + 3, 4, 5, 7, 0, 9, 4, 5, 3, 6, + 15, 13, -1, -1, 8 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -577,7 +577,7 @@ static const yytype_int8 yycheck[] = static const yytype_uint8 yystos[] = { 0, 3, 4, 5, 11, 12, 13, 14, 15, 16, - 17, 18, 7, 0, 6, 15, 13, 8 + 17, 18, 0, 7, 9, 6, 15, 3, 13, 8 }; #define yyerrok (yyerrstatus = 0) @@ -1424,8 +1424,8 @@ yyreduce: { evtr_var_t var; var = evtr_var_new(uniq_varname()); - var->val.type = EVTR_VAL_INT; - var->val.str = strdup((yyvsp[(1) - (1)].tok)->str); + var->val.type = EVTR_VAL_STR; + var->val.str = (yyvsp[(1) - (1)].tok)->str; if (!var->val.str) { fprintf(stderr, "oom\n"); YYABORT; @@ -1470,48 +1470,59 @@ yyreduce: { evtr_var_t hsh, var; evtr_variable_value_t val; - hsh = symtab_find(ctx->symtab, (yyvsp[(1) - (4)].tok)->str); + uintptr_t ret, key; + hsh = symtab_find(ctx->symtab, (yyvsp[(1) - (4)].var)->name); +#if 0 if (!hsh) { - printd(PARSE, "creating hash: %s\n", (yyvsp[(1) - (4)].tok)->str); - hsh = evtr_var_new((yyvsp[(1) - (4)].tok)->str); + printd(PARSE, "creating hash: %s\n", (yyvsp[(1) - (4)].var)->name); + hsh = evtr_var_new((yyvsp[(1) - (4)].var)->name); hsh->val.type = EVTR_VAL_HASH; hsh->val.hashtab = hash_new(); - symtab_insert(ctx->symtab, (yyvsp[(1) - (4)].tok)->str, hsh); + symtab_insert(ctx->symtab, (yyvsp[(1) - (4)].var)->str, hsh); } - if (hsh->val.type != EVTR_VAL_HASH) { - printd(PARSE, "variable %s does not contain a hash\n", hsh->name); +#endif + if (hsh->val.type == EVTR_VAL_NIL) { + /* it's probably the first time we see this "variable" */ + printd(PARSE, "creating hash for %s\n", hsh->name); + hsh->val.type = EVTR_VAL_HASH; + hsh->val.hashtab = hash_new(); + } else if (hsh->val.type != EVTR_VAL_HASH) { + printd(PARSE, "trying to use type %d as hash\n", hsh->val.type); YYABORT; } val = &(yyvsp[(3) - (4)].var)->val; if (val->type == EVTR_VAL_INT) { - uintptr_t ret; - uintptr_t key = val->num; - printd(PARSE, "looking up %s[%jd] in %p\n", (yyvsp[(1) - (4)].tok)->str, val->num, hsh->val.hashtab); - /* XXX: should definitely be using uintptr_t for keys/values */ - if (hash_find(hsh->val.hashtab, key, &ret)) { - printd(PARSE, "didn't find it\n"); - var = evtr_var_new(uniq_varname()); - if (var) { - printd(PARSE, "inserting it as %s\n", var->name); - if (!hash_insert(hsh->val.hashtab, key, (uintptr_t)var)) { - fprintf(stderr, "can't insert tmp " - "variable into hash\n"); - YYABORT; - } + key = val->num; + printd(PARSE, "looking up %s[%jd] in %p\n", hsh->name, val->num, hsh->val.hashtab); + } else if (val->type == EVTR_VAL_STR) { + key = (uintptr_t)val->str; + printd(PARSE, "looking up %s[\"%s\"] in %p\n", hsh->name, val->str, hsh->val.hashtab); + } else { + fprintf(stderr, "trying to index hash w/ non-supported value\n"); + YYABORT; + } + + if (hash_find(hsh->val.hashtab, key, &ret)) { + printd(PARSE, "didn't find it\n"); + var = evtr_var_new(uniq_varname()); + if (var) { + printd(PARSE, "inserting it as %s\n", var->name); + if (!hash_insert(hsh->val.hashtab, key, (uintptr_t)var)) { + fprintf(stderr, "can't insert tmp " + "variable into hash\n"); + YYABORT; } } else { - var = (struct evtr_variable *)ret; + /* XXX: oom */ } } else { - fprintf(stderr, "trying to index hash w/ non-integral value\n"); - YYABORT; + var = (struct evtr_variable *)ret; } if (!var) { fprintf(stderr, "no var!\n"); YYABORT; /* XXX */ } - tok_free((yyvsp[(1) - (4)].tok)); (yyval.var) = var; ;} break; @@ -1519,16 +1530,16 @@ yyreduce: case 10: /* Line 1455 of yacc.c */ -#line 182 "ktrfmt.y" +#line 193 "ktrfmt.y" { - (yyval.var) = (yyvsp[(1) - (1)].var); + /* XXX */ ;} break; case 11: /* Line 1455 of yacc.c */ -#line 186 "ktrfmt.y" +#line 196 "ktrfmt.y" { (yyval.var) = (yyvsp[(1) - (1)].var); ;} @@ -1537,7 +1548,16 @@ yyreduce: case 12: /* Line 1455 of yacc.c */ -#line 190 "ktrfmt.y" +#line 200 "ktrfmt.y" + { + (yyval.var) = (yyvsp[(1) - (1)].var); + ;} + break; + + case 13: + +/* Line 1455 of yacc.c */ +#line 204 "ktrfmt.y" { (yyvsp[(1) - (3)].var)->val = (yyvsp[(3) - (3)].var)->val; ctx->ev->type = EVTR_TYPE_STMT; @@ -1547,10 +1567,10 @@ yyreduce: ;} break; - case 13: + case 14: /* Line 1455 of yacc.c */ -#line 198 "ktrfmt.y" +#line 212 "ktrfmt.y" { (yyval.na) = (yyvsp[(1) - (1)].na); ;} @@ -1559,7 +1579,7 @@ yyreduce: /* Line 1455 of yacc.c */ -#line 1563 "ktrfmt.tab.c" +#line 1583 "ktrfmt.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1771,7 +1791,7 @@ yyreturn: /* Line 1675 of yacc.c */ -#line 203 "ktrfmt.y" +#line 217 "ktrfmt.y" void * __ktrfmt_scan_string(const char *); diff --git a/lib/libevtr/ktrfmt.y b/lib/libevtr/ktrfmt.y index 531ac03892..f0b30990e1 100644 --- a/lib/libevtr/ktrfmt.y +++ b/lib/libevtr/ktrfmt.y @@ -104,8 +104,8 @@ constant: TOK_INT { | TOK_STR { evtr_var_t var; var = evtr_var_new(uniq_varname()); - var->val.type = EVTR_VAL_INT; - var->val.str = strdup($1->str); + var->val.type = EVTR_VAL_STR; + var->val.str = $1->str; if (!var->val.str) { fprintf(stderr, "oom\n"); YYABORT; @@ -132,52 +132,66 @@ primary_expr: TOK_ID { $$ = $1; } ; -postfix_expr: TOK_ID TOK_LEFT_BRACK postfix_expr TOK_RIGHT_BRACK { +postfix_expr: primary_expr TOK_LEFT_BRACK postfix_expr TOK_RIGHT_BRACK { evtr_var_t hsh, var; evtr_variable_value_t val; - hsh = symtab_find(ctx->symtab, $1->str); + uintptr_t ret, key; + hsh = symtab_find(ctx->symtab, $1->name); +#if 0 if (!hsh) { - printd(PARSE, "creating hash: %s\n", $1->str); - hsh = evtr_var_new($1->str); + printd(PARSE, "creating hash: %s\n", $1->name); + hsh = evtr_var_new($1->name); hsh->val.type = EVTR_VAL_HASH; hsh->val.hashtab = hash_new(); symtab_insert(ctx->symtab, $1->str, hsh); } - if (hsh->val.type != EVTR_VAL_HASH) { - printd(PARSE, "variable %s does not contain a hash\n", hsh->name); +#endif + if (hsh->val.type == EVTR_VAL_NIL) { + /* it's probably the first time we see this "variable" */ + printd(PARSE, "creating hash for %s\n", hsh->name); + hsh->val.type = EVTR_VAL_HASH; + hsh->val.hashtab = hash_new(); + } else if (hsh->val.type != EVTR_VAL_HASH) { + printd(PARSE, "trying to use type %d as hash\n", hsh->val.type); YYABORT; } val = &$3->val; if (val->type == EVTR_VAL_INT) { - uintptr_t ret; - uintptr_t key = val->num; - printd(PARSE, "looking up %s[%jd] in %p\n", $1->str, val->num, hsh->val.hashtab); - /* XXX: should definitely be using uintptr_t for keys/values */ - if (hash_find(hsh->val.hashtab, key, &ret)) { - printd(PARSE, "didn't find it\n"); - var = evtr_var_new(uniq_varname()); - if (var) { - printd(PARSE, "inserting it as %s\n", var->name); - if (!hash_insert(hsh->val.hashtab, key, (uintptr_t)var)) { - fprintf(stderr, "can't insert tmp " - "variable into hash\n"); - YYABORT; - } + key = val->num; + printd(PARSE, "looking up %s[%jd] in %p\n", hsh->name, val->num, hsh->val.hashtab); + } else if (val->type == EVTR_VAL_STR) { + key = (uintptr_t)val->str; + printd(PARSE, "looking up %s[\"%s\"] in %p\n", hsh->name, val->str, hsh->val.hashtab); + } else { + fprintf(stderr, "trying to index hash w/ non-supported value\n"); + YYABORT; + } + + if (hash_find(hsh->val.hashtab, key, &ret)) { + printd(PARSE, "didn't find it\n"); + var = evtr_var_new(uniq_varname()); + if (var) { + printd(PARSE, "inserting it as %s\n", var->name); + if (!hash_insert(hsh->val.hashtab, key, (uintptr_t)var)) { + fprintf(stderr, "can't insert tmp " + "variable into hash\n"); + YYABORT; } } else { - var = (struct evtr_variable *)ret; + /* XXX: oom */ } } else { - fprintf(stderr, "trying to index hash w/ non-integral value\n"); - YYABORT; + var = (struct evtr_variable *)ret; } if (!var) { fprintf(stderr, "no var!\n"); YYABORT; /* XXX */ } - tok_free($1); $$ = var; + } +| primary_expr TOK_DOT TOK_ID { + /* XXX */ } | primary_expr { $$ = $1; diff --git a/lib/libevtr/ktrfmt.yy.c b/lib/libevtr/ktrfmt.yy.c index de95311eb8..c924c061cb 100644 --- a/lib/libevtr/ktrfmt.yy.c +++ b/lib/libevtr/ktrfmt.yy.c @@ -391,8 +391,8 @@ static void yy_fatal_error (yyconst char msg[] ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 7 -#define YY_END_OF_BUFFER 8 +#define YY_NUM_RULES 8 +#define YY_END_OF_BUFFER 9 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -400,28 +400,28 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[15] = +static yyconst flex_int16_t yy_accept[20] = { 0, - 0, 0, 8, 7, 1, 2, 3, 4, 5, 6, - 1, 2, 3, 0 + 0, 0, 9, 8, 1, 8, 3, 4, 5, 6, + 7, 1, 0, 0, 3, 4, 2, 2, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 1, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, - 5, 1, 1, 1, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 1, 8, 1, 6, 1, 6, 6, 6, 6, - - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 4, 1, 5, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 1, 1, 1, + 7, 1, 1, 1, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 10, 11, 1, 8, 1, 8, 8, 8, 8, + + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -438,35 +438,40 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[9] = +static yyconst flex_int32_t yy_meta[12] = { 0, - 1, 1, 1, 2, 1, 2, 1, 1 + 1, 1, 2, 2, 1, 3, 1, 3, 1, 1, + 1 } ; -static yyconst flex_int16_t yy_base[16] = +static yyconst flex_int16_t yy_base[22] = { 0, - 0, 0, 14, 15, 11, 0, 8, 15, 15, 15, - 9, 0, 6, 15, 7 + 0, 0, 23, 24, 20, 10, 0, 11, 24, 24, + 24, 14, 8, 11, 0, 8, 24, 0, 24, 18, + 10 } ; -static yyconst flex_int16_t yy_def[16] = +static yyconst flex_int16_t yy_def[22] = { 0, - 14, 1, 14, 14, 14, 15, 14, 14, 14, 14, - 14, 15, 14, 0, 14 + 19, 1, 19, 19, 19, 20, 21, 19, 19, 19, + 19, 19, 20, 13, 21, 19, 19, 13, 0, 19, + 19 } ; -static yyconst flex_int16_t yy_nxt[24] = +static yyconst flex_int16_t yy_nxt[36] = { 0, - 4, 5, 6, 7, 8, 6, 9, 10, 12, 13, - 11, 13, 11, 14, 3, 14, 14, 14, 14, 14, - 14, 14, 14 + 4, 5, 4, 6, 7, 8, 9, 7, 10, 4, + 11, 17, 15, 16, 18, 12, 16, 14, 13, 14, + 13, 12, 19, 3, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19 } ; -static yyconst flex_int16_t yy_chk[24] = +static yyconst flex_int16_t yy_chk[36] = { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 15, 13, - 11, 7, 5, 3, 14, 14, 14, 14, 14, 14, - 14, 14, 14 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 13, 21, 16, 14, 12, 8, 13, 20, 6, + 20, 5, 3, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19 } ; static yy_state_type yy_last_accepting_state; @@ -498,6 +503,7 @@ enum { static struct token tokens[NR_TOKENS]; static int curr_tok; +static struct symtab *strtab; struct token * tok_new(void) @@ -519,7 +525,25 @@ tok_free(struct token *tok) --curr_tok; } -#line 523 "ktrfmt.yy.c" +/* + * We keep track of strings we've seen before so string comparison + * can be done w/ a simple pointer comparison + */ +static +char * +newstr(const char *s) +{ + void *r; + if (!strtab) + strtab = symtab_new(); /* XXX: oom */ + if ((r = symtab_find(strtab, s))) + return r; + r = strdup(s); + symtab_insert(strtab, r, r); + return r; +} + +#line 547 "ktrfmt.yy.c" #define INITIAL 0 @@ -712,9 +736,9 @@ YY_DECL YYSTYPE * yylval; -#line 48 "ktrfmt.l" +#line 67 "ktrfmt.l" -#line 718 "ktrfmt.yy.c" +#line 742 "ktrfmt.yy.c" yylval = yylval_param; @@ -769,13 +793,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 15 ) + if ( yy_current_state >= 20 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 15 ); + while ( yy_base[yy_current_state] != 24 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -801,23 +825,37 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 49 "ktrfmt.l" +#line 68 "ktrfmt.l" { /* ignore */ } YY_BREAK case 2: YY_RULE_SETUP -#line 50 "ktrfmt.l" +#line 69 "ktrfmt.l" +{ + size_t len; + yylval->tok = tok_new(); + yylval->tok->type = TOK_STR; + len = strlen(__ktrfmttext); + __ktrfmttext[len - 1] = '\0'; /* kill trailing quote */ + yylval->tok->str = newstr(__ktrfmttext + 1); + printd(LEX, "TOK_STR\n"); + return TOK_STR; + } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 79 "ktrfmt.l" { yylval->tok = tok_new(); yylval->tok->type = TOK_ID; printd(LEX, "tok %p TOK_ID %p:%s\n", yylval->tok, __ktrfmttext, __ktrfmttext); - yylval->tok->str = strdup(__ktrfmttext); + yylval->tok->str = strdup(__ktrfmttext); /* XXX: oom */ return TOK_ID; } YY_BREAK -case 3: +case 4: YY_RULE_SETUP -#line 57 "ktrfmt.l" +#line 86 "ktrfmt.l" { yylval->tok = tok_new(); yylval->tok->type = TOK_INT; @@ -826,39 +864,39 @@ YY_RULE_SETUP return TOK_INT; } YY_BREAK -case 4: +case 5: YY_RULE_SETUP -#line 64 "ktrfmt.l" +#line 93 "ktrfmt.l" { yylval = NULL; printd(LEX, "TOK_EQ\n"); return TOK_EQ; } YY_BREAK -case 5: +case 6: YY_RULE_SETUP -#line 69 "ktrfmt.l" +#line 98 "ktrfmt.l" { yylval = NULL; printd(LEX, "TOK_LEFT_BRACK\n"); return TOK_LEFT_BRACK; } YY_BREAK -case 6: +case 7: YY_RULE_SETUP -#line 74 "ktrfmt.l" +#line 103 "ktrfmt.l" { yylval = NULL; printd(LEX, "TOK_RIGHT_BRACK\n"); return TOK_RIGHT_BRACK; } YY_BREAK -case 7: +case 8: YY_RULE_SETUP -#line 80 "ktrfmt.l" +#line 109 "ktrfmt.l" ECHO; YY_BREAK -#line 862 "ktrfmt.yy.c" +#line 900 "ktrfmt.yy.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1150,7 +1188,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 15 ) + if ( yy_current_state >= 20 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1178,11 +1216,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 15 ) + if ( yy_current_state >= 20 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 14); + yy_is_jam = (yy_current_state == 19); return yy_is_jam ? 0 : yy_current_state; } @@ -1819,6 +1857,6 @@ void __ktrfmtfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 80 "ktrfmt.l" +#line 109 "ktrfmt.l" -- 2.41.0