46 #define MIN_ALLOC_NODES (8)
47 #define MIN_ALLOC_BUF (64)
48 #define TUPLEZ_MAX_VARS (4)
50 #define tuple_error(ctx, ...) fprintf (stderr, "Tuple compiler: " __VA_ARGS__)
106 return g_new0(TupleEvalContext, 1);
116 for (i = 0; i < ctx->nvariables; i++)
117 if (ctx->variables[i]) {
118 ctx->variables[i]->fieldread =
FALSE;
119 ctx->variables[i]->fieldvalid =
FALSE;
121 ctx->variables[i]->fieldstr =
NULL;
135 for (i = 0; i < ctx->nvariables; i++)
136 if (ctx->variables[i])
139 g_free(ctx->variables);
150 tmp->
name = g_strdup(name);
169 for (i = 0; i < ctx->nvariables; i++)
170 if (!ctx->variables[i]) {
171 ctx->variables[i] = tmp;
179 ctx->variables[i] = tmp;
188 node->prev = (*nodes)->prev;
189 (*nodes)->prev->next = node;
190 (*nodes)->prev = node;
202 return g_new0(TupleEvalNode, 1);
208 TupleEvalNode *curr = expr, *next;
225 static TupleEvalNode *
tuple_compiler_pass1(
int *level, TupleEvalContext *ctx,
char **expression);
229 char **str,
char *buf, gssize max,
230 char endch,
bool_t *literal,
char *errstr,
char *item)
233 char *
s = *str, tmpendch;
236 if (*literal ==
FALSE) {
237 tuple_error(ctx,
"Literal string value not allowed in '%s'.\n", item);
248 if (*literal ==
FALSE) {
249 while (*s !=
'\0' && *s != tmpendch && (isalnum(*s) || *s ==
'-') && i < (max - 1)) {
253 if (*s != tmpendch && *s !=
'}' && !isalnum(*s) && *s !=
'-') {
254 tuple_error(ctx,
"Invalid field '%s' in '%s'.\n", *str, item);
256 }
else if (*s != tmpendch) {
257 tuple_error(ctx,
"Expected '%c' in '%s'.\n", tmpendch, item);
261 while (*s !=
'\0' && *s != tmpendch && i < (max - 1)) {
272 tuple_error(ctx,
"Expected literal string end ('%c') in '%s'.\n", tmpendch, item);
278 tuple_error(ctx,
"Expected '%c' after %s in '%s'\n", endch, errstr, item);
292 if (name ==
'\0')
return -1;
294 if (isdigit(name[0])) {
301 for (i = 0; i < ctx->nvariables; i++)
302 if (ctx->variables[i] && !strcmp(ctx->variables[i]->name, name))
322 tmp->opcode = opcode;
325 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, item);
330 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps2, item);
350 TupleEvalNode *res =
NULL, *tmp =
NULL;
351 char *c = *expression, *item, tmps1[
MAX_STR];
356 while (*c !=
'\0' && !end) {
362 }
else if (*c ==
'$') {
378 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, expr);
396 }
else if (isdigit(*c)) {
400 tuple_error(ctx,
"Definitions are not yet supported!\n");
412 if (*c !=
'=')
goto ext_expression;
440 if (!strncmp(c,
"empty)?", 7)) {
448 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, expr);
471 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, expr);
481 tuple_error(ctx,
"Expected '{', got '%c' in '%s'.\n", *c, c);
485 }
else if (*c ==
'%') {
492 while (*c !=
'\0' && (isalnum(*c) || *c ==
'-') && *c !=
'}' && *c !=
':' && i < (
MAX_STR - 1))
498 }
else if (*c ==
'}') {
500 }
else if (*c ==
'\0') {
501 tuple_error(ctx,
"Expected '}' or function arguments in '%s'\n", item);
505 tuple_error(ctx,
"Expected '{', got '%c' in '%s'.\n", *c, c);
511 while (*c !=
'\0' && *c !=
'$' && *c !=
'%' && *c !=
'}' && i < (
MAX_STR - 1)) {
519 tmp->text = g_strdup(tmps1);
525 tuple_error(ctx,
"Syntax error! Uneven/unmatched nesting of elements in '%s'!\n", c);
542 char *tmpexpr = expr;
548 tuple_error(ctx,
"Syntax error! Uneven/unmatched nesting of elements! (%d)\n", level);
587 var,
const Tuple * tuple)
595 switch (var->
ctype) {
622 expr,
const Tuple * tuple, GString * out)
624 TupleEvalNode *curr = expr;
628 char tmps[
MAX_STR], *tmps0, *tmps1, *tmps2;
632 if (!expr)
return FALSE;
635 const char *str =
NULL;
637 switch (curr->opcode) {
643 var0 = ctx->variables[curr->var[0]];
645 switch (var0->
type) {
648 switch (var0->
ctype) {
654 g_snprintf (tmps,
sizeof (tmps),
"%d", var0->
defvali);
670 var0 = ctx->variables[curr->var[0]];
671 var1 = ctx->variables[curr->var[1]];
673 type0 =
tf_get_var(&tmps0, &tmpi0, var0, tuple);
674 type1 =
tf_get_var(&tmps1, &tmpi1, var1, tuple);
678 if (type0 == type1) {
680 resulti = strcmp(tmps0, tmps1);
682 resulti = tmpi0 - tmpi1;
685 resulti = tmpi0 - atoi(tmps1);
687 resulti = atoi(tmps0) - tmpi1;
690 switch (curr->opcode) {
691 case OP_EQUALS: result = (resulti == 0);
break;
693 case OP_LT: result = (resulti < 0);
break;
694 case OP_LTEQ: result = (resulti <= 0);
break;
695 case OP_GT: result = (resulti > 0);
break;
696 case OP_GTEQ: result = (resulti >= 0);
break;
697 default: result =
FALSE;
713 var0 = ctx->variables[curr->var[0]];
716 switch (var0->
ctype) {
725 while (result && tmps2 && *tmps2 !=
'\0') {
726 gunichar uc = g_utf8_get_char(tmps2);
727 if (g_unichar_isspace(uc))
728 tmps2 = g_utf8_next_char(tmps2);
745 tuple_error(ctx,
"Unimplemented opcode %d!\n", curr->opcode);
751 g_string_append (out, str);
760 const Tuple * tuple, GString * out)
762 g_string_truncate (out, 0);