45 #define MIN_ALLOC_NODES (8)
46 #define MIN_ALLOC_BUF (64)
47 #define TUPLEZ_MAX_VARS (4)
49 #define tuple_error(ctx, ...) fprintf (stderr, "Tuple compiler: " __VA_ARGS__)
105 return g_new0(TupleEvalContext, 1);
115 for (i = 0; i < ctx->nvariables; i++)
116 if (ctx->variables[i]) {
117 ctx->variables[i]->fieldread =
FALSE;
118 ctx->variables[i]->fieldvalid =
FALSE;
120 ctx->variables[i]->fieldstr =
NULL;
134 for (i = 0; i < ctx->nvariables; i++)
135 if (ctx->variables[i])
138 g_free(ctx->variables);
149 tmp->
name = g_strdup(name);
168 for (i = 0; i < ctx->nvariables; i++)
169 if (!ctx->variables[i]) {
170 ctx->variables[i] = tmp;
178 ctx->variables[i] = tmp;
187 node->prev = (*nodes)->prev;
188 (*nodes)->prev->next = node;
189 (*nodes)->prev = node;
201 return g_new0(TupleEvalNode, 1);
207 TupleEvalNode *curr = expr, *next;
224 static TupleEvalNode *
tuple_compiler_pass1(
int *level, TupleEvalContext *ctx,
const char **expression);
228 const char **str,
char *buf, gssize max,
229 char endch,
bool_t *literal,
char *errstr,
const char *item)
232 const char *
s = *str;
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))
311 const char *item,
const char **c,
int *level,
int opcode)
323 tmp->opcode = opcode;
326 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, item);
331 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps2, item);
351 TupleEvalNode *res =
NULL, *tmp =
NULL;
352 const char *c = *expression, *item;
358 while (*c !=
'\0' && !end) {
364 }
else if (*c ==
'$') {
369 const char *expr = ++c;
380 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, expr);
398 }
else if (isdigit(*c)) {
402 tuple_error(ctx,
"Definitions are not yet supported!\n");
414 if (*c !=
'=')
goto ext_expression;
442 if (!strncmp(c,
"empty)?", 7)) {
450 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, expr);
473 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, expr);
483 tuple_error(ctx,
"Expected '{', got '%c' in '%s'.\n", *c, c);
487 }
else if (*c ==
'%') {
494 while (*c !=
'\0' && (isalnum(*c) || *c ==
'-') && *c !=
'}' && *c !=
':' && i < (
MAX_STR - 1))
500 }
else if (*c ==
'}') {
502 }
else if (*c ==
'\0') {
503 tuple_error(ctx,
"Expected '}' or function arguments in '%s'\n", item);
507 tuple_error(ctx,
"Expected '{', got '%c' in '%s'.\n", *c, c);
513 while (*c !=
'\0' && *c !=
'$' && *c !=
'%' && *c !=
'}' && i < (
MAX_STR - 1)) {
521 tmp->text = g_strdup(tmps1);
527 tuple_error(ctx,
"Syntax error! Uneven/unmatched nesting of elements in '%s'!\n", c);
544 const char *tmpexpr = expr;
550 tuple_error(ctx,
"Syntax error! Uneven/unmatched nesting of elements! (%d)\n", level);
589 var,
const Tuple * tuple)
597 switch (var->
ctype) {
624 expr,
const Tuple * tuple, GString * out)
626 TupleEvalNode *curr = expr;
630 char tmps[
MAX_STR], *tmps0, *tmps1, *tmps2;
634 if (!expr)
return FALSE;
637 const char *str =
NULL;
639 switch (curr->opcode) {
645 var0 = ctx->variables[curr->var[0]];
647 switch (var0->
type) {
650 switch (var0->
ctype) {
656 g_snprintf (tmps,
sizeof (tmps),
"%d", var0->
defvali);
672 var0 = ctx->variables[curr->var[0]];
673 var1 = ctx->variables[curr->var[1]];
675 type0 =
tf_get_var(&tmps0, &tmpi0, var0, tuple);
676 type1 =
tf_get_var(&tmps1, &tmpi1, var1, tuple);
680 if (type0 == type1) {
682 resulti = strcmp(tmps0, tmps1);
684 resulti = tmpi0 - tmpi1;
687 resulti = tmpi0 - atoi(tmps1);
689 resulti = atoi(tmps0) - tmpi1;
692 switch (curr->opcode) {
693 case OP_EQUALS: result = (resulti == 0);
break;
695 case OP_LT: result = (resulti < 0);
break;
696 case OP_LTEQ: result = (resulti <= 0);
break;
697 case OP_GT: result = (resulti > 0);
break;
698 case OP_GTEQ: result = (resulti >= 0);
break;
699 default: result =
FALSE;
715 var0 = ctx->variables[curr->var[0]];
718 switch (var0->
ctype) {
727 while (result && tmps2 && *tmps2 !=
'\0') {
728 gunichar uc = g_utf8_get_char(tmps2);
729 if (g_unichar_isspace(uc))
730 tmps2 = g_utf8_next_char(tmps2);
747 tuple_error(ctx,
"Unimplemented opcode %d!\n", curr->opcode);
753 g_string_append (out, str);
762 const Tuple * tuple, GString * out)
764 g_string_truncate (out, 0);