13 #include "ktrfmt.tab.h"
15 int __ktrfmtlex
(YYSTYPE *);
16 #define __ktrfmt_lex __ktrfmtlex
18 void __ktrfmt_error
(struct ktrfmt_parse_ctx
*, const char *);
20 static void do_parse_err
(struct ktrfmt_parse_ctx
*, const char *, ...
)
25 do_parse_err
(struct ktrfmt_parse_ctx
*ctx
, const char *fmt
, ...
)
30 vsnprintf
(ctx
->errbuf
, ctx
->errbufsz
, fmt
, ap
);
35 #define parse_err(fmt, ...) \
37 do_parse_err
(ctx
, fmt
, ##__VA_ARGS__); \
42 struct evtr_variable
*
43 evtr_var_new
(const char *name
)
45 struct evtr_variable
*var
;
47 var
= calloc
(1, sizeof
(*var
));
49 if
(!(var
->name
= strdup
(name
))) {
53 var
->val.type
= EVTR_VAL_NIL
;
59 * XXX: should be reentrant
69 snprintf
(buf
, sizeof
(buf
), "@%ld", serno
);
75 index_hash
(struct ktrfmt_parse_ctx
*ctx
, const char *hashname
,
76 evtr_variable_value_t val
, evtr_var_t
*_var
)
80 hsh
= symtab_find
(ctx
->symtab
, hashname
);
81 if
(hsh
->val.type
== EVTR_VAL_NIL
) {
82 /* it's probably the first time we see this "variable" */
83 printd
(PARSE
, "creating hash for %s\n", hsh
->name
);
84 hsh
->val.type
= EVTR_VAL_HASH
;
85 hsh
->val.hashtab
= hash_new
();
86 } else if
(hsh
->val.type
!= EVTR_VAL_HASH
) {
87 printd
(PARSE
, "trying to use type %d as hash\n", hsh
->val.type
);
90 if
(val
->type
== EVTR_VAL_INT
) {
92 printd
(PARSE
, "looking up %s[%jd] in %p\n", hsh
->name
,
93 val
->num
, hsh
->val.hashtab
);
94 } else if
(val
->type
== EVTR_VAL_STR
) {
95 key
= (uintptr_t)val
->str
;
96 printd
(PARSE
, "looking up %s[\"%s\"] in %p\n", hsh
->name
,
97 val
->str
, hsh
->val.hashtab
);
99 do_parse_err
(ctx
, "trying to index hash '%s' with "
100 "non-supported value", hashname
);
104 if
(hash_find
(hsh
->val.hashtab
, key
, &ret
)) {
105 printd
(PARSE
, "didn't find it\n");
106 var
= evtr_var_new
(uniq_varname
());
108 printd
(PARSE
, "inserting it as %s\n", var
->name
);
109 if
(!hash_insert
(hsh
->val.hashtab
, key
,
111 do_parse_err
(ctx
, "can't insert temporary "
112 "variable into hash\n");
115 symtab_insert
(ctx
->symtab
, var
->name
, var
);
117 do_parse_err
(ctx
, "out of memory");
120 var
= (struct evtr_variable
*)ret
;
123 fprintf
(stderr
, "no var!\n");
136 %name
-prefix
"__ktrfmt_"
138 %parse
-param
{struct ktrfmt_parse_ctx
*ctx
}
142 struct evtr_variable
*var
;
143 struct evtr_variable_value
*val
;
153 %token
<na
> TOK_LEFT_BRACK
154 %token
<na
> TOK_RIGHT_BRACK
159 %type
<var
> construct_expr
160 %type
<var
> primary_expr
161 %type
<var
> postfix_expr
162 %type
<var
> unary_expr
163 %type
<na
> assign_expr
178 parse_err
("out of memory");
179 var
= evtr_var_new
(uniq_varname
());
180 var
->val.type
= EVTR_VAL_INT
;
182 var
->val.num
= strtoll
($1->str
, NULL
, 0);
184 parse_err
("Can't parse numeric constant '%s'", $1->str
);
192 parse_err
("out of memory");
193 var
= evtr_var_new
(uniq_varname
());
194 var
->val.type
= EVTR_VAL_STR
;
195 var
->val.str
= $1->str
;
197 parse_err
("out of memory");
203 ctor_args: constant
{
205 ctor
= evtr_var_new
(uniq_varname
());
206 ctor
->val.type
= EVTR_VAL_CTOR
;
207 ctor
->val.ctor.name
= NULL
;
208 TAILQ_INIT
(&ctor
->val.ctor.args
);
209 TAILQ_INSERT_HEAD
(&ctor
->val.ctor.args
, &$1->val
, link
);
212 | constant ctor_args
{
213 TAILQ_INSERT_HEAD
(&$2->val.ctor.args
, &$1->val
, link
);
217 construct_expr: TOK_CTOR
{
220 parse_err
("out of memory");
221 printd
(PARSE
, "TOK_CTOR\n");
222 printd
(PARSE
, "tok: %p, str = %p\n", $1, $1->str
);
223 var
= evtr_var_new
(uniq_varname
());
224 var
->val.type
= EVTR_VAL_CTOR
;
225 var
->val.ctor.name
= $1->str
;
226 TAILQ_INIT
(&var
->val.ctor.args
);
230 | TOK_CTOR ctor_args
{
231 evtr_variable_value_t val
;
233 parse_err
("out of memory");
234 printd
(PARSE
, "TOK_CTOR\n");
235 printd
(PARSE
, "tok: %p, str = %p\n", $1, $1->str
);
236 $2->val.ctor.name
= $1->str
;
238 printd
(PARSE
, "CTOR: %s\n", $1->str
);
239 TAILQ_FOREACH
(val
, &$2->val.ctor.args
, link
) {
242 printd
(PARSE
, "\t%jd\n", val
->num
);
245 printd
(PARSE
, "\t\"%s\"\n", val
->str
);
248 assert
(!"can't get here");
255 primary_expr: TOK_ID
{
258 parse_err
("out of memory");
259 printd
(PARSE
, "TOK_ID\n");
260 printd
(PARSE
, "tok: %p, str = %p\n", $1, $1->str
);
261 var
= symtab_find
(ctx
->symtab
, $1->str
);
263 if
(!(var
= evtr_var_new
($1->str
))) {
265 parse_err
("out of memory");
267 printd
(PARSE
, "creating var %s\n", $1->str
);
268 symtab_insert
(ctx
->symtab
, $1->str
, var
);
277 postfix_expr: postfix_expr TOK_LEFT_BRACK postfix_expr TOK_RIGHT_BRACK
{
280 if
(index_hash
(ctx
, $1->name
, &$3->val
, &var
))
284 | postfix_expr TOK_DOT TOK_ID
{
287 parse_err
("out of memory");
288 tmp
= evtr_var_new
(uniq_varname
());
289 tmp
->val.type
= EVTR_VAL_STR
;
290 tmp
->val.str
= $3->str
;
292 if
(index_hash
(ctx
, $1->name
, &tmp
->val
, &var
))
301 unary_expr: postfix_expr
{
305 assign_expr: unary_expr TOK_EQ constant
{
307 ctx
->ev
->type
= EVTR_TYPE_STMT
;
308 ctx
->ev
->stmt.var
= $1;
309 ctx
->ev
->stmt.val
= &$3->val
;
310 ctx
->ev
->stmt.op
= EVTR_OP_SET
;
312 | unary_expr TOK_EQ construct_expr
{
314 ctx
->ev
->type
= EVTR_TYPE_STMT
;
315 ctx
->ev
->stmt.var
= $1;
316 ctx
->ev
->stmt.val
= &$3->val
;
317 ctx
->ev
->stmt.op
= EVTR_OP_SET
;
327 void * __ktrfmt_scan_string
(const char *);
328 void __ktrfmt_delete_buffer
(void *);
331 __ktrfmt_error
(struct ktrfmt_parse_ctx
*ctx
, const char *s
)
333 do_parse_err
(ctx
, "%s", s
);
337 parse_string
(evtr_event_t ev
, struct symtab
*symtab
, const char *str
,
338 char *errbuf
, size_t errbufsz
)
342 struct ktrfmt_parse_ctx ctx
;
344 printd
(PARSE
, "parsing \"%s\"\n", str
);
348 ctx.errbuf
[0] = '\0';
349 ctx.errbufsz
= errbufsz
;
351 bufstate
= __ktrfmt_scan_string
(str
);
352 ret
= __ktrfmt_parse
(&ctx
);
353 __ktrfmt_delete_buffer
(bufstate
);
359 parse_var
(const char *str
, struct symtab
*symtab
, struct evtr_variable
**var
,
360 char *errbuf
, size_t errbufsz
)
364 struct ktrfmt_parse_ctx ctx
;
366 printd
(PARSE
, "parsing \"%s\"\n", str
);
371 ctx.errbuf
[0] = '\0';
372 ctx.errbufsz
= errbufsz
;
374 bufstate
= __ktrfmt_scan_string
(str
);
375 ret
= __ktrfmt_parse
(&ctx
);
376 __ktrfmt_delete_buffer
(bufstate
);