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