Add:Core:Support for FRA FRA NLS Setting
[navit-package] / navit / command.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdarg.h>
4 #include <stdlib.h>
5 #include <glib.h>
6 #include "item.h"
7 #include "xmlconfig.h"
8 #include "main.h"
9 #include "navit.h"
10 #include "vehicle.h"
11 #include "speech.h"
12 #include "gui.h"
13 #include "debug.h"
14 #include "callback.h"
15 #include "command.h"
16 #include "event.h"
17 #include "navit_nls.h"
18
19 /*
20 gui.fullscreen=!gui.fullscreen
21 gui.menu()
22 gui.get_data() 
23 zoom_in() 
24 zoom_out()
25 speech.active=!speech.active
26 osd_configuration=1
27 Not yet:
28 osd[type=="xxx"].active=0;osd[type=="yyy"].active=0
29 */
30
31
32 struct result {
33         struct attr attr;
34         double val;
35         char *var;
36         int varlen;
37         char *attrn;
38         int attrnlen;
39         int allocated;
40 };
41
42 struct context {
43         struct attr *attr;
44         int error;
45         char *expr;
46         struct result res;
47 };
48
49 struct command_saved_cb {
50         struct callback *cb;
51         struct attr attr;
52 };
53
54 struct command_saved {
55         struct context ctx;
56         struct result res;
57         char *command;                          // The command string itself
58         struct event_idle *idle_ev;             // Event to update this command
59         struct callback *idle_cb;
60         struct callback *register_cb;                   // Callback to register all the callbacks
61         struct event_idle *register_ev;         // Idle event to register all the callbacks
62         struct attr navit;
63         int num_cbs;
64         struct command_saved_cb *cbs;           // List of callbacks for this saved command
65         struct callback *cb; // Callback that should be called when we re-evaluate
66         int error;
67 };
68
69 enum error {
70         no_error=0,missing_closing_brace, missing_colon, wrong_type, illegal_number_format, illegal_character, missing_closing_bracket, invalid_type, not_ready
71 };
72
73 static void eval_comma(struct context *ctx, struct result *res);
74 static struct attr ** eval_list(struct context *ctx);
75
76 static void
77 result_free(struct result *res)
78 {
79 }
80
81 static int command_register_callbacks(struct command_saved *cs);
82
83 static char *
84 get_op(struct context *ctx, int test, ...)
85 {
86         char *op,*ret=NULL;
87         va_list ap;
88
89         while (g_ascii_isspace(*ctx->expr)) {
90                 ctx->expr++;
91         }
92
93         va_start(ap, test);
94         while ((op = va_arg(ap, char *))) {
95                 if (!strncmp(ctx->expr, op, strlen(op))) {
96                         ret=ctx->expr;
97                         if (! test)
98                                 ctx->expr+=strlen(op);
99                         break;
100                 }
101         }
102         va_end(ap);
103         return ret;
104 }
105
106 /*static int
107 is_int(struct result *res)
108 {
109         return 1;
110 }*/
111
112 static int
113 is_double(struct result *res)
114 {
115         return 0;
116 }
117
118 static void
119 dump(struct result *res)
120 {
121 #if 0
122         char object[res->varlen+1];
123         char attribute[res->attrnlen+1];
124         if (res->var)
125                 strncpy(object, res->var, res->varlen);
126         object[res->varlen]='\0';
127         if (res->attrn)
128                 strncpy(attribute, res->attrn, res->attrnlen);
129         attribute[res->attrnlen]='\0';
130         dbg(0,"type:%s\n", attr_to_name(res->attr.type));
131         dbg(0,"attribute '%s' from '%s'\n", attribute, object);
132 #endif
133 }
134
135 static enum attr_type
136 command_attr_type(struct result *res)
137 {
138         char attrn[res->attrnlen+1];
139
140         strncpy(attrn, res->attrn, res->attrnlen);
141         attrn[res->attrnlen]='\0';
142         return attr_from_name(attrn);
143 }
144
145 static int
146 command_object_get_attr(struct context *ctx, struct attr *object, enum attr_type attr_type, struct attr *ret)
147 {
148         struct object_func *func=object_func_lookup(object->type);
149         if (!func || !func->get_attr)
150                 return 0;
151         return func->get_attr(object->u.data, attr_type, ret, NULL);
152 }
153
154 static void
155 command_get_attr(struct context *ctx, struct result *res)
156 {
157         int result;
158         enum attr_type attr_type=command_attr_type(res);
159         result=command_object_get_attr(ctx, &res->attr, attr_type, &res->attr);
160         if (result) {
161                 res->var=res->attrn;
162                 res->varlen=res->attrnlen;
163         } else {
164                 res->attr.type=attr_none;
165                 res->var=NULL;
166                 res->varlen=0;
167         }
168         res->attrn=NULL;
169         res->attrnlen=0;
170         dump(res);
171 }
172
173 static void
174 command_set_attr(struct context *ctx, struct result *res, struct result *newres)
175 {
176         int result=0;
177         enum attr_type attr_type=command_attr_type(res);
178         struct object_func *func=object_func_lookup(res->attr.type);
179         if (!func || !func->set_attr)
180                 return;
181         newres->attr.type=attr_type;
182         result=func->set_attr(res->attr.u.data, &newres->attr);
183         *res=*newres;
184 }
185
186 static void
187 resolve_object(struct context *ctx, struct result *res)
188 {
189         if (res->attr.type == attr_none && res->varlen) {
190                 res->attr=*ctx->attr;
191                 res->attrn=res->var;
192                 res->attrnlen=res->varlen;
193                 res->var=NULL;
194                 res->varlen=0;
195         }
196 }
197
198 static void
199 resolve(struct context *ctx, struct result *res, struct attr *parent) //FIXME What is that parent for?
200 {
201         resolve_object(ctx, res);
202         if (res->attrn)
203                 command_get_attr(ctx, res);
204 }
205
206 static double
207 get_double(struct context *ctx, struct result *res)
208 {
209         resolve(ctx, res, NULL);
210         return res->val;
211 }
212
213
214
215 static int
216 get_int(struct context *ctx, struct result *res)
217 {
218         resolve(ctx, res, NULL);
219         if (res->attr.type == attr_none)
220                 return 0;
221         if (res->attr.type >= attr_type_int_begin && res->attr.type <= attr_type_int_end) {
222                 return res->attr.u.num;
223         }
224         if (res->attr.type >= attr_type_double_begin && res->attr.type <= attr_type_double_end) {
225                 return (int) (*res->attr.u.numd);
226         }
227         ctx->error=wrong_type;
228         return 0;
229 }
230
231
232 static char *
233 get_string(struct context *ctx, struct result *res)
234 {
235         resolve(ctx, res, NULL);
236         return attr_to_text(&res->attr, NULL, 0);
237 }
238
239 static void
240 set_double(struct context *ctx, struct result *res, double val)
241 {
242         result_free(res);
243         res->val=val;
244 }
245
246 static void
247 set_int(struct context *ctx, struct result *res, int val)
248 {
249         result_free(res);
250         res->attr.type=attr_type_int_begin;
251         res->attr.u.num=val;
252 }
253
254
255 static void
256 eval_value(struct context *ctx, struct result *res) {
257         char *op;
258         int len,dots=0;
259         op=ctx->expr;
260         res->varlen=0;
261         res->var=NULL;
262         res->attrnlen=0;
263         res->attrn=NULL;
264
265         while (g_ascii_isspace(*op)) {
266                 op++;
267         }
268
269         if ((op[0] >= 'a' && op[0] <= 'z') || op[0] == '_') {
270                 res->attr.type=attr_none;
271                 res->var=op;
272                 for (;;) {
273                         while ((op[0] >= 'a' && op[0] <= 'z') || op[0] == '_') {
274                                 res->varlen++;
275                                 op++;
276                         }
277                         if (res->varlen == 3 && !strncmp(res->var,"new",3) && op[0] == ' ') {
278                                 res->varlen++;
279                                 op++;
280                         } else
281                                 break;
282                 }
283                 ctx->expr=op;
284                 return;
285         }
286         if ((op[0] >= '0' && op[0] <= '9') ||
287             (op[0] == '.' && op[1] >= '0' && op[1] <= '9') ||
288             (op[0] == '-' && op[1] >= '0' && op[1] <= '9') ||
289             (op[0] == '-' && op[1] == '.' && op[2] >= '0' && op[2] <= '9')) {
290                 while ((op[0] >= '0' && op[0] <= '9') || op[0] == '.' || (res->varlen == 0 && op[0] == '-')) {
291                         if (op[0] == '.')
292                                 dots++;
293                         if (dots > 1) {
294                                 ctx->error=illegal_number_format;
295                                 return;
296                         }
297                         res->varlen++;
298                         op++;
299                 }
300                 if (dots) {
301                         res->val = strtod(ctx->expr, NULL);
302                         res->attr.type=attr_type_double_begin;
303                         res->attr.u.numd=&res->val;
304                 } else {
305                         res->attr.type=attr_type_int_begin;
306                         res->attr.u.num=atoi(ctx->expr);
307                 }
308                 ctx->expr=op;
309                 return;
310         }
311         if (op[0] == '"') {
312                 do {
313                         op++;
314                 } while (op[0] != '"');
315                 res->attr.type=attr_type_string_begin;
316                 len=op-ctx->expr-1;
317                 res->attr.u.str=g_malloc(len+1);
318                 strncpy(res->attr.u.str, ctx->expr+1, len);
319                 res->attr.u.str[len]='\0';
320                 op++;
321                 ctx->expr=op;
322                 return;
323         }
324         ctx->error=illegal_character;
325 }
326
327 static int
328 get_next_object(struct context *ctx, struct result *res) {
329         
330         while (*ctx->expr) {
331                 res->varlen = 0;
332                 ctx->error = 0;
333
334                 eval_value(ctx,res);
335                 
336                 if ((res->attr.type == attr_none) && (res->varlen > 0)) {
337                         if (ctx->expr[0] != '.') {
338                                 return 1;               // 1 means "this is the final object name"
339                         } else {
340                                 return 2;               // 2 means "there are more object names following" (e.g. we just hit 'vehicle' in 'vehicle.position_speed'
341                         }
342                 }
343
344                 if (ctx->error) {
345                         // Probably hit an operator
346                         ctx->expr++;
347                 }
348         }
349
350         return 0;
351 }
352
353 static void
354 eval_brace(struct context *ctx, struct result *res)
355 {
356         if (get_op(ctx,0,"(",NULL)) {
357                 eval_comma(ctx, res);
358                 if (ctx->error) return;
359                 if (!get_op(ctx,0,")",NULL)) 
360                         ctx->error=missing_closing_brace;
361                 return;
362         }
363         eval_value(ctx, res);
364 }
365
366 static void
367 command_call_function(struct context *ctx, struct result *res)
368 {
369         struct attr cbl,**list=NULL;
370         char function[res->attrnlen+1];
371         if (res->attrn)
372                 strncpy(function, res->attrn, res->attrnlen);
373         function[res->attrnlen]='\0';
374         dbg(1,"function=%s\n", function);
375         if (ctx->expr[0] != ')') {
376                 list=eval_list(ctx);    
377                 if (ctx->error) return;
378         }
379         if (!get_op(ctx,0,")",NULL)) {
380                 ctx->error=missing_closing_brace;
381                 return;
382         }
383         if (!strcmp(function,"_") && list && list[0] && list[0]->type >= attr_type_string_begin && list[0]->type <= attr_type_string_end) {
384                 res->attr.type=list[0]->type;
385                 res->attr.u.str=g_strdup(gettext(list[0]->u.str));      
386                 
387         } else if (!strncmp(function,"new ",4)) {
388                 enum attr_type attr_type=attr_from_name(function+4);
389                 if (attr_type != attr_none) {
390                         struct object_func *func=object_func_lookup(attr_type);
391                         if (func && func->new) {
392                                 res->attr.type=attr_type;
393                                 res->attr.u.data=func->new(NULL, list);
394                         }
395                 }
396         } else {
397                 if (command_object_get_attr(ctx, &res->attr, attr_callback_list, &cbl)) {
398                         int valid;
399                         struct attr **out=NULL;
400                         dbg(1,"function call %s from %s\n",function, attr_to_name(res->attr.type));
401                         callback_list_call_attr_4(cbl.u.callback_list, attr_command, function, list, &out, &valid);
402                         if (out && out[0]) {
403                                 attr_dup_content(out[0], &res->attr);
404                                 attr_list_free(out);
405                         } else
406                                 res->attr.type=attr_none;
407                 } else
408                         res->attr.type=attr_none;
409         }
410         res->var=NULL;
411         res->varlen=0;
412         res->attrn=NULL;
413         res->attrnlen=0;
414 }
415
416 static void
417 eval_postfix(struct context *ctx, struct result *res)
418 {
419         struct result tmp;
420         char *op;
421
422         eval_brace(ctx, res);
423         if (ctx->error) return;
424         for (;;) {
425                 if (!(op=get_op(ctx,0,"[","(",".",NULL)))
426                         return;
427                 if (op[0] == '.') {
428                         eval_brace(ctx, &tmp);
429                         if (ctx->error) return;
430                         resolve(ctx, res,NULL);
431                         if (ctx->error) return;
432                         res->attrn=tmp.var;
433                         res->attrnlen=tmp.varlen;
434                         dump(res);
435                 } else if (op[0] == '[') {
436                         if (!get_op(ctx,0,"]",NULL)) {
437                                 ctx->error=missing_closing_bracket;
438                                 return;
439                         }
440                 } else if (op[0] == '(') {
441                         dbg(1,"function call\n");
442                         resolve_object(ctx, res);
443                         command_call_function(ctx, res);
444                 }
445         }
446 }
447
448 static void
449 eval_unary(struct context *ctx, struct result *res) 
450 {
451         char *op;
452         op=get_op(ctx,0,"~","!",NULL);
453         if (op) {
454                 eval_unary(ctx, res);
455                 if (ctx->error) return;
456                 if (op[0] == '~')
457                         set_int(ctx, res, ~get_int(ctx, res));
458                 else
459                         set_int(ctx, res, !get_int(ctx, res));
460         } else
461                 eval_postfix(ctx, res);
462 }
463
464 static void
465 eval_multiplicative(struct context *ctx, struct result *res) 
466 {
467         struct result tmp;
468         char *op;
469
470         eval_unary(ctx, res);
471         if (ctx->error) return;
472         for (;;) {
473                 if (!(op=get_op(ctx,0,"*","/","%",NULL))) return;
474                 eval_unary(ctx, &tmp);
475                 if (ctx->error) return;
476                 if (is_double(res) || is_double(&tmp)) {
477                         if (op[0] == '*')
478                                 set_double(ctx, res, get_double(ctx, res) * get_double(ctx, &tmp));
479                         else if (op[0] == '/')
480                                 set_double(ctx, res, get_double(ctx, res) / get_double(ctx, &tmp));
481                         else {
482                                 ctx->error=invalid_type;
483                                 return;
484                         }
485                 } else {
486                         if (op[0] == '*')
487                                 set_int(ctx, res, get_int(ctx, res) * get_int(ctx, &tmp));
488                         else if (op[0] == '/')
489                                 set_int(ctx, res, get_int(ctx, res) / get_int(ctx, &tmp));
490                         else
491                                 set_int(ctx, res, get_int(ctx, res) % get_int(ctx, &tmp));
492                 }
493                 if (ctx->error) return;
494         }
495 }
496
497 static void
498 eval_additive(struct context *ctx, struct result *res) 
499 {
500         struct result tmp;
501         char *op;
502
503         eval_multiplicative(ctx, res);
504         if (ctx->error) return;
505         for (;;) {
506                 if (!(op=get_op(ctx,0,"-","+",NULL))) return;
507                 eval_multiplicative(ctx, &tmp);
508                 if (ctx->error) return;
509                 if (is_double(res) || is_double(&tmp)) {
510                         if (op[0] == '+')
511                                 set_double(ctx, res, get_double(ctx, res) + get_double(ctx, &tmp));
512                         else
513                                 set_double(ctx, res, get_double(ctx, res) - get_double(ctx, &tmp));
514                 } else {
515                         if (op[0] == '+')
516                                 set_int(ctx, res, get_int(ctx, res) + get_int(ctx, &tmp));
517                         else
518                                 set_int(ctx, res, get_int(ctx, res) - get_int(ctx, &tmp));
519                 }
520                 if (ctx->error) return;
521         }
522 }
523
524 static void
525 eval_equality(struct context *ctx, struct result *res) 
526 {
527         struct result tmp;
528         char *op;
529
530         eval_additive(ctx, res);
531         if (ctx->error) return;
532         for (;;) {
533                 if (!(op=get_op(ctx,0,"==","!=","<=",">=","<",">",NULL))) return;
534                 eval_additive(ctx, &tmp);
535                 if (ctx->error) return;
536
537                 switch (op[0]) {
538                 case '=':
539                         set_int(ctx, res, (get_int(ctx, res) == get_int(ctx, &tmp)));
540                         break;
541                 case '!':
542                         set_int(ctx, res, (get_int(ctx, res) != get_int(ctx, &tmp)));
543                         break;
544                 case '<':
545                         if (op[1] == '=') {
546                                 set_int(ctx, res, (get_int(ctx, res) <= get_int(ctx, &tmp)));
547                         } else {
548                                 set_int(ctx, res, (get_int(ctx, res) < get_int(ctx, &tmp)));
549                         }
550                         break;
551                 case '>':
552                         if (op[1] == '=') {
553                                 set_int(ctx, res, (get_int(ctx, res) >= get_int(ctx, &tmp)));
554                         } else {
555                                 set_int(ctx, res, (get_int(ctx, res) > get_int(ctx, &tmp)));
556                         }
557                         break;
558                 default:
559                         break;
560                 }
561                 result_free(&tmp);
562         }
563 }
564
565
566 static void
567 eval_bitwise_and(struct context *ctx, struct result *res) 
568 {
569         struct result tmp;
570
571         eval_equality(ctx, res);
572         if (ctx->error) return;
573         for (;;) {
574                 if (get_op(ctx,1,"&&",NULL)) return;
575                 if (!get_op(ctx,0,"&",NULL)) return;
576                 eval_equality(ctx, &tmp);
577                 if (ctx->error) return;
578                 set_int(ctx, res, get_int(ctx, res) & get_int(ctx, &tmp));
579                 if (ctx->error) return;
580         }
581 }
582
583 static void
584 eval_bitwise_xor(struct context *ctx, struct result *res) 
585 {
586         struct result tmp;
587
588         eval_bitwise_and(ctx, res);
589         if (ctx->error) return;
590         for (;;) {
591                 if (!get_op(ctx,0,"^",NULL)) return;
592                 eval_bitwise_and(ctx, &tmp);
593                 if (ctx->error) return;
594                 set_int(ctx, res, get_int(ctx, res) ^ get_int(ctx, &tmp));
595                 if (ctx->error) return;
596         }
597 }
598
599 static void
600 eval_bitwise_or(struct context *ctx, struct result *res) 
601 {
602         struct result tmp;
603
604         eval_bitwise_xor(ctx, res);
605         if (ctx->error) return;
606         for (;;) {
607                 if (get_op(ctx,1,"||",NULL)) return;
608                 if (!get_op(ctx,0,"|",NULL)) return;
609                 eval_bitwise_xor(ctx, &tmp);
610                 if (ctx->error) return;
611                 set_int(ctx, res, get_int(ctx, res) | get_int(ctx, &tmp));
612                 if (ctx->error) return;
613         }
614 }
615
616 static void
617 eval_logical_and(struct context *ctx, struct result *res) 
618 {
619         struct result tmp;
620
621         eval_bitwise_or(ctx, res);
622         if (ctx->error) return;
623         for (;;) {
624                 if (!get_op(ctx,0,"&&",NULL)) return;
625                 eval_bitwise_or(ctx, &tmp);
626                 if (ctx->error) return;
627                 set_int(ctx, res, get_int(ctx, res) && get_int(ctx, &tmp));
628                 if (ctx->error) return;
629         }
630 }
631
632 static void
633 eval_logical_or(struct context *ctx, struct result *res) 
634 {
635         struct result tmp;
636
637         eval_logical_and(ctx, res);
638         if (ctx->error) return;
639         for (;;) {
640                 if (!get_op(ctx,0,"||",NULL)) return;
641                 eval_logical_and(ctx, &tmp);
642                 if (ctx->error) return;
643                 set_int(ctx, res, get_int(ctx, res) || get_int(ctx, &tmp));
644                 if (ctx->error) return;
645         }
646 }
647
648 static void
649 eval_conditional(struct context *ctx, struct result *res)
650 {
651         struct result tmp;
652         int cond;
653
654         eval_logical_or(ctx, res);
655         if (ctx->error) return;
656         if (!get_op(ctx,0,"?",NULL)) return;
657         cond=!!get_int(ctx, res);
658         if (ctx->error) return;
659         eval_logical_or(ctx, &tmp);
660         if (ctx->error) return;
661         if (cond)
662                 *res=tmp;
663         if (!get_op(ctx,0,":",NULL)) {
664                 ctx->error=missing_colon;
665                 return;
666         }
667         eval_logical_or(ctx, &tmp);
668         if (ctx->error) return;
669         if (!cond)
670                 *res=tmp;
671 }
672
673 /* = *= /= %= += -= >>= <<= &= ^= |= */
674
675 static void
676 eval_assignment(struct context *ctx, struct result *res)
677 {
678         struct result tmp;
679         eval_conditional(ctx, res);
680         if (ctx->error) return;
681         if (!get_op(ctx,0,"=",NULL)) return;
682         eval_conditional(ctx, &tmp);
683         if (ctx->error) return;
684         resolve(ctx, &tmp, NULL);
685         if (ctx->error) return;
686         resolve_object(ctx, res);
687         command_set_attr(ctx, res, &tmp);
688 }
689
690 /* , */
691 static void
692 eval_comma(struct context *ctx, struct result *res)
693 {
694         struct result tmp;
695
696         eval_assignment(ctx, res);
697         if (ctx->error) return;
698         for (;;) {
699                 if (!get_op(ctx,0,",",NULL)) return;
700                 eval_assignment(ctx, &tmp);
701                 if (ctx->error) return;
702                 *res=tmp;
703         }
704 }
705
706 static struct attr **
707 eval_list(struct context *ctx)
708 {
709         struct result tmp;
710
711         struct attr **ret=NULL;
712         for (;;) {
713                 eval_assignment(ctx, &tmp);
714                 if (ctx->error) {
715                         attr_list_free(ret);
716                         return NULL;
717                 }
718                 resolve(ctx, &tmp, NULL);
719                 ret=attr_generic_add_attr(ret, &tmp.attr);
720                 if (!get_op(ctx,0,",",NULL)) return ret;
721         }
722 }
723
724 #if 0
725
726 void command(struct attr *attr, char *expr)
727 {
728         struct result res;
729         struct context ctx;
730         memset(&res, 0, sizeof(res));
731         memset(&ctx, 0, sizeof(ctx));
732         ctx.attr=attr;
733         ctx.error=0;
734         ctx.expr=expr;
735         printf("command='%s'\n", expr);
736         eval_comma(&ctx,&res);
737         printf("err=%d %s\n", ctx.error, ctx.expr);
738         dump(&res);
739         printf("***\n");
740         resolve(&ctx, &res, NULL);
741         dump(&res);
742         printf("%s\n", get_string(&ctx, &res));
743 }
744 #endif
745
746 static void
747 command_evaluate_to(struct attr *attr, char *expr, struct context *ctx, struct result *res)
748 {
749         memset(res, 0, sizeof(*res));
750         memset(ctx, 0, sizeof(*ctx));
751         ctx->attr=attr;
752         ctx->expr=expr;
753         eval_comma(ctx,res);
754 }
755
756 void
757 command_evaluate_to_void(struct attr *attr, char *expr, int **error)
758 {
759         struct result res;
760         struct context ctx;
761         command_evaluate_to(attr, expr, &ctx, &res);
762         if (!ctx.error)
763                 resolve(&ctx, &res, NULL);
764         if (error)
765                 *error=&ctx.error;
766
767 }
768
769 char *
770 command_evaluate_to_string(struct attr *attr, char *expr, int **error)
771 {
772         struct result res;
773         struct context ctx;
774         char *ret=NULL;
775
776         command_evaluate_to(attr, expr, &ctx, &res);
777         if (!ctx.error)
778                 resolve(&ctx, &res, NULL);
779         if (!ctx.error)
780                 ret=get_string(&ctx, &res);
781         if (error)
782                 *error=&ctx.error;
783         if (ctx.error)
784                 return NULL;
785         else
786                 return ret;
787 }
788
789 int
790 command_evaluate_to_int(struct attr *attr, char *expr, int **error)
791 {
792         struct result res;
793         struct context ctx;
794         int ret=0;
795
796         command_evaluate_to(attr, expr, &ctx, &res);
797         if (!ctx.error)
798                 resolve(&ctx, &res, NULL);
799         if (!ctx.error)
800                 ret=get_int(&ctx, &res);
801         if (error)
802                 *error=&ctx.error;
803         if (ctx.error)
804                 return 0;
805         else
806                 return ret;
807 }
808
809 int
810 command_evaluate_to_boolean(struct attr *attr, char *expr, int **error)
811 {
812         struct result res;
813         struct context ctx;
814         int ret=0;
815
816         command_evaluate_to(attr, expr, &ctx, &res);
817         if (!ctx.error)
818                 resolve(&ctx, &res, NULL);
819         if (!ctx.error) {
820                 if (res.attr.type == attr_none)
821                         ret=0;
822                 else if ((res.attr.type >= attr_type_int_begin && res.attr.type <= attr_type_int_end) ||
823                          (res.attr.type >= attr_type_double_begin && res.attr.type <= attr_type_double_end))
824                         ret=get_int(&ctx, &res);
825                 else 
826                         ret=res.attr.u.data != NULL;
827         }
828         if (error)
829                 *error=&ctx.error;
830         if (ctx.error)
831                 return 0;
832         else    
833                 return ret;
834 }
835
836 void
837 command_evaluate(struct attr *attr, char *expr)
838 {
839         struct result res;
840         struct context ctx;
841         memset(&res, 0, sizeof(res));
842         memset(&ctx, 0, sizeof(ctx));
843         ctx.attr=attr;
844         ctx.error=0;
845         ctx.expr=expr;
846         for (;;) {
847                 eval_comma(&ctx,&res);
848                 if (ctx.error)
849                         return;
850                 resolve(&ctx, &res, NULL);
851                 if (ctx.error)
852                         return;
853                 if (!get_op(&ctx,0,";",NULL)) return;
854         }
855 }
856
857 #if 0
858 void
859 command_interpreter(struct attr *attr)
860 {
861                 char buffer[4096];
862                 int size;
863                 for (;;) {
864                 size=read(0, buffer, 4095);
865                 buffer[size]='\0';
866                 if (size) {
867                         buffer[size-1]='\0';
868                 }
869                 command(attr, buffer);
870                 }
871 }
872 #endif
873
874 static void
875 command_table_call(struct command_table *table, int count, void *data, char *command, struct attr **in, struct attr ***out, int *valid)
876 {
877         int i;
878         for (i = 0 ; i < count ; i++) {
879                 if (!strcmp(command,table->command)) {
880                         if (valid)
881                                 *valid=1;
882                         table->func(data, command, in, out);
883                 }
884                 table++;
885         }
886 }
887
888 void
889 command_add_table_attr(struct command_table *table, int count, void *data, struct attr *attr)
890 {
891         attr->type=attr_callback;
892         attr->u.callback=callback_new_attr_3(callback_cast(command_table_call),attr_command, table, count, data);
893 }
894
895 void
896 command_add_table(struct callback_list *cbl, struct command_table *table, int count, void *data)
897 {
898         struct attr attr;
899         command_add_table_attr(table, count, data, &attr);
900         callback_list_add(cbl, attr.u.callback);
901 }
902
903 void
904 command_saved_set_cb (struct command_saved *cs, struct callback *cb)
905 {
906         cs->cb = cb;
907 }
908
909 int
910 command_saved_get_int (struct command_saved *cs)
911 {
912         return get_int(&cs->ctx, &cs->res);
913 }
914
915 int 
916 command_saved_error (struct command_saved *cs)
917 {
918         return cs->error;
919 }
920
921 static void
922 command_saved_evaluate_idle (struct command_saved *cs) 
923 {
924         // Only run once at a time
925         if (cs->idle_ev) {
926                 event_remove_idle(cs->idle_ev);
927                 cs->idle_ev = NULL;
928         }
929
930         command_evaluate_to(&cs->navit, cs->command, &cs->ctx, &cs->res);
931
932         if (!cs->ctx.error) {
933                 cs->error = 0;
934
935                 if (cs->cb) {
936                         callback_call_1(cs->cb, cs);
937                 }
938         } else {
939                 cs->error = cs->ctx.error;
940         }
941 }
942
943 static void
944 command_saved_evaluate(struct command_saved *cs)
945 {       
946         if (cs->idle_ev) {
947                 // We're already scheduled for reevaluation
948                 return;
949         }
950
951         if (!cs->idle_cb) {
952                 cs->idle_cb = callback_new_1(callback_cast(command_saved_evaluate_idle), cs);
953         }
954
955         cs->idle_ev = event_add_idle(100, cs->idle_cb);
956 }
957
958 static void
959 command_saved_callbacks_changed(struct command_saved *cs)
960 {
961         // For now, we delete each and every callback and then re-create them
962         int i;
963         struct object_func *func;
964         struct attr attr;
965
966         if (cs->register_ev) {
967                 event_remove_idle(cs->register_ev);
968                 cs->register_ev = NULL;
969         }
970
971         attr.type = attr_callback;
972
973         for (i = 0; i < cs->num_cbs; i++) {
974                 func = object_func_lookup(cs->cbs[i].attr.type);
975                 
976                 if (!func->remove_attr) {
977                         dbg(0, "Could not remove command-evaluation callback because remove_attr is missing for type %i!\n", cs->cbs[i].attr.type);
978                         continue;
979                 }
980
981                 attr.u.callback = cs->cbs[i].cb;
982
983                 func->remove_attr(cs->cbs[i].attr.u.data, &attr);
984                 callback_destroy(cs->cbs[i].cb);
985         }
986
987         g_free(cs->cbs);
988         cs->cbs = NULL;
989         cs->num_cbs = 0;
990
991         // Now, re-create all the callbacks
992         command_register_callbacks(cs);
993 }
994
995 static int
996 command_register_callbacks(struct command_saved *cs)
997 {
998         struct attr prev,cb_attr,attr;
999         int status;
1000         struct object_func *func;
1001         struct callback *cb;
1002         
1003         attr = cs->navit;
1004         cs->ctx.expr = cs->command;
1005         cs->ctx.attr = &attr;
1006         prev = cs->navit;       
1007
1008         while ((status = get_next_object(&cs->ctx, &cs->res)) != 0) {
1009                 resolve(&cs->ctx, &cs->res, NULL);
1010
1011                 if (cs->ctx.error || (cs->res.attr.type == attr_none)) {
1012                         // We could not resolve an object, perhaps because it has not been created
1013                         return 0;
1014                 }
1015
1016                 if (prev.type != attr_none) {
1017                         func = object_func_lookup(prev.type);
1018
1019                         if (func->add_attr) {
1020                                 if (status == 2) { // This is not the final attribute name
1021                                         cb = callback_new_attr_1(callback_cast(command_saved_callbacks_changed), cs->res.attr.type, (void*)cs);
1022                                         attr = cs->res.attr;
1023                                 } else if (status == 1) { // This is the final attribute name
1024                                         cb = callback_new_attr_1(callback_cast(command_saved_evaluate), cs->res.attr.type, (void*)cs);
1025                                         cs->ctx.attr = &cs->navit;
1026                                 } else {
1027                                         dbg(0, "Error: Strange status returned from get_next_object()\n");
1028                                 }
1029
1030                                 cs->num_cbs++;
1031                                 cs->cbs = g_realloc(cs->cbs, (sizeof(struct command_saved_cb) * cs->num_cbs));
1032                                 cs->cbs[cs->num_cbs-1].cb = cb;
1033                                 cs->cbs[cs->num_cbs-1].attr = prev;
1034                                         
1035                                 cb_attr.u.callback = cb;
1036                                 cb_attr.type = attr_callback;
1037
1038                                 func->add_attr(prev.u.data, &cb_attr);
1039
1040                         } else {
1041                                 dbg(0, "Could not add callback because add_attr is missing for type %i}n", prev.type);
1042                         }
1043                 }
1044
1045                 if (status == 2) {
1046                         prev = cs->res.attr;
1047                 } else {
1048                         prev = cs->navit;
1049                 }
1050         }
1051
1052         command_saved_evaluate_idle(cs);
1053
1054         return 1;
1055 }
1056
1057 struct command_saved
1058 *command_saved_new(char *command, struct navit *navit, struct callback *cb)
1059 {
1060         struct command_saved *ret;
1061
1062         ret = g_new0(struct command_saved, 1);
1063         ret->command = g_strdup(command);
1064         ret->navit.u.navit = navit;
1065         ret->navit.type = attr_navit;
1066         ret->cb = cb;
1067         ret->error = not_ready;
1068
1069         if (!command_register_callbacks(ret)) {
1070                 // We try this as an idle call again
1071                 ret->register_cb = callback_new_1(callback_cast(command_saved_callbacks_changed), ret);
1072                 ret->register_ev = event_add_idle(300, ret->register_cb);
1073         }               
1074
1075         return ret;
1076 }
1077
1078 void 
1079 command_saved_destroy(struct command_saved *cs)
1080 {
1081         g_free(cs->command);
1082         g_free(cs);
1083 }