fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1205 lines 19 kB view raw
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}