fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * libini *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/libini/expr.c *
7 * Created: 2010-09-13 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2010-2024 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include <config.h>
24
25#include <stdlib.h>
26#include <string.h>
27
28#include <libini/libini.h>
29#include <libini/scanner.h>
30
31
32int ini_eval (scanner_t *scn, ini_sct_t *sct, ini_val_t *val);
33
34
35static
36int val_str_cat (ini_val_t *dst, const char *s1, const char *s2)
37{
38 unsigned n1, n2;
39 char *str;
40
41 n1 = strlen (s1);
42 n2 = strlen (s2);
43
44 str = malloc (n1 + n2 + 1);
45
46 if (str == NULL) {
47 return (1);
48 }
49
50 if (n1 > 0) {
51 memcpy (str, s1, n1);
52 }
53
54 if (n2 > 0) {
55 memcpy (str + n1, s2, n2);
56 }
57
58 str[n1 + n2] = 0;
59
60 ini_val_set_str (dst, str);
61
62 free (str);
63
64 return (0);
65}
66
67static
68int val_promote1 (ini_val_t *val)
69{
70 if (val->type == INI_VAL_NONE) {
71 ini_val_set_uint32 (val, 0);
72 }
73
74 return (0);
75}
76
77static
78int val_promote2 (ini_val_t *val1, ini_val_t *val2)
79{
80 if (val1->type == val2->type) {
81 if (val1->type == INI_VAL_NONE) {
82 ini_val_set_uint32 (val1, 0);
83 ini_val_set_uint32 (val2, 0);
84 }
85
86 return (0);
87 }
88
89 if (val1->type == INI_VAL_NONE) {
90 if (val2->type == INI_VAL_INT) {
91 ini_val_set_uint32 (val1, 0);
92 }
93 else if (val2->type == INI_VAL_STR) {
94 ini_val_set_str (val1, "");
95 }
96 else {
97 return (1);
98 }
99
100 return (0);
101 }
102
103 if (val2->type == INI_VAL_NONE) {
104 if (val1->type == INI_VAL_INT) {
105 ini_val_set_uint32 (val2, 0);
106 }
107 else if (val1->type == INI_VAL_STR) {
108 ini_val_set_str (val2, "");
109 }
110 else {
111 return (1);
112 }
113
114 return (0);
115 }
116
117 return (1);
118}
119
120static
121int val_plus (ini_val_t *val)
122{
123 if (val_promote1 (val)) {
124 return (1);
125 }
126
127 if (val->type == INI_VAL_INT) {
128 return (0);
129 }
130
131 return (1);
132}
133
134static
135int val_neg (ini_val_t *val)
136{
137 if (val_promote1 (val)) {
138 return (1);
139 }
140
141 if (val->type == INI_VAL_INT) {
142 val->val.u32 = (~val->val.u32 + 1) & 0xffffffff;
143 return (0);
144 }
145
146 return (1);
147}
148
149static
150int val_bnot (ini_val_t *val)
151{
152 if (val_promote1 (val)) {
153 return (1);
154 }
155
156 if (val->type == INI_VAL_INT) {
157 val->val.u32 = ~val->val.u32 & 0xffffffff;
158 return (0);
159 }
160
161 return (1);
162}
163
164static
165int val_lnot (ini_val_t *val)
166{
167 if (val_promote1 (val)) {
168 return (1);
169 }
170
171 if (val->type == INI_VAL_INT) {
172 val->val.u32 = val->val.u32 == 0;
173 return (0);
174 }
175 else if (val->type == INI_VAL_STR) {
176 ini_val_set_uint32 (val, strcmp (val->val.str, "") == 0);
177 return (0);
178 }
179
180 return (1);
181}
182
183static
184int val_mul (ini_val_t *dst, ini_val_t *src)
185{
186 if (val_promote2 (dst, src)) {
187 return (1);
188 }
189
190 if (dst->type == INI_VAL_INT) {
191 dst->val.u32 = (dst->val.u32 * src->val.u32) & 0xffffffff;
192 return (0);
193 }
194
195 return (1);
196}
197
198static
199int val_div (ini_val_t *dst, ini_val_t *src)
200{
201 if (val_promote2 (dst, src)) {
202 return (1);
203 }
204
205 if (dst->type == INI_VAL_INT) {
206 if (src->val.u32 == 0) {
207 return (1);
208 }
209
210 dst->val.u32 = (dst->val.u32 / src->val.u32) & 0xffffffff;
211
212 return (0);
213 }
214
215 return (1);
216}
217
218static
219int val_mod (ini_val_t *dst, ini_val_t *src)
220{
221 if (val_promote2 (dst, src)) {
222 return (1);
223 }
224
225 if (dst->type == INI_VAL_INT) {
226 if (src->val.u32 == 0) {
227 return (1);
228 }
229
230 dst->val.u32 = (dst->val.u32 % src->val.u32) & 0xffffffff;
231
232 return (0);
233 }
234
235 return (1);
236}
237
238static
239int val_add (ini_val_t *dst, ini_val_t *src)
240{
241 unsigned t1, t2;
242 char buf[32];
243
244 val_promote2 (dst, src);
245
246 t1 = dst->type;
247 t2 = src->type;
248
249 if ((t1 == INI_VAL_INT) && (t2 == INI_VAL_INT)) {
250 dst->val.u32 = (dst->val.u32 + src->val.u32) & 0xffffffff;
251 return (0);
252 }
253 else if ((t1 == INI_VAL_STR) && (t2 == INI_VAL_STR)) {
254 if (val_str_cat (dst, dst->val.str, src->val.str)) {
255 return (1);
256 }
257
258 return (0);
259 }
260 else if ((t1 == INI_VAL_STR) && (t2 == INI_VAL_INT)) {
261 sprintf (buf, "%lu", src->val.u32);
262
263 if (val_str_cat (dst, dst->val.str, buf)) {
264 return (1);
265 }
266
267 return (0);
268 }
269 else if ((t1 == INI_VAL_INT) && (t2 == INI_VAL_STR)) {
270 sprintf (buf, "%lu", dst->val.u32);
271
272 if (val_str_cat (dst, buf, src->val.str)) {
273 return (1);
274 }
275
276 return (0);
277 }
278
279 return (1);
280}
281
282static
283int val_sub (ini_val_t *dst, ini_val_t *src)
284{
285 if (val_promote2 (dst, src)) {
286 return (1);
287 }
288
289 if (dst->type == INI_VAL_INT) {
290 dst->val.u32 = (dst->val.u32 - src->val.u32) & 0xffffffff;
291 return (0);
292 }
293
294 return (1);
295}
296
297static
298int val_shl (ini_val_t *dst, ini_val_t *src)
299{
300 if (val_promote2 (dst, src)) {
301 return (1);
302 }
303
304 if (dst->type == INI_VAL_INT) {
305 dst->val.u32 = (dst->val.u32 << (src->val.u32 & 31)) & 0xffffffff;
306 return (0);
307 }
308
309 return (1);
310}
311
312static
313int val_shr (ini_val_t *dst, ini_val_t *src)
314{
315 if (val_promote2 (dst, src)) {
316 return (1);
317 }
318
319 if (dst->type == INI_VAL_INT) {
320 dst->val.u32 = (dst->val.u32 >> (src->val.u32 & 31)) & 0xffffffff;
321 return (0);
322 }
323
324 return (1);
325}
326
327static
328int val_lt (ini_val_t *dst, ini_val_t *src)
329{
330 if (val_promote2 (dst, src)) {
331 return (1);
332 }
333
334 if (dst->type == INI_VAL_INT) {
335 dst->val.u32 = dst->val.u32 < src->val.u32;
336 return (0);
337 }
338 else if (dst->type == INI_VAL_STR) {
339 ini_val_set_uint32 (dst, strcmp (dst->val.str, src->val.str) < 0);
340 return (0);
341 }
342
343 return (1);
344}
345
346static
347int val_le (ini_val_t *dst, ini_val_t *src)
348{
349 if (val_promote2 (dst, src)) {
350 return (1);
351 }
352
353 if (dst->type == INI_VAL_INT) {
354 dst->val.u32 = dst->val.u32 <= src->val.u32;
355 return (0);
356 }
357 else if (dst->type == INI_VAL_STR) {
358 ini_val_set_uint32 (dst, strcmp (dst->val.str, src->val.str) <= 0);
359 return (0);
360 }
361
362 return (1);
363}
364
365static
366int val_gt (ini_val_t *dst, ini_val_t *src)
367{
368 if (val_promote2 (dst, src)) {
369 return (1);
370 }
371
372 if (dst->type == INI_VAL_INT) {
373 dst->val.u32 = dst->val.u32 > src->val.u32;
374 return (0);
375 }
376 else if (dst->type == INI_VAL_STR) {
377 ini_val_set_uint32 (dst, strcmp (dst->val.str, src->val.str) > 0);
378 return (0);
379 }
380
381 return (1);
382}
383
384static
385int val_ge (ini_val_t *dst, ini_val_t *src)
386{
387 if (val_promote2 (dst, src)) {
388 return (1);
389 }
390
391 if (dst->type == INI_VAL_INT) {
392 dst->val.u32 = dst->val.u32 >= src->val.u32;
393 return (0);
394 }
395 else if (dst->type == INI_VAL_STR) {
396 ini_val_set_uint32 (dst, strcmp (dst->val.str, src->val.str) >= 0);
397 return (0);
398 }
399
400 return (1);
401}
402
403static
404int val_equ (ini_val_t *dst, ini_val_t *src)
405{
406 if (val_promote2 (dst, src)) {
407 return (1);
408 }
409
410 if (dst->type == INI_VAL_INT) {
411 dst->val.u32 = dst->val.u32 == src->val.u32;
412 return (0);
413 }
414 else if (dst->type == INI_VAL_STR) {
415 ini_val_set_uint32 (dst, strcmp (dst->val.str, src->val.str) == 0);
416 return (0);
417 }
418
419 return (1);
420}
421
422static
423int val_neq (ini_val_t *dst, ini_val_t *src)
424{
425 if (val_promote2 (dst, src)) {
426 return (1);
427 }
428
429 if (dst->type == INI_VAL_INT) {
430 dst->val.u32 = dst->val.u32 != src->val.u32;
431 return (0);
432 }
433 else if (dst->type == INI_VAL_STR) {
434 ini_val_set_uint32 (dst, strcmp (dst->val.str, src->val.str) != 0);
435 return (0);
436 }
437
438 return (1);
439}
440
441static
442int val_band (ini_val_t *dst, ini_val_t *src)
443{
444 if (val_promote2 (dst, src)) {
445 return (1);
446 }
447
448 if (dst->type == INI_VAL_INT) {
449 dst->val.u32 = dst->val.u32 & src->val.u32;
450 return (0);
451 }
452
453 return (1);
454}
455
456static
457int val_bxor (ini_val_t *dst, ini_val_t *src)
458{
459 if (val_promote2 (dst, src)) {
460 return (1);
461 }
462
463 if (dst->type == INI_VAL_INT) {
464 dst->val.u32 = dst->val.u32 ^ src->val.u32;
465 return (0);
466 }
467
468 return (1);
469}
470
471static
472int val_bor (ini_val_t *dst, ini_val_t *src)
473{
474 if (val_promote2 (dst, src)) {
475 return (1);
476 }
477
478 if (dst->type == INI_VAL_INT) {
479 dst->val.u32 = dst->val.u32 | src->val.u32;
480 return (0);
481 }
482
483 return (1);
484}
485
486static
487int val_land (ini_val_t *dst, ini_val_t *src)
488{
489 if (val_promote2 (dst, src)) {
490 return (1);
491 }
492
493 if (dst->type == INI_VAL_INT) {
494 dst->val.u32 = (dst->val.u32 != 0) && (src->val.u32 != 0);
495 return (0);
496 }
497
498 return (1);
499}
500
501static
502int val_lor (ini_val_t *dst, ini_val_t *src)
503{
504 if (val_promote2 (dst, src)) {
505 return (1);
506 }
507
508 if (dst->type == INI_VAL_INT) {
509 dst->val.u32 = (dst->val.u32 != 0) || (src->val.u32 != 0);
510 return (0);
511 }
512
513 return (1);
514}
515
516
517static
518int ini_eval_uint (scanner_t *scn, ini_val_t *val)
519{
520 int r;
521 char c;
522 unsigned base;
523 unsigned long v, d;
524
525 if (scn_match (scn, "0x")) {
526 base = 16;
527 }
528 else if (scn_match (scn, "0b")) {
529 base = 2;
530 }
531 else {
532 base = 10;
533 }
534
535 r = 1;
536 v = 0;
537
538 while (1) {
539 c = scn_get_chr (scn, 0);
540
541 if (c == 0) {
542 break;
543 }
544
545 if ((c >= '0') && (c <= '9')) {
546 d = c - '0';
547 }
548 else if ((c >= 'a') && (c <= 'f')) {
549 d = c - 'a' + 10;
550 }
551 else if ((c >= 'A') && (c <= 'F')) {
552 d = c - 'A' + 10;
553 }
554 else {
555 break;
556 }
557
558 if (d >= base) {
559 break;
560 }
561
562 v = base * v + d;
563
564 scn_rmv_chr (scn, 1);
565
566 r = 0;
567 }
568
569 if (r) {
570 return (1);
571 }
572
573 if ((c == 'k') || (c == 'K')) {
574 scn_rmv_chr (scn, 1);
575 v *= 1024;
576 }
577 else if ((c == 'm') || (c == 'M')) {
578 scn_rmv_chr (scn, 1);
579 v *= 1024UL * 1024UL;
580 }
581 else if ((c == 'g') || (c == 'G')) {
582 scn_rmv_chr (scn, 1);
583 v *= 1024UL * 1024UL * 1024UL;
584 }
585
586 ini_val_set_uint32 (val, v);
587
588 return (0);
589}
590
591static
592int ini_eval_literal (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
593{
594 unsigned i;
595 ini_sct_t *tmp;
596 ini_val_t *val2;
597 char str[256];
598
599 if (scn_match (scn, "(")) {
600 if (ini_eval (scn, sct, val)) {
601 return (1);
602 }
603
604 scn_match_space (scn);
605
606 if (scn_match (scn, ")") == 0) {
607 return (1);
608 }
609
610 return (0);
611 }
612
613 if (scn_match_string (scn, str, 256)) {
614 ini_val_set_str (val, str);
615 return (0);
616 }
617
618 if (scn_match_name (scn, str, 256)) {
619 if (strcmp (str, "defined") == 0) {
620 if (ini_eval_literal (scn, sct, val)) {
621 return (1);
622 }
623
624 ini_val_set_uint32 (val, val->type != INI_VAL_NONE);
625
626 return (0);
627 }
628 else if (strcmp (str, "true") == 0) {
629 ini_val_set_uint32 (val, 1);
630 return (0);
631 }
632 else if (strcmp (str, "false") == 0) {
633 ini_val_set_uint32 (val, 0);
634 return (0);
635 }
636 else if (strcmp (str, "yes") == 0) {
637 ini_val_set_uint32 (val, 1);
638 return (0);
639 }
640 else if (strcmp (str, "no") == 0) {
641 ini_val_set_uint32 (val, 0);
642 return (0);
643 }
644
645 i = (str[0] == '$') ? 1 : 0;
646
647 tmp = sct;
648 val2 = NULL;
649
650 while (tmp != NULL) {
651 val2 = ini_get_val (tmp, str + i, 0);
652
653 if (val2 != NULL) {
654 break;
655 }
656
657 tmp = tmp->parent;
658 }
659
660 if (val2 == NULL) {
661 ini_val_set_none (val);
662 return (0);
663 }
664
665 ini_val_copy (val, val2);
666
667 return (0);
668 }
669
670 if (ini_eval_uint (scn, val) == 0) {
671 return (0);
672 }
673
674 return (1);
675}
676
677static
678int ini_eval_neg (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
679{
680 int r;
681 unsigned op;
682
683 if (scn_match (scn, "+")) {
684 op = 1;
685 }
686 else if (scn_match (scn, "-")) {
687 op = 2;
688 }
689 else if (scn_match (scn, "~")) {
690 op = 3;
691 }
692 else if (scn_match (scn, "!")) {
693 op = 4;
694 }
695 else {
696 op = 0;
697 }
698
699 if (ini_eval_literal (scn, sct, val)) {
700 return (1);
701 }
702
703 if (op == 1) {
704 r = val_plus (val);
705 }
706 else if (op == 2) {
707 r = val_neg (val);
708 }
709 else if (op == 3) {
710 r = val_bnot (val);
711 }
712 else if (op == 4) {
713 r = val_lnot (val);
714 }
715 else {
716 r = 0;
717 }
718
719 return (r);
720}
721
722static
723int ini_eval_mul (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
724{
725 int r;
726 unsigned op;
727 ini_val_t val2;
728
729 if (ini_eval_neg (scn, sct, val)) {
730 return (1);
731 }
732
733 while (1) {
734 if (scn_match (scn, "*")) {
735 op = 1;
736 }
737 else if (scn_match (scn, "/")) {
738 op = 2;
739 }
740 else if (scn_match (scn, "%")) {
741 op = 3;
742 }
743 else {
744 return (0);
745 }
746
747 ini_val_init (&val2, NULL);
748
749 if (ini_eval_neg (scn, sct, &val2)) {
750 ini_val_free (&val2);
751 return (1);
752 }
753
754 if (op == 1) {
755 r = val_mul (val, &val2);
756 }
757 else if (op == 2) {
758 r = val_div (val, &val2);
759 }
760 else if (op == 3) {
761 r = val_mod (val, &val2);
762 }
763 else {
764 r = 1;
765 }
766
767 ini_val_free (&val2);
768
769 if (r) {
770 return (1);
771 }
772 }
773}
774
775static
776int ini_eval_add (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
777{
778 int r;
779 unsigned op;
780 ini_val_t val2;
781
782 if (ini_eval_mul (scn, sct, val)) {
783 return (1);
784 }
785
786 while (1) {
787 if (scn_match (scn, "+")) {
788 op = 1;
789 }
790 else if (scn_match (scn, "-")) {
791 op = 2;
792 }
793 else {
794 return (0);
795 }
796
797 ini_val_init (&val2, NULL);
798
799 if (ini_eval_mul (scn, sct, &val2)) {
800 ini_val_free (&val2);
801 return (1);
802 }
803
804 if (op == 1) {
805 r = val_add (val, &val2);
806 }
807 else if (op == 2) {
808 r = val_sub (val, &val2);
809 }
810 else {
811 r = 1;
812 }
813
814 ini_val_free (&val2);
815
816 if (r) {
817 return (1);
818 }
819 }
820}
821
822static
823int ini_eval_shift (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
824{
825 int r;
826 unsigned op;
827 ini_val_t val2;
828
829 if (ini_eval_add (scn, sct, val)) {
830 return (1);
831 }
832
833 while (1) {
834 if (scn_match (scn, "<<")) {
835 op = 1;
836 }
837 else if (scn_match (scn, ">>")) {
838 op = 2;
839 }
840 else {
841 return (0);
842 }
843
844 ini_val_init (&val2, NULL);
845
846 if (ini_eval_add (scn, sct, &val2)) {
847 ini_val_free (&val2);
848 return (1);
849 }
850
851 if (op == 1) {
852 r = val_shl (val, &val2);
853 }
854 else if (op == 2) {
855 r = val_shr (val, &val2);
856 }
857 else {
858 r = 1;
859 }
860
861 ini_val_free (&val2);
862
863 if (r) {
864 return (1);
865 }
866 }
867}
868
869static
870int ini_eval_cmp (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
871{
872 int r;
873 unsigned op;
874 ini_val_t val2;
875
876 if (ini_eval_shift (scn, sct, val)) {
877 return (1);
878 }
879
880 while (1) {
881 if (scn_match (scn, "<=")) {
882 op = 2;
883 }
884 else if (scn_match (scn, ">=")) {
885 op = 4;
886 }
887 else if (scn_match (scn, "<")) {
888 op = 1;
889 }
890 else if (scn_match (scn, ">")) {
891 op = 3;
892 }
893 else {
894 return (0);
895 }
896
897 ini_val_init (&val2, NULL);
898
899 if (ini_eval_shift (scn, sct, &val2)) {
900 ini_val_free (&val2);
901 return (1);
902 }
903
904 if (op == 1) {
905 r = val_lt (val, &val2);
906 }
907 else if (op == 2) {
908 r = val_le (val, &val2);
909 }
910 else if (op == 3) {
911 r = val_gt (val, &val2);
912 }
913 else if (op == 4) {
914 r = val_ge (val, &val2);
915 }
916 else {
917 r = 1;
918 }
919
920 ini_val_free (&val2);
921
922 if (r) {
923 return (1);
924 }
925 }
926}
927
928static
929int ini_eval_equ (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
930{
931 int r;
932 unsigned op;
933 ini_val_t val2;
934
935 if (ini_eval_cmp (scn, sct, val)) {
936 return (1);
937 }
938
939 while (1) {
940 if (scn_match (scn, "==")) {
941 op = 1;
942 }
943 else if (scn_match (scn, "!=")) {
944 op = 2;
945 }
946 else {
947 return (0);
948 }
949
950 ini_val_init (&val2, NULL);
951
952 if (ini_eval_cmp (scn, sct, &val2)) {
953 ini_val_free (&val2);
954 return (1);
955 }
956
957 if (op == 1) {
958 r = val_equ (val, &val2);
959 }
960 else if (op == 2) {
961 r = val_neq (val, &val2);
962 }
963 else {
964 r = 1;
965 }
966
967 ini_val_free (&val2);
968
969 if (r) {
970 return (1);
971 }
972 }
973}
974
975static
976int ini_eval_band (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
977{
978 int r;
979 ini_val_t val2;
980
981 if (ini_eval_equ (scn, sct, val)) {
982 return (1);
983 }
984
985 while (1) {
986 if (scn_peek (scn, "&&")) {
987 return (0);
988 }
989
990 if (scn_match (scn, "&") == 0) {
991 return (0);
992 }
993
994 ini_val_init (&val2, NULL);
995
996 if (ini_eval_equ (scn, sct, &val2)) {
997 ini_val_free (&val2);
998 return (1);
999 }
1000
1001 r = val_band (val, &val2);
1002
1003 ini_val_free (&val2);
1004
1005 if (r) {
1006 return (1);
1007 }
1008 }
1009}
1010
1011static
1012int ini_eval_bxor (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
1013{
1014 int r;
1015 ini_val_t val2;
1016
1017 if (ini_eval_band (scn, sct, val)) {
1018 return (1);
1019 }
1020
1021 while (1) {
1022 if (scn_peek (scn, "^^")) {
1023 return (0);
1024 }
1025
1026 if (scn_match (scn, "^") == 0) {
1027 return (0);
1028 }
1029
1030 ini_val_init (&val2, NULL);
1031
1032 if (ini_eval_band (scn, sct, &val2)) {
1033 ini_val_free (&val2);
1034 return (1);
1035 }
1036
1037 r = val_bxor (val, &val2);
1038
1039 ini_val_free (&val2);
1040
1041 if (r) {
1042 return (1);
1043 }
1044 }
1045}
1046
1047static
1048int ini_eval_bor (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
1049{
1050 int r;
1051 ini_val_t val2;
1052
1053 if (ini_eval_bxor (scn, sct, val)) {
1054 return (1);
1055 }
1056
1057 while (1) {
1058 if (scn_peek (scn, "||")) {
1059 return (0);
1060 }
1061
1062 if (scn_match (scn, "|") == 0) {
1063 return (0);
1064 }
1065
1066 ini_val_init (&val2, NULL);
1067
1068 if (ini_eval_bxor (scn, sct, &val2)) {
1069 ini_val_free (&val2);
1070 return (1);
1071 }
1072
1073 r = val_bor (val, &val2);
1074
1075 ini_val_free (&val2);
1076
1077 if (r) {
1078 return (1);
1079 }
1080 }
1081}
1082
1083static
1084int ini_eval_land (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
1085{
1086 int r;
1087 ini_val_t val2;
1088
1089 if (ini_eval_bor (scn, sct, val)) {
1090 return (1);
1091 }
1092
1093 while (1) {
1094 if (scn_match (scn, "&&") == 0) {
1095 return (0);
1096 }
1097
1098 ini_val_init (&val2, NULL);
1099
1100 if (ini_eval_bor (scn, sct, &val2)) {
1101 ini_val_free (&val2);
1102 return (1);
1103 }
1104
1105 r = val_land (val, &val2);
1106
1107 ini_val_free (&val2);
1108
1109 if (r) {
1110 return (1);
1111 }
1112 }
1113}
1114
1115static
1116int ini_eval_lor (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
1117{
1118 int r;
1119 ini_val_t val2;
1120
1121 if (ini_eval_land (scn, sct, val)) {
1122 return (1);
1123 }
1124
1125 while (1) {
1126 if (scn_match (scn, "||") == 0) {
1127 return (0);
1128 }
1129
1130 ini_val_init (&val2, NULL);
1131
1132 if (ini_eval_land (scn, sct, &val2)) {
1133 ini_val_free (&val2);
1134 return (1);
1135 }
1136
1137 r = val_lor (val, &val2);
1138
1139 ini_val_free (&val2);
1140
1141 if (r) {
1142 return (1);
1143 }
1144 }
1145}
1146
1147static
1148int ini_eval_cond (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
1149{
1150 ini_val_t val2;
1151 ini_val_t *v1, *v2;
1152
1153 if (ini_eval_lor (scn, sct, val)) {
1154 return (1);
1155 }
1156
1157 if (scn_match (scn, "?") == 0) {
1158 return (0);
1159 }
1160
1161 val_promote1 (val);
1162
1163 ini_val_init (&val2, NULL);
1164
1165 if ((val->type == INI_VAL_INT) && (val->val.u32 != 0)) {
1166 v1 = val;
1167 v2 = &val2;
1168 }
1169 else if ((val->type == INI_VAL_STR) && (val->val.str[0] != 0)) {
1170 v1 = val;
1171 v2 = &val2;
1172 }
1173 else {
1174 v1 = &val2;
1175 v2 = val;
1176 }
1177
1178 if (ini_eval_lor (scn, sct, v1)) {
1179 ini_val_free (&val2);
1180 return (1);
1181 }
1182
1183 if (scn_match (scn, ":") == 0) {
1184 ini_val_free (&val2);
1185 return (1);
1186 }
1187
1188 if (ini_eval_lor (scn, sct, v2)) {
1189 ini_val_free (&val2);
1190 return (1);
1191 }
1192
1193 ini_val_free (&val2);
1194
1195 return (0);
1196}
1197
1198int ini_eval (scanner_t *scn, ini_sct_t *sct, ini_val_t *val)
1199{
1200 if (ini_eval_cond (scn, sct, val)) {
1201 return (1);
1202 }
1203
1204 return (0);
1205}