add log daemon
[project/ubox.git] / validate / validate.c
1 /*
2  * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License version 2.1
6  * as published by the Free Software Foundation
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <stdbool.h>
18 #include <ctype.h>
19
20 #include <arpa/inet.h>
21 #include <netinet/ether.h>
22 #include <sys/stat.h>
23
24 #include "libvalidate.h"
25
26 enum dt_optype {
27         OP_UNKNOWN,
28         OP_BOOL,
29         OP_NUMBER,
30         OP_STRING,
31         OP_FUNCTION
32 };
33
34 struct dt_fun;
35
36 struct dt_op {
37         enum dt_optype type;
38         const char *next;
39         int length;
40         int nextop;
41         union {
42                 bool boolean;
43                 double number;
44                 const char *string;
45                 struct dt_fun *function;
46         } value;
47 };
48
49 struct dt_state {
50         int pos;
51         int depth;
52         const char *value;
53         struct dt_op stack[32];
54 };
55
56 struct dt_fun {
57         const char *name;
58         bool (*call)(struct dt_state *s, int nargs);
59 };
60
61 static bool
62 dt_test_number(double number, const char *value)
63 {
64         char *e;
65         double n;
66
67         n = strtod(value, &e);
68
69         return (e > value && *e == 0 && n == number);
70 }
71
72 static bool
73 dt_test_string(const char *s, const char *end, const char *value)
74 {
75         bool esc = false;
76
77         while (*value)
78         {
79                 if (s > end)
80                         return false;
81
82                 if (!esc && *s == '\\')
83                 {
84                         s++;
85
86                         if (s >= end)
87                                 break;
88
89                         esc = true;
90                         continue;
91                 }
92
93                 if (*s != *value)
94                         return false;
95
96                 esc = false;
97                 value++;
98                 s++;
99         }
100
101         return (*s == *value || (s > end && *value == 0));
102 }
103
104 static bool
105 dt_step(struct dt_state *s);
106
107 static bool
108 dt_call(struct dt_state *s);
109
110 static bool
111 dt_type_or(struct dt_state *s, int nargs)
112 {
113         while (nargs--)
114                 if (dt_step(s))
115                         return true;
116
117         return false;
118 }
119
120 static bool
121 dt_type_and(struct dt_state *s, int nargs)
122 {
123         while (nargs--)
124                 if (!dt_step(s))
125                         return false;
126
127         return true;
128 }
129
130 static bool
131 dt_type_not(struct dt_state *s, int nargs)
132 {
133         if (!nargs)
134                 return false;
135
136         return !dt_step(s);
137 }
138
139 static bool
140 dt_type_neg(struct dt_state *s, int nargs)
141 {
142         bool rv;
143         const char *value = s->value;
144
145         if (!nargs)
146                 return false;
147
148         if (*s->value == '!')
149                 while (isspace(*++s->value));
150
151         rv = dt_step(s);
152         s->value = value;
153
154         return rv;
155 }
156
157 static bool
158 dt_type_list(struct dt_state *s, int nargs)
159 {
160         bool rv = true;
161         int pos = s->pos;
162         char *p, *str = strdup(s->value);
163         const char *value = s->value;
164
165         if (!str || !nargs)
166                 return false;
167
168         for (p = strtok(str, " \t"); p; p = strtok(NULL, " \t"))
169         {
170                 s->value = p;
171
172                 if (!dt_step(s))
173                 {
174                         rv = false;
175                         break;
176                 }
177
178                 s->pos = pos;
179         }
180
181         s->value = value;
182         free(str);
183
184         return rv;
185 }
186
187 static bool
188 dt_type_min(struct dt_state *s, int nargs)
189 {
190         int n;
191         char *e;
192
193         if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
194         {
195                 n = strtol(s->value, &e, 0);
196
197                 return (e > s->value && *e == 0 &&
198                         n >= s->stack[s->pos].value.number);
199         }
200
201         return false;
202 }
203
204 static bool
205 dt_type_max(struct dt_state *s, int nargs)
206 {
207         int n;
208         char *e;
209
210         if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
211         {
212                 n = strtol(s->value, &e, 0);
213
214                 return (e > s->value && *e == 0 &&
215                         n <= s->stack[s->pos].value.number);
216         }
217
218         return false;
219 }
220
221 static bool
222 dt_type_range(struct dt_state *s, int nargs)
223 {
224         int n;
225         char *e;
226
227         if (nargs >= 2 &&
228             s->stack[s->pos].type == OP_NUMBER &&
229             s->stack[s->pos + 1].type == OP_NUMBER)
230         {
231                 n = strtol(s->value, &e, 0);
232
233                 return (e > s->value && *e == 0 &&
234                         n >= s->stack[s->pos].value.number &&
235                         n <= s->stack[s->pos + 1].value.number);
236         }
237
238         return false;
239 }
240
241 static bool
242 dt_type_minlen(struct dt_state *s, int nargs)
243 {
244         if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
245                 return (strlen(s->value) >= s->stack[s->pos].value.number);
246
247         return false;
248 }
249
250 static bool
251 dt_type_maxlen(struct dt_state *s, int nargs)
252 {
253         if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER)
254                 return (strlen(s->value) <= s->stack[s->pos].value.number);
255
256         return false;
257 }
258
259 static bool
260 dt_type_rangelen(struct dt_state *s, int nargs)
261 {
262         if (nargs >= 2 &&
263             s->stack[s->pos].type == OP_NUMBER &&
264             s->stack[s->pos + 1].type == OP_NUMBER)
265                 return (strlen(s->value) >= s->stack[s->pos].value.number &&
266                                 strlen(s->value) <= s->stack[s->pos + 1].value.number);
267
268         return false;
269 }
270
271 static bool
272 dt_type_int(struct dt_state *s, int nargs)
273 {
274         char *e;
275
276         strtol(s->value, &e, 0);
277
278         return (e > s->value && *e == 0);
279 }
280
281 static bool
282 dt_type_uint(struct dt_state *s, int nargs)
283 {
284         int n;
285         char *e;
286
287         n = strtol(s->value, &e, 0);
288
289         return (e > s->value && *e == 0 && n >= 0);
290 }
291
292 static bool
293 dt_type_float(struct dt_state *s, int nargs)
294 {
295         char *e;
296
297         strtod(s->value, &e);
298
299         return (e > s->value && *e == 0);
300 }
301
302 static bool
303 dt_type_ufloat(struct dt_state *s, int nargs)
304 {
305         int n;
306         char *e;
307
308         n = strtod(s->value, &e);
309
310         return (e > s->value && *e == 0 && n >= 0.0);
311 }
312
313 static bool
314 dt_type_bool(struct dt_state *s, int nargs)
315 {
316         int i;
317         const char *values[] = {
318                 "0", "off", "false", "no",
319                 "1", "on", "true", "yes"
320         };
321
322         for (i = 0; i < sizeof(values) / sizeof(values[0]); i++)
323                 if (!strcasecmp(values[i], s->value))
324                         return true;
325
326         return false;
327 }
328
329 static bool
330 dt_type_string(struct dt_state *s, int nargs)
331 {
332         return true;
333 }
334
335 static bool
336 dt_type_ip4addr(struct dt_state *s, int nargs)
337 {
338         struct in6_addr a;
339         return inet_pton(AF_INET, s->value, &a);
340 }
341
342 static bool
343 dt_type_ip6addr(struct dt_state *s, int nargs)
344 {
345         struct in6_addr a;
346         return inet_pton(AF_INET6, s->value, &a);
347 }
348
349 static bool
350 dt_type_ipaddr(struct dt_state *s, int nargs)
351 {
352         return (dt_type_ip4addr(s, 0) || dt_type_ip6addr(s, 0));
353 }
354
355 static bool
356 dt_type_netmask4(struct dt_state *s, int nargs)
357 {
358         int i;
359         struct in_addr a;
360
361         if (!inet_pton(AF_INET, s->value, &a))
362                 return false;
363
364         if (a.s_addr == 0)
365                 return true;
366
367         a.s_addr = ntohl(a.s_addr);
368
369         for (i = 0; (i < 32) && !(a.s_addr & (1 << i)); i++);
370
371         return ((uint32_t)(~((1 << i) - 1)) == a.s_addr);
372 }
373
374 static bool
375 dt_type_netmask6(struct dt_state *s, int nargs)
376 {
377         int i;
378         struct in6_addr a;
379
380         if (!inet_pton(AF_INET6, s->value, &a))
381                 return false;
382
383         for (i = 0; (i < 16) && (a.s6_addr[i] == 0xFF); i++);
384
385         if (i == 16)
386                 return true;
387
388         if ((a.s6_addr[i] != 255) && (a.s6_addr[i] != 254) &&
389                 (a.s6_addr[i] != 252) && (a.s6_addr[i] != 248) &&
390                 (a.s6_addr[i] != 240) && (a.s6_addr[i] != 224) &&
391                 (a.s6_addr[i] != 192) && (a.s6_addr[i] != 128) &&
392                 (a.s6_addr[i] != 0))
393                 return false;
394
395         for (; (i < 16) && (a.s6_addr[i] == 0); i++);
396
397         return (i == 16);
398 }
399
400 static bool
401 dt_type_cidr4(struct dt_state *s, int nargs)
402 {
403         int n;
404         struct in_addr a;
405         char *p, buf[sizeof("255.255.255.255/32\0")];
406
407         if (strlen(s->value) >= sizeof(buf))
408                 return false;
409
410         strcpy(buf, s->value);
411         p = strchr(buf, '/');
412
413         if (p)
414         {
415                 *p++ = 0;
416
417                 n = strtoul(p, &p, 10);
418
419                 if ((*p != 0) || (n > 32))
420                         return false;
421         }
422
423         return inet_pton(AF_INET, buf, &a);
424 }
425
426 static bool
427 dt_type_cidr6(struct dt_state *s, int nargs)
428 {
429         int n;
430         struct in6_addr a;
431         char *p, buf[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/128\0")];
432
433         if (strlen(s->value) >= sizeof(buf))
434                 return false;
435
436         strcpy(buf, s->value);
437         p = strchr(buf, '/');
438
439         if (p)
440         {
441                 *p++ = 0;
442
443                 n = strtoul(p, &p, 10);
444
445                 if ((*p != 0) || (n > 128))
446                         return false;
447         }
448
449         return inet_pton(AF_INET6, buf, &a);
450 }
451
452 static bool
453 dt_type_cidr(struct dt_state *s, int nargs)
454 {
455         return (dt_type_cidr4(s, 0) || dt_type_cidr6(s, 0));
456 }
457
458 static bool
459 dt_type_ipmask4(struct dt_state *s, int nargs)
460 {
461         bool rv;
462         struct in_addr a;
463         const char *value;
464         char *p, buf[sizeof("255.255.255.255/255.255.255.255\0")];
465
466         if (strlen(s->value) >= sizeof(buf))
467                 return false;
468
469         strcpy(buf, s->value);
470         p = strchr(buf, '/');
471
472         if (p)
473         {
474                 *p++ = 0;
475
476                 value = s->value;
477                 s->value = p;
478                 rv = dt_type_netmask4(s, 0);
479                 s->value = value;
480
481                 if (!rv)
482                         return false;
483         }
484
485         return inet_pton(AF_INET, buf, &a);
486 }
487
488 static bool
489 dt_type_ipmask6(struct dt_state *s, int nargs)
490 {
491         bool rv;
492         struct in6_addr a;
493         const char *value;
494         char *p, buf[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/"
495                             "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255\0")];
496
497         if (strlen(s->value) >= sizeof(buf))
498                 return false;
499
500         strcpy(buf, s->value);
501         p = strchr(buf, '/');
502
503         if (p)
504         {
505                 *p++ = 0;
506
507                 value = s->value;
508                 s->value = p;
509                 rv = dt_type_netmask6(s, 0);
510                 s->value = value;
511
512                 if (!rv)
513                         return false;
514         }
515
516         return inet_pton(AF_INET6, buf, &a);
517 }
518
519 static bool
520 dt_type_ipmask(struct dt_state *s, int nargs)
521 {
522         return (dt_type_ipmask4(s, 0) || dt_type_ipmask6(s, 0));
523 }
524
525 static bool
526 dt_type_port(struct dt_state *s, int nargs)
527 {
528         int n;
529         char *e;
530
531         n = strtoul(s->value, &e, 10);
532
533         return (e > s->value && *e == 0 && n <= 65535);
534 }
535
536 static bool
537 dt_type_portrange(struct dt_state *s, int nargs)
538 {
539         int n, m;
540         char *e;
541
542         n = strtoul(s->value, &e, 10);
543
544         if (e == s->value || *e != '-')
545                 return false;
546
547         m = strtoul(e + 1, &e, 10);
548
549         return (*e == 0 && n <= 65535 && m <= 65535 && n <= m);
550 }
551
552 static bool
553 dt_type_macaddr(struct dt_state *s, int nargs)
554 {
555         return !!ether_aton(s->value);
556 }
557
558 static bool
559 dt_type_uciname(struct dt_state *s, int nargs)
560 {
561         const char *p;
562
563         for (p = s->value;
564              *p && ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') ||
565                     (*p >= '0' && *p <= '9') || (*p == '_'));
566                  p++);
567
568         return (*p == 0);
569 }
570
571 static bool
572 dt_type_wpakey(struct dt_state *s, int nargs)
573 {
574         int len = strlen(s->value);
575         const char *p = s->value;
576
577         if (len == 64)
578         {
579                 while (isxdigit(*p))
580                         p++;
581
582                 return (*p == 0);
583         }
584
585         return (len >= 8 && len <= 63);
586 }
587
588 static bool
589 dt_type_wepkey(struct dt_state *s, int nargs)
590 {
591         int len = strlen(s->value);
592         const char *p = s->value;
593
594         if (!strncmp(p, "s:", 2))
595         {
596                 len -= 2;
597                 p += 2;
598         }
599
600         if (len == 10 || len == 26)
601         {
602                 while (isxdigit(*p))
603                         p++;
604
605                 return (*p == 0);
606         }
607
608         return (len == 5 || len == 13);
609 }
610
611 static bool
612 dt_type_hostname(struct dt_state *s, int nargs)
613 {
614         const char *p, *last;
615
616         for (p = last = s->value; *p; p++)
617         {
618                 if (*p == '.')
619                 {
620                         if ((p - last) == 0 || (p - last) > 63)
621                                 return false;
622
623                         last = p + 1;
624                         continue;
625                 }
626                 else if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') ||
627                          (*p >= '0' && *p <= '9') || (*p == '_') || (*p == '-'))
628                 {
629                         continue;
630                 }
631
632                 return false;
633         }
634
635         return ((p - last) > 0 && (p - last) <= 255);
636 }
637
638 static bool
639 dt_type_host(struct dt_state *s, int nargs)
640 {
641         return (dt_type_hostname(s, 0) || dt_type_ipaddr(s, 0));
642 }
643
644 static bool
645 dt_type_network(struct dt_state *s, int nargs)
646 {
647         return (dt_type_uciname(s, 0) || dt_type_host(s, 0));
648 }
649
650 static bool
651 dt_type_phonedigit(struct dt_state *s, int nargs)
652 {
653         const char *p;
654
655         for (p = s->value;
656              *p && ((*p >= '0' && *p <= '9') || (*p == '*') || (*p == '#') ||
657                     (*p == '!') || (*p == '.'));
658                  p++);
659
660         return (*p == 0);
661 }
662
663 static bool
664 dt_type_directory(struct dt_state *s, int nargs)
665 {
666         struct stat st;
667         return (!stat(s->value, &st) && S_ISDIR(st.st_mode));
668 }
669
670
671 static bool
672 dt_type_device(struct dt_state *s, int nargs)
673 {
674         struct stat st;
675         return (!stat(s->value, &st) &&
676                 (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)));
677 }
678
679 static bool
680 dt_type_file(struct dt_state *s, int nargs)
681 {
682         struct stat st;
683         return (!stat(s->value, &st) && S_ISREG(st.st_mode));
684 }
685
686
687 static struct dt_fun dt_types[] = {
688         { "or",                         dt_type_or                      },
689         { "and",                        dt_type_and                     },
690         { "not",                        dt_type_not                     },
691         { "neg",                        dt_type_neg                     },
692         { "list",                       dt_type_list            },
693         { "min",                        dt_type_min                     },
694         { "max",                        dt_type_max                     },
695         { "range",                      dt_type_range           },
696         { "minlength",          dt_type_minlen          },
697         { "maxlength",          dt_type_maxlen          },
698         { "rangelength",        dt_type_rangelen        },
699         { "integer",            dt_type_int                     },
700         { "uinteger",           dt_type_uint            },
701         { "float",                      dt_type_float           },
702         { "ufloat",                     dt_type_ufloat          },
703         { "bool",                       dt_type_bool            },
704         { "string",                     dt_type_string          },
705         { "ip4addr",            dt_type_ip4addr         },
706         { "ip6addr",            dt_type_ip6addr         },
707         { "ipaddr",                     dt_type_ipaddr          },
708         { "cidr4",                      dt_type_cidr4           },
709         { "cidr6",                      dt_type_cidr6           },
710         { "cidr",                       dt_type_cidr            },
711         { "netmask4",           dt_type_netmask4        },
712         { "netmask6",           dt_type_netmask6        },
713         { "ipmask4",            dt_type_ipmask4         },
714         { "ipmask6",            dt_type_ipmask6         },
715         { "ipmask",                     dt_type_ipmask          },
716         { "port",                       dt_type_port            },
717         { "portrange",          dt_type_portrange       },
718         { "macaddr",            dt_type_macaddr         },
719         { "uciname",        dt_type_uciname             },
720         { "wpakey",                     dt_type_wpakey          },
721         { "wepkey",                     dt_type_wepkey          },
722         { "hostname",           dt_type_hostname        },
723         { "host",                       dt_type_host            },
724         { "network",            dt_type_network         },
725         { "phonedigit",         dt_type_phonedigit      },
726         { "directory",          dt_type_directory       },
727         { "device",                     dt_type_device          },
728         { "file",                       dt_type_file            },
729
730         { }
731 };
732
733 static struct dt_fun *
734 dt_lookup_function(const char *s, const char *e)
735 {
736         struct dt_fun *fun = dt_types;
737
738         while (fun->name)
739         {
740                 if (!strncmp(fun->name, s, e - s) && *(fun->name + (e - s)) == '\0')
741                         return fun;
742
743                 fun++;
744         }
745
746         return NULL;
747 }
748
749 static bool
750 dt_parse_atom(struct dt_state *s, const char *label, const char *end)
751 {
752         char q, *e;
753         const char *p;
754         bool esc;
755         double dval;
756         struct dt_fun *func;
757         struct dt_op *op = &s->stack[s->depth];
758
759         if ((s->depth + 1) >= (sizeof(s->stack) / sizeof(s->stack[0])))
760         {
761                 printf("Syntax error, expression too long\n");
762                 return false;
763         }
764
765         while (isspace(*label))
766                 label++;
767
768         /* test whether label is a float */
769         dval = strtod(label, &e);
770
771         if (e > label)
772         {
773                 op->next = e;
774                 op->type = OP_NUMBER;
775                 op->value.number = dval;
776                 op->nextop = ++s->depth;
777
778                 return true;
779         }
780         else if ((*label == '"') || (*label == '\''))
781         {
782                 for (p = label + 1, q = *label, esc = false; p <= end; p++)
783                 {
784                         if (esc)
785                         {
786                                 esc = false;
787                                 continue;
788                         }
789                         else if (*p == '\\')
790                         {
791                                 esc = true;
792                                 continue;
793                         }
794                         else if (*p == q)
795                         {
796                                 op->next = p + 1;
797                                 op->type = OP_STRING;
798                                 op->length = (p - label) - 2;
799                                 op->value.string = label + 1;
800                                 op->nextop = ++s->depth;
801
802                                 return true;
803                         }
804                 }
805
806                 printf("Syntax error, unterminated string\n");
807                 return false;
808         }
809         else if (*label)
810         {
811                 for (p = label;
812                      p <= end && ((*p >= 'A' && *p <= 'Z') ||
813                                   (*p >= 'a' && *p <= 'z') ||
814                                   (*p >= '0' && *p <= '9') ||
815                                   (*p == '_'));
816                      p++);
817
818                 func = dt_lookup_function(label, p);
819
820                 if (!func)
821                 {
822                         printf("Syntax error, unrecognized function\n");
823                         return false;
824                 }
825
826                 op->next = p;
827                 op->type = OP_FUNCTION;
828                 op->value.function = func;
829                 op->nextop = ++s->depth;
830
831                 return true;
832         }
833
834         printf("Syntax error, unexpected EOF\n");
835         return false;
836 }
837
838 static bool
839 dt_parse_list(struct dt_state *s, const char *code, const char *end);
840
841 static bool
842 dt_parse_expr(const char *code, const char *end, struct dt_state *s)
843 {
844         struct dt_op *tok;
845
846         if (!dt_parse_atom(s, code, end))
847                 return false;
848
849         tok = &s->stack[s->depth - 1];
850
851         while (isspace(*tok->next))
852                 tok->next++;
853
854         if (tok->type == OP_FUNCTION)
855         {
856                 if (*tok->next == '(')
857                 {
858                         end--;
859
860                         while (isspace(*end) && end > tok->next + 1)
861                                 end--;
862
863                         return dt_parse_list(s, tok->next + 1, end);
864                 }
865                 else if (tok->next == end)
866                 {
867                         return dt_parse_list(s, tok->next, tok->next);
868                 }
869
870                 printf("Syntax error, expected '(' or EOF after function label\n");
871                 return false;
872         }
873         else if (tok->next == end)
874         {
875                 return true;
876         }
877
878         printf("Syntax error, expected ',' after literal\n");
879         return false;
880 }
881
882 static bool
883 dt_parse_list(struct dt_state *s, const char *code, const char *end)
884 {
885         char c;
886         bool esc;
887         int nest;
888         const char *p, *last;
889         struct dt_op *fptr;
890
891         if (!code)
892                 return false;
893
894         fptr = &s->stack[s->depth - 1];
895
896         for (nest = 0, p = last = code, esc = false, c = *p;
897              p <= end;
898              p++, c = (p < end) ? *p : '\0')
899         {
900                 if (esc)
901                 {
902                         esc = false;
903                         continue;
904                 }
905
906                 switch (c)
907                 {
908                 case '\\':
909                         esc = true;
910                         break;
911
912                 case '(':
913                         nest++;
914                         break;
915
916                 case ')':
917                         nest--;
918                         break;
919
920                 case ',':
921                 case '\0':
922                         if (nest <= 0)
923                         {
924                                 if (p > last)
925                                 {
926                                         if (!dt_parse_expr(last, p, s))
927                                                 return false;
928
929                                         fptr->length++;
930                                 }
931
932                                 last = p + 1;
933                         }
934
935                         break;
936                 }
937         }
938
939         fptr->nextop = s->depth;
940         return true;
941 }
942
943 static bool
944 dt_step(struct dt_state *s)
945 {
946         bool rv;
947         struct dt_op *op = &s->stack[s->pos];
948
949         switch (op->type)
950         {
951         case OP_BOOL:
952                 rv = op->value.boolean;
953                 break;
954
955         case OP_NUMBER:
956                 rv = dt_test_number(op->value.number, s->value);
957                 break;
958
959         case OP_STRING:
960                 rv = dt_test_string(op->value.string, op->value.string + op->length, s->value);
961                 break;
962
963         case OP_FUNCTION:
964                 rv = dt_call(s);
965                 break;
966
967         default:
968                 rv = false;
969                 break;
970         }
971
972         s->pos = op->nextop;
973         return rv;
974 }
975
976 static bool
977 dt_call(struct dt_state *s)
978 {
979         bool rv;
980         struct dt_op *fptr = &s->stack[s->pos];
981         struct dt_fun *func = fptr->value.function;
982
983         s->pos++;
984
985         rv = func->call(s, fptr->length);
986
987         s->pos = fptr->nextop;
988
989         return rv;
990 }
991
992 bool
993 dt_parse(const char *code, const char *value)
994 {
995         struct dt_state s = {
996                 .depth = 1,
997                 .stack = {
998                         {
999                                 .type = OP_FUNCTION,
1000                                 .value.function = &dt_types[0],
1001                                 .next = code
1002                         }
1003                 }
1004         };
1005
1006         if (!value || !*value)
1007                 return false;
1008
1009         if (!dt_parse_list(&s, code, code + strlen(code)))
1010                 return false;
1011
1012         s.value = value;
1013
1014         return dt_call(&s);
1015 }