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,
char **expression);
228 char **str,
char *buf, gssize max,
229 char endch,
bool_t *literal,
char *errstr,
char *item)
232 char *
s = *str, tmpendch;
235 if (*literal ==
FALSE) {
236 tuple_error(ctx,
"Literal string value not allowed in '%s'.\n", item);
247 if (*literal ==
FALSE) {
248 while (*s !=
'\0' && *s != tmpendch && (isalnum(*s) || *s ==
'-') && i < (max - 1)) {
252 if (*s != tmpendch && *s !=
'}' && !isalnum(*s) && *s !=
'-') {
253 tuple_error(ctx,
"Invalid field '%s' in '%s'.\n", *str, item);
255 }
else if (*s != tmpendch) {
256 tuple_error(ctx,
"Expected '%c' in '%s'.\n", tmpendch, item);
260 while (*s !=
'\0' && *s != tmpendch && i < (max - 1)) {
271 tuple_error(ctx,
"Expected literal string end ('%c') in '%s'.\n", tmpendch, item);
277 tuple_error(ctx,
"Expected '%c' after %s in '%s'\n", endch, errstr, item);
291 if (name ==
'\0')
return -1;
293 if (isdigit(name[0])) {
300 for (i = 0; i < ctx->nvariables; i++)
301 if (ctx->variables[i] && !strcmp(ctx->variables[i]->name, name))
321 tmp->opcode = opcode;
324 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, item);
329 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps2, item);
349 TupleEvalNode *res =
NULL, *tmp =
NULL;
350 char *c = *expression, *item, tmps1[
MAX_STR];
355 while (*c !=
'\0' && !end) {
361 }
else if (*c ==
'$') {
377 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, expr);
395 }
else if (isdigit(*c)) {
399 tuple_error(ctx,
"Definitions are not yet supported!\n");
411 if (*c !=
'=')
goto ext_expression;
439 if (!strncmp(c,
"empty)?", 7)) {
447 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, expr);
470 tuple_error(ctx,
"Invalid variable '%s' in '%s'.\n", tmps1, expr);
480 tuple_error(ctx,
"Expected '{', got '%c' in '%s'.\n", *c, c);
484 }
else if (*c ==
'%') {
491 while (*c !=
'\0' && (isalnum(*c) || *c ==
'-') && *c !=
'}' && *c !=
':' && i < (
MAX_STR - 1))
497 }
else if (*c ==
'}') {
499 }
else if (*c ==
'\0') {
500 tuple_error(ctx,
"Expected '}' or function arguments in '%s'\n", item);
504 tuple_error(ctx,
"Expected '{', got '%c' in '%s'.\n", *c, c);
510 while (*c !=
'\0' && *c !=
'$' && *c !=
'%' && *c !=
'}' && i < (
MAX_STR - 1)) {
518 tmp->text = g_strdup(tmps1);
524 tuple_error(ctx,
"Syntax error! Uneven/unmatched nesting of elements in '%s'!\n", c);
541 char *tmpexpr = expr;
547 tuple_error(ctx,
"Syntax error! Uneven/unmatched nesting of elements! (%d)\n", level);
586 var,
const Tuple * tuple)
594 switch (var->
ctype) {
621 expr,
const Tuple * tuple, GString * out)
623 TupleEvalNode *curr = expr;
627 char tmps[
MAX_STR], *tmps0, *tmps1, *tmps2;
631 if (!expr)
return FALSE;
634 const char *str =
NULL;
636 switch (curr->opcode) {
642 var0 = ctx->variables[curr->var[0]];
644 switch (var0->
type) {
647 switch (var0->
ctype) {
653 g_snprintf (tmps,
sizeof (tmps),
"%d", var0->
defvali);
669 var0 = ctx->variables[curr->var[0]];
670 var1 = ctx->variables[curr->var[1]];
672 type0 =
tf_get_var(&tmps0, &tmpi0, var0, tuple);
673 type1 =
tf_get_var(&tmps1, &tmpi1, var1, tuple);
677 if (type0 == type1) {
679 resulti = strcmp(tmps0, tmps1);
681 resulti = tmpi0 - tmpi1;
684 resulti = tmpi0 - atoi(tmps1);
686 resulti = atoi(tmps0) - tmpi1;
689 switch (curr->opcode) {
690 case OP_EQUALS: result = (resulti == 0);
break;
692 case OP_LT: result = (resulti < 0);
break;
693 case OP_LTEQ: result = (resulti <= 0);
break;
694 case OP_GT: result = (resulti > 0);
break;
695 case OP_GTEQ: result = (resulti >= 0);
break;
696 default: result =
FALSE;
712 var0 = ctx->variables[curr->var[0]];
715 switch (var0->
ctype) {
724 while (result && tmps2 && *tmps2 !=
'\0') {
725 gunichar uc = g_utf8_get_char(tmps2);
726 if (g_unichar_isspace(uc))
727 tmps2 = g_utf8_next_char(tmps2);
744 tuple_error(ctx,
"Unimplemented opcode %d!\n", curr->opcode);
750 g_string_append (out, str);
759 const Tuple * tuple, GString * out)
761 g_string_truncate (out, 0);
struct _TupleEvalNode * prev
struct _TupleEvalNode * next
struct _TupleEvalNode * children
static bool_t tc_parse_construct(TupleEvalContext *ctx, TupleEvalNode **res, char *item, char **c, int *level, int opcode)
static TupleValueType tf_get_var(char **tmps, int *tmpi, TupleEvalVar *var, const Tuple *tuple)
static int tc_get_variable(TupleEvalContext *ctx, char *name, int type)
static void tuple_evalnode_insert(TupleEvalNode **nodes, TupleEvalNode *node)
static bool_t tf_get_fieldval(TupleEvalVar *var, const Tuple *tuple)
EXPORT int tuple_field_by_name(const char *name)
static TupleEvalNode * tuple_compiler_pass1(int *level, TupleEvalContext *ctx, char **expression)
void tuple_evalctx_reset(TupleEvalContext *ctx)
EXPORT TupleValueType tuple_field_get_type(int field)
void tuple_evalnode_free(TupleEvalNode *expr)
void str_unref(char *str)
static TupleEvalNode * tuple_evalnode_new(void)
TupleEvalContext * tuple_evalctx_new(void)
#define tuple_error(ctx,...)
void tuple_formatter_eval(TupleEvalContext *ctx, TupleEvalNode *expr, const Tuple *tuple, GString *out)
EXPORT char * tuple_get_str(const Tuple *tuple, int nfield, const char *field)
static int tuple_evalctx_add_var(TupleEvalContext *ctx, const char *name, const int type, const TupleValueType ctype)
EXPORT TupleValueType tuple_get_value_type(const Tuple *tuple, int nfield, const char *field)
Returns TupleValueType of given #Tuple field.
static bool_t tuple_formatter_eval_do(TupleEvalContext *ctx, TupleEvalNode *expr, const Tuple *tuple, GString *out)
TupleEvalNode * tuple_formatter_compile(TupleEvalContext *ctx, char *expr)
TupleEvalVar ** variables
void tuple_evalctx_free(TupleEvalContext *ctx)
static void tuple_evalctx_free_var(TupleEvalVar *var)
static bool_t tc_get_item(TupleEvalContext *ctx, char **str, char *buf, gssize max, char endch, bool_t *literal, char *errstr, char *item)
EXPORT int tuple_get_int(const Tuple *tuple, int nfield, const char *field)
Returns integer associated to #Tuple field.