Fix:Core:Avoid dragging the map from/to illegal positions
[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()
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                 while ((op[0] >= 'a' && op[0] <= 'z') || op[0] == '_') {
273                         res->varlen++;
274                         op++;
275                 }
276                 ctx->expr=op;
277                 return;
278         }
279         if ((op[0] >= '0' && op[0] <= '9') ||
280             (op[0] == '.' && op[1] >= '0' && op[1] <= '9') ||
281             (op[0] == '-' && op[1] >= '0' && op[1] <= '9') ||
282             (op[0] == '-' && op[1] == '.' && op[2] >= '0' && op[2] <= '9')) {
283                 while ((op[0] >= '0' && op[0] <= '9') || op[0] == '.' || (res->varlen == 0 && op[0] == '-')) {
284                         if (op[0] == '.')
285                                 dots++;
286                         if (dots > 1) {
287                                 ctx->error=illegal_number_format;
288                                 return;
289                         }
290                         res->varlen++;
291                         op++;
292                 }
293                 if (dots) {
294                         res->val = strtod(ctx->expr, NULL);
295                         res->attr.type=attr_type_double_begin;
296                         res->attr.u.numd=&res->val;
297                 } else {
298                         res->attr.type=attr_type_int_begin;
299                         res->attr.u.num=atoi(ctx->expr);
300                 }
301                 ctx->expr=op;
302                 return;
303         }
304         if (op[0] == '"') {
305                 do {
306                         op++;
307                 } while (op[0] != '"');
308                 res->attr.type=attr_type_string_begin;
309                 len=op-ctx->expr-1;
310                 res->attr.u.str=g_malloc(len+1);
311                 strncpy(res->attr.u.str, ctx->expr+1, len);
312                 res->attr.u.str[len]='\0';
313                 op++;
314                 ctx->expr=op;
315                 return;
316         }
317         ctx->error=illegal_character;
318 }
319
320 static int
321 get_next_object(struct context *ctx, struct result *res) {
322         
323         while (*ctx->expr) {
324                 res->varlen = 0;
325                 ctx->error = 0;
326
327                 eval_value(ctx,res);
328                 
329                 if ((res->attr.type == attr_none) && (res->varlen > 0)) {
330                         if (ctx->expr[0] != '.') {
331                                 return 1;               // 1 means "this is the final object name"
332                         } else {
333                                 return 2;               // 2 means "there are more object names following" (e.g. we just hit 'vehicle' in 'vehicle.position_speed'
334                         }
335                 }
336
337                 if (ctx->error) {
338                         // Probably hit an operator
339                         ctx->expr++;
340                 }
341         }
342
343         return 0;
344 }
345
346 static void
347 eval_brace(struct context *ctx, struct result *res)
348 {
349         if (get_op(ctx,0,"(",NULL)) {
350                 eval_comma(ctx, res);
351                 if (ctx->error) return;
352                 if (!get_op(ctx,0,")",NULL)) 
353                         ctx->error=missing_closing_brace;
354                 return;
355         }
356         eval_value(ctx, res);
357 }
358
359 static void
360 command_call_function(struct context *ctx, struct result *res)
361 {
362         struct attr cbl,**list=NULL;
363         char function[res->attrnlen+1];
364         if (res->attrn)
365                 strncpy(function, res->attrn, res->attrnlen);
366         function[res->attrnlen]='\0';
367         dbg(1,"function=%s\n", function);
368         if (ctx->expr[0] != ')') {
369                 list=eval_list(ctx);    
370                 if (ctx->error) return;
371         }
372         if (!get_op(ctx,0,")",NULL)) {
373                 ctx->error=missing_closing_brace;
374                 return;
375         }
376         if (!strcmp(function,"_") && list && list[0] && list[0]->type >= attr_type_string_begin && list[0]->type <= attr_type_string_end) {
377                 res->attr.type=list[0]->type;
378                 res->attr.u.str=g_strdup(gettext(list[0]->u.str));      
379                 
380         } else {
381                 if (command_object_get_attr(ctx, &res->attr, attr_callback_list, &cbl)) {
382                         int valid;
383                         dbg(1,"function call %s from %s\n",function, attr_to_name(res->attr.type));
384                         callback_list_call_attr_4(cbl.u.callback_list, attr_command, function, list, NULL, &valid);
385                 }
386                 res->attr.type=attr_none;
387         }
388         res->var=NULL;
389         res->varlen=0;
390         res->attrn=NULL;
391         res->attrnlen=0;
392 }
393
394 static void
395 eval_postfix(struct context *ctx, struct result *res)
396 {
397         struct result tmp;
398         char *op;
399
400         eval_brace(ctx, res);
401         if (ctx->error) return;
402         for (;;) {
403                 if (!(op=get_op(ctx,0,"[","(",".",NULL)))
404                         return;
405                 if (op[0] == '.') {
406                         eval_brace(ctx, &tmp);
407                         if (ctx->error) return;
408                         resolve(ctx, res,NULL);
409                         if (ctx->error) return;
410                         res->attrn=tmp.var;
411                         res->attrnlen=tmp.varlen;
412                         dump(res);
413                 } else if (op[0] == '[') {
414                         if (!get_op(ctx,0,"]",NULL)) {
415                                 ctx->error=missing_closing_bracket;
416                                 return;
417                         }
418                 } else if (op[0] == '(') {
419                         dbg(1,"function call\n");
420                         resolve_object(ctx, res);
421                         command_call_function(ctx, res);
422                 }
423         }
424 }
425
426 static void
427 eval_unary(struct context *ctx, struct result *res) 
428 {
429         char *op;
430         op=get_op(ctx,0,"~","!",NULL);
431         if (op) {
432                 eval_unary(ctx, res);
433                 if (ctx->error) return;
434                 if (op[0] == '~')
435                         set_int(ctx, res, ~get_int(ctx, res));
436                 else
437                         set_int(ctx, res, !get_int(ctx, res));
438         } else
439                 eval_postfix(ctx, res);
440 }
441
442 static void
443 eval_multiplicative(struct context *ctx, struct result *res) 
444 {
445         struct result tmp;
446         char *op;
447
448         eval_unary(ctx, res);
449         if (ctx->error) return;
450         for (;;) {
451                 if (!(op=get_op(ctx,0,"*","/","%",NULL))) return;
452                 eval_unary(ctx, &tmp);
453                 if (ctx->error) return;
454                 if (is_double(res) || is_double(&tmp)) {
455                         if (op[0] == '*')
456                                 set_double(ctx, res, get_double(ctx, res) * get_double(ctx, &tmp));
457                         else if (op[0] == '/')
458                                 set_double(ctx, res, get_double(ctx, res) / get_double(ctx, &tmp));
459                         else {
460                                 ctx->error=invalid_type;
461                                 return;
462                         }
463                 } else {
464                         if (op[0] == '*')
465                                 set_int(ctx, res, get_int(ctx, res) * get_int(ctx, &tmp));
466                         else if (op[0] == '/')
467                                 set_int(ctx, res, get_int(ctx, res) / get_int(ctx, &tmp));
468                         else
469                                 set_int(ctx, res, get_int(ctx, res) % get_int(ctx, &tmp));
470                 }
471                 if (ctx->error) return;
472         }
473 }
474
475 static void
476 eval_additive(struct context *ctx, struct result *res) 
477 {
478         struct result tmp;
479         char *op;
480
481         eval_multiplicative(ctx, res);
482         if (ctx->error) return;
483         for (;;) {
484                 if (!(op=get_op(ctx,0,"-","+",NULL))) return;
485                 eval_multiplicative(ctx, &tmp);
486                 if (ctx->error) return;
487                 if (is_double(res) || is_double(&tmp)) {
488                         if (op[0] == '+')
489                                 set_double(ctx, res, get_double(ctx, res) + get_double(ctx, &tmp));
490                         else
491                                 set_double(ctx, res, get_double(ctx, res) - get_double(ctx, &tmp));
492                 } else {
493                         if (op[0] == '+')
494                                 set_int(ctx, res, get_int(ctx, res) + get_int(ctx, &tmp));
495                         else
496                                 set_int(ctx, res, get_int(ctx, res) - get_int(ctx, &tmp));
497                 }
498                 if (ctx->error) return;
499         }
500 }
501
502 static void
503 eval_equality(struct context *ctx, struct result *res) 
504 {
505         struct result tmp;
506         char *op;
507
508         eval_additive(ctx, res);
509         if (ctx->error) return;
510         for (;;) {
511                 if (!(op=get_op(ctx,0,"==","!=","<=",">=","<",">",NULL))) return;
512                 eval_additive(ctx, &tmp);
513                 if (ctx->error) return;
514
515                 switch (op[0]) {
516                 case '=':
517                         set_int(ctx, res, (get_int(ctx, res) == get_int(ctx, &tmp)));
518                         break;
519                 case '!':
520                         set_int(ctx, res, (get_int(ctx, res) != get_int(ctx, &tmp)));
521                         break;
522                 case '<':
523                         if (op[1] == '=') {
524                                 set_int(ctx, res, (get_int(ctx, res) <= get_int(ctx, &tmp)));
525                         } else {
526                                 set_int(ctx, res, (get_int(ctx, res) < get_int(ctx, &tmp)));
527                         }
528                         break;
529                 case '>':
530                         if (op[1] == '=') {
531                                 set_int(ctx, res, (get_int(ctx, res) >= get_int(ctx, &tmp)));
532                         } else {
533                                 set_int(ctx, res, (get_int(ctx, res) > get_int(ctx, &tmp)));
534                         }
535                         break;
536                 default:
537                         break;
538                 }
539                 result_free(&tmp);
540         }
541 }
542
543
544 static void
545 eval_bitwise_and(struct context *ctx, struct result *res) 
546 {
547         struct result tmp;
548
549         eval_equality(ctx, res);
550         if (ctx->error) return;
551         for (;;) {
552                 if (get_op(ctx,1,"&&",NULL)) return;
553                 if (!get_op(ctx,0,"&",NULL)) return;
554                 eval_equality(ctx, &tmp);
555                 if (ctx->error) return;
556                 set_int(ctx, res, get_int(ctx, res) & get_int(ctx, &tmp));
557                 if (ctx->error) return;
558         }
559 }
560
561 static void
562 eval_bitwise_xor(struct context *ctx, struct result *res) 
563 {
564         struct result tmp;
565
566         eval_bitwise_and(ctx, res);
567         if (ctx->error) return;
568         for (;;) {
569                 if (!get_op(ctx,0,"^",NULL)) return;
570                 eval_bitwise_and(ctx, &tmp);
571                 if (ctx->error) return;
572                 set_int(ctx, res, get_int(ctx, res) ^ get_int(ctx, &tmp));
573                 if (ctx->error) return;
574         }
575 }
576
577 static void
578 eval_bitwise_or(struct context *ctx, struct result *res) 
579 {
580         struct result tmp;
581
582         eval_bitwise_xor(ctx, res);
583         if (ctx->error) return;
584         for (;;) {
585                 if (get_op(ctx,1,"||",NULL)) return;
586                 if (!get_op(ctx,0,"|",NULL)) return;
587                 eval_bitwise_xor(ctx, &tmp);
588                 if (ctx->error) return;
589                 set_int(ctx, res, get_int(ctx, res) | get_int(ctx, &tmp));
590                 if (ctx->error) return;
591         }
592 }
593
594 static void
595 eval_logical_and(struct context *ctx, struct result *res) 
596 {
597         struct result tmp;
598
599         eval_bitwise_or(ctx, res);
600         if (ctx->error) return;
601         for (;;) {
602                 if (!get_op(ctx,0,"&&",NULL)) return;
603                 eval_bitwise_or(ctx, &tmp);
604                 if (ctx->error) return;
605                 set_int(ctx, res, get_int(ctx, res) && get_int(ctx, &tmp));
606                 if (ctx->error) return;
607         }
608 }
609
610 static void
611 eval_logical_or(struct context *ctx, struct result *res) 
612 {
613         struct result tmp;
614
615         eval_logical_and(ctx, res);
616         if (ctx->error) return;
617         for (;;) {
618                 if (!get_op(ctx,0,"||",NULL)) return;
619                 eval_logical_and(ctx, &tmp);
620                 if (ctx->error) return;
621                 set_int(ctx, res, get_int(ctx, res) || get_int(ctx, &tmp));
622                 if (ctx->error) return;
623         }
624 }
625
626 static void
627 eval_conditional(struct context *ctx, struct result *res)
628 {
629         struct result tmp;
630         int cond;
631
632         eval_logical_or(ctx, res);
633         if (ctx->error) return;
634         if (!get_op(ctx,0,"?",NULL)) return;
635         cond=!!get_int(ctx, res);
636         if (ctx->error) return;
637         eval_logical_or(ctx, &tmp);
638         if (ctx->error) return;
639         if (cond)
640                 *res=tmp;
641         if (!get_op(ctx,0,":",NULL)) {
642                 ctx->error=missing_colon;
643                 return;
644         }
645         eval_logical_or(ctx, &tmp);
646         if (ctx->error) return;
647         if (!cond)
648                 *res=tmp;
649 }
650
651 /* = *= /= %= += -= >>= <<= &= ^= |= */
652
653 static void
654 eval_assignment(struct context *ctx, struct result *res)
655 {
656         struct result tmp;
657         eval_conditional(ctx, res);
658         if (ctx->error) return;
659         if (!get_op(ctx,0,"=",NULL)) return;
660         eval_conditional(ctx, &tmp);
661         if (ctx->error) return;
662         resolve(ctx, &tmp, NULL);
663         if (ctx->error) return;
664         resolve_object(ctx, res);
665         command_set_attr(ctx, res, &tmp);
666 }
667
668 /* , */
669 static void
670 eval_comma(struct context *ctx, struct result *res)
671 {
672         struct result tmp;
673
674         eval_assignment(ctx, res);
675         if (ctx->error) return;
676         for (;;) {
677                 if (!get_op(ctx,0,",",NULL)) return;
678                 eval_assignment(ctx, &tmp);
679                 if (ctx->error) return;
680                 *res=tmp;
681         }
682 }
683
684 static struct attr **
685 eval_list(struct context *ctx)
686 {
687         struct result tmp;
688
689         struct attr **ret=NULL;
690         for (;;) {
691                 eval_assignment(ctx, &tmp);
692                 if (ctx->error) {
693                         attr_list_free(ret);
694                         return NULL;
695                 }
696                 resolve(ctx, &tmp, NULL);
697                 ret=attr_generic_add_attr(ret, &tmp.attr);
698                 if (!get_op(ctx,0,",",NULL)) return ret;
699         }
700 }
701
702 #if 0
703
704 void command(struct attr *attr, char *expr)
705 {
706         struct result res;
707         struct context ctx;
708         memset(&res, 0, sizeof(res));
709         memset(&ctx, 0, sizeof(ctx));
710         ctx.attr=attr;
711         ctx.error=0;
712         ctx.expr=expr;
713         printf("command='%s'\n", expr);
714         eval_comma(&ctx,&res);
715         printf("err=%d %s\n", ctx.error, ctx.expr);
716         dump(&res);
717         printf("***\n");
718         resolve(&ctx, &res, NULL);
719         dump(&res);
720         printf("%s\n", get_string(&ctx, &res));
721 }
722 #endif
723
724 static void
725 command_evaluate_to(struct attr *attr, char *expr, struct context *ctx, struct result *res)
726 {
727         memset(res, 0, sizeof(*res));
728         memset(ctx, 0, sizeof(*ctx));
729         ctx->attr=attr;
730         ctx->expr=expr;
731         eval_comma(ctx,res);
732 }
733
734 void
735 command_evaluate_to_void(struct attr *attr, char *expr, int **error)
736 {
737         struct result res;
738         struct context ctx;
739         command_evaluate_to(attr, expr, &ctx, &res);
740         if (!ctx.error)
741                 resolve(&ctx, &res, NULL);
742         if (error)
743                 *error=&ctx.error;
744
745 }
746
747 char *
748 command_evaluate_to_string(struct attr *attr, char *expr, int **error)
749 {
750         struct result res;
751         struct context ctx;
752         char *ret=NULL;
753
754         command_evaluate_to(attr, expr, &ctx, &res);
755         if (!ctx.error)
756                 resolve(&ctx, &res, NULL);
757         if (!ctx.error)
758                 ret=get_string(&ctx, &res);
759         if (error)
760                 *error=&ctx.error;
761         if (ctx.error)
762                 return NULL;
763         else
764                 return ret;
765 }
766
767 int
768 command_evaluate_to_int(struct attr *attr, char *expr, int **error)
769 {
770         struct result res;
771         struct context ctx;
772         int ret=0;
773
774         command_evaluate_to(attr, expr, &ctx, &res);
775         if (!ctx.error)
776                 resolve(&ctx, &res, NULL);
777         if (!ctx.error)
778                 ret=get_int(&ctx, &res);
779         if (error)
780                 *error=&ctx.error;
781         if (ctx.error)
782                 return 0;
783         else
784                 return ret;
785 }
786
787 int
788 command_evaluate_to_boolean(struct attr *attr, char *expr, int **error)
789 {
790         struct result res;
791         struct context ctx;
792         int ret=0;
793
794         command_evaluate_to(attr, expr, &ctx, &res);
795         if (!ctx.error)
796                 resolve(&ctx, &res, NULL);
797         if (!ctx.error) {
798                 if (res.attr.type == attr_none)
799                         ret=0;
800                 else if ((res.attr.type >= attr_type_int_begin && res.attr.type <= attr_type_int_end) ||
801                          (res.attr.type >= attr_type_double_begin && res.attr.type <= attr_type_double_end))
802                         ret=get_int(&ctx, &res);
803                 else 
804                         ret=res.attr.u.data != NULL;
805         }
806         if (error)
807                 *error=&ctx.error;
808         if (ctx.error)
809                 return 0;
810         else    
811                 return ret;
812 }
813
814 void
815 command_evaluate(struct attr *attr, char *expr)
816 {
817         struct result res;
818         struct context ctx;
819         memset(&res, 0, sizeof(res));
820         memset(&ctx, 0, sizeof(ctx));
821         ctx.attr=attr;
822         ctx.error=0;
823         ctx.expr=expr;
824         for (;;) {
825                 eval_comma(&ctx,&res);
826                 if (ctx.error)
827                         return;
828                 resolve(&ctx, &res, NULL);
829                 if (ctx.error)
830                         return;
831                 if (!get_op(&ctx,0,";",NULL)) return;
832         }
833 }
834
835 #if 0
836 void
837 command_interpreter(struct attr *attr)
838 {
839                 char buffer[4096];
840                 int size;
841                 for (;;) {
842                 size=read(0, buffer, 4095);
843                 buffer[size]='\0';
844                 if (size) {
845                         buffer[size-1]='\0';
846                 }
847                 command(attr, buffer);
848                 }
849 }
850 #endif
851
852 static void
853 command_table_call(struct command_table *table, int count, void *data, char *command, struct attr **in, struct attr ***out, int *valid)
854 {
855         int i;
856         for (i = 0 ; i < count ; i++) {
857                 if (!strcmp(command,table->command)) {
858                         if (valid)
859                                 *valid=1;
860                         table->func(data, command, in, out);
861                 }
862                 table++;
863         }
864 }
865
866 void
867 command_add_table_attr(struct command_table *table, int count, void *data, struct attr *attr)
868 {
869         attr->type=attr_callback;
870         attr->u.callback=callback_new_attr_3(callback_cast(command_table_call),attr_command, table, count, data);
871 }
872
873 void
874 command_add_table(struct callback_list *cbl, struct command_table *table, int count, void *data)
875 {
876         struct attr attr;
877         command_add_table_attr(table, count, data, &attr);
878         callback_list_add(cbl, attr.u.callback);
879 }
880
881 void
882 command_saved_set_cb (struct command_saved *cs, struct callback *cb)
883 {
884         cs->cb = cb;
885 }
886
887 int
888 command_saved_get_int (struct command_saved *cs)
889 {
890         return get_int(&cs->ctx, &cs->res);
891 }
892
893 int 
894 command_saved_error (struct command_saved *cs)
895 {
896         return cs->error;
897 }
898
899 static void
900 command_saved_evaluate_idle (struct command_saved *cs) 
901 {
902         // Only run once at a time
903         if (cs->idle_ev) {
904                 event_remove_idle(cs->idle_ev);
905                 cs->idle_ev = NULL;
906         }
907
908         command_evaluate_to(&cs->navit, cs->command, &cs->ctx, &cs->res);
909
910         if (!cs->ctx.error) {
911                 cs->error = 0;
912
913                 if (cs->cb) {
914                         callback_call_1(cs->cb, cs);
915                 }
916         } else {
917                 cs->error = cs->ctx.error;
918         }
919 }
920
921 static void
922 command_saved_evaluate(struct command_saved *cs)
923 {       
924         if (cs->idle_ev) {
925                 // We're already scheduled for reevaluation
926                 return;
927         }
928
929         if (!cs->idle_cb) {
930                 cs->idle_cb = callback_new_1(callback_cast(command_saved_evaluate_idle), cs);
931         }
932
933         cs->idle_ev = event_add_idle(100, cs->idle_cb);
934 }
935
936 static void
937 command_saved_callbacks_changed(struct command_saved *cs)
938 {
939         // For now, we delete each and every callback and then re-create them
940         int i;
941         struct object_func *func;
942         struct attr attr;
943
944         if (cs->register_ev) {
945                 event_remove_idle(cs->register_ev);
946                 cs->register_ev = NULL;
947         }
948
949         attr.type = attr_callback;
950
951         for (i = 0; i < cs->num_cbs; i++) {
952                 func = object_func_lookup(cs->cbs[i].attr.type);
953                 
954                 if (!func->remove_attr) {
955                         dbg(0, "Could not remove command-evaluation callback because remove_attr is missing for type %i!\n", cs->cbs[i].attr.type);
956                         continue;
957                 }
958
959                 attr.u.callback = cs->cbs[i].cb;
960
961                 func->remove_attr(cs->cbs[i].attr.u.data, &attr);
962                 callback_destroy(cs->cbs[i].cb);
963         }
964
965         g_free(cs->cbs);
966         cs->cbs = NULL;
967         cs->num_cbs = 0;
968
969         // Now, re-create all the callbacks
970         command_register_callbacks(cs);
971 }
972
973 static int
974 command_register_callbacks(struct command_saved *cs)
975 {
976         struct attr prev,cb_attr,attr;
977         int status;
978         struct object_func *func;
979         struct callback *cb;
980         
981         attr = cs->navit;
982         cs->ctx.expr = cs->command;
983         cs->ctx.attr = &attr;
984         prev = cs->navit;       
985
986         while ((status = get_next_object(&cs->ctx, &cs->res)) != 0) {
987                 resolve(&cs->ctx, &cs->res, NULL);
988
989                 if (cs->ctx.error || (cs->res.attr.type == attr_none)) {
990                         // We could not resolve an object, perhaps because it has not been created
991                         return 0;
992                 }
993
994                 if (prev.type != attr_none) {
995                         func = object_func_lookup(prev.type);
996
997                         if (func->add_attr) {
998                                 if (status == 2) { // This is not the final attribute name
999                                         cb = callback_new_attr_1(callback_cast(command_saved_callbacks_changed), cs->res.attr.type, (void*)cs);
1000                                         attr = cs->res.attr;
1001                                 } else if (status == 1) { // This is the final attribute name
1002                                         cb = callback_new_attr_1(callback_cast(command_saved_evaluate), cs->res.attr.type, (void*)cs);
1003                                         cs->ctx.attr = &cs->navit;
1004                                 } else {
1005                                         dbg(0, "Error: Strange status returned from get_next_object()\n");
1006                                 }
1007
1008                                 cs->num_cbs++;
1009                                 cs->cbs = g_realloc(cs->cbs, (sizeof(struct command_saved_cb) * cs->num_cbs));
1010                                 cs->cbs[cs->num_cbs-1].cb = cb;
1011                                 cs->cbs[cs->num_cbs-1].attr = prev;
1012                                         
1013                                 cb_attr.u.callback = cb;
1014                                 cb_attr.type = attr_callback;
1015
1016                                 func->add_attr(prev.u.data, &cb_attr);
1017
1018                         } else {
1019                                 dbg(0, "Could not add callback because add_attr is missing for type %i}n", prev.type);
1020                         }
1021                 }
1022
1023                 if (status == 2) {
1024                         prev = cs->res.attr;
1025                 } else {
1026                         prev = cs->navit;
1027                 }
1028         }
1029
1030         command_saved_evaluate_idle(cs);
1031
1032         return 1;
1033 }
1034
1035 struct command_saved
1036 *command_saved_new(char *command, struct navit *navit, struct callback *cb)
1037 {
1038         struct command_saved *ret;
1039
1040         ret = g_new0(struct command_saved, 1);
1041         ret->command = g_strdup(command);
1042         ret->navit.u.navit = navit;
1043         ret->navit.type = attr_navit;
1044         ret->cb = cb;
1045         ret->error = not_ready;
1046
1047         if (!command_register_callbacks(ret)) {
1048                 // We try this as an idle call again
1049                 ret->register_cb = callback_new_1(callback_cast(command_saved_callbacks_changed), ret);
1050                 ret->register_ev = event_add_idle(300, ret->register_cb);
1051         }               
1052
1053         return ret;
1054 }
1055
1056 void 
1057 command_saved_destroy(struct command_saved *cs)
1058 {
1059         g_free(cs->command);
1060         g_free(cs);
1061 }