fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1327 lines 20 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/lib/cmd.c * 7 * Created: 2003-11-08 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2003-2009 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 <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26 27#include "console.h" 28#include "cmd.h" 29 30 31typedef struct { 32 char *name; 33 unsigned long val; 34} cmd_sym_t; 35 36 37static void *cmd_get_sym_ext = NULL; 38static int (*cmd_get_sym_fct) (void *ext, const char *sym, unsigned long *val); 39 40static void *cmd_set_sym_ext = NULL; 41static int (*cmd_set_sym_fct) (void *ext, const char *sym, unsigned long val); 42 43static unsigned cmd_sym_cnt = 0; 44static cmd_sym_t *cmd_sym = NULL; 45 46 47static 48int str_is_space (char c) 49{ 50 if ((c == ' ') || (c == '\t')) { 51 return (1); 52 } 53 54 if ((c == '\n') || (c == '\r')) { 55 return (1); 56 } 57 58 return (0); 59} 60 61static 62char *str_ltrim (char *str) 63{ 64 unsigned i, j; 65 66 i = 0; 67 j = 0; 68 69 while ((str[i] != 0) && str_is_space (str[i])) { 70 i += 1; 71 } 72 73 if (i == 0) { 74 return (str); 75 } 76 77 while (str[i] != 0) { 78 str[j] = str[i]; 79 i += 1; 80 j += 1; 81 } 82 83 str[j] = 0; 84 85 return (str); 86} 87 88static 89char *str_rtrim (char *str) 90{ 91 unsigned i, j; 92 93 i = 0; j = 0; 94 95 while (str[i] != 0) { 96 if ((str[i] != ' ') && (str[i] != '\t') && (str[i] != '\n')) { 97 j = i + 1; 98 } 99 i++; 100 } 101 102 str[j] = 0; 103 104 return (str); 105} 106 107void cmd_get (cmd_t *cmd, const char *prompt) 108{ 109 if (prompt == NULL) { 110 prompt = "-"; 111 } 112 113 pce_gets (prompt, cmd->str, PCE_CMD_MAX); 114 115 str_ltrim (cmd->str); 116 str_rtrim (cmd->str); 117 118 cmd->i = 0; 119} 120 121void cmd_set_str (cmd_t *cmd, const char *str) 122{ 123 unsigned i; 124 125 cmd->i = 0; 126 127 for (i = 0; i < PCE_CMD_MAX; i++) { 128 cmd->str[i] = str[i]; 129 130 if (str[i] == 0) { 131 return; 132 } 133 } 134 135 cmd->str[PCE_CMD_MAX - 1] = 0; 136} 137 138void cmd_rewind (cmd_t *cmd) 139{ 140 cmd->i = 0; 141} 142 143const char *cmd_get_str (cmd_t *cmd) 144{ 145 return (cmd->str + cmd->i); 146} 147 148int cmd_get_sym (cmd_t *cmd, const char *sym, unsigned long *val) 149{ 150 unsigned i; 151 const char *str; 152 153 str = sym; 154 155 if ((str[0] == '%') || (str[0] == '$')) { 156 str += 1; 157 } 158 159 if (sym[0] != '$') { 160 if (cmd_get_sym_fct != NULL) { 161 if (cmd_get_sym_fct (cmd_get_sym_ext, str, val) == 0) { 162 return (0); 163 } 164 } 165 166 if (sym[0] == '%') { 167 return (1); 168 } 169 } 170 171 for (i = 0; i < cmd_sym_cnt; i++) { 172 if (strcmp (cmd_sym[i].name, str) == 0) { 173 *val = cmd_sym[i].val; 174 return (0); 175 } 176 } 177 178 return (1); 179} 180 181int cmd_set_sym (cmd_t *cmd, const char *sym, unsigned long val) 182{ 183 unsigned i; 184 const char *str; 185 cmd_sym_t *tmp; 186 187 str = sym; 188 189 if ((str[0] == '%') || (str[0] == '$')) { 190 str += 1; 191 } 192 193 if (sym[0] != '$') { 194 if (cmd_set_sym_fct != NULL) { 195 if (cmd_set_sym_fct (cmd_set_sym_ext, str, val) == 0) { 196 return (0); 197 } 198 } 199 200 if (sym[0] == '%') { 201 return (1); 202 } 203 } 204 205 for (i = 0; i < cmd_sym_cnt; i++) { 206 if (strcmp (cmd_sym[i].name, str) == 0) { 207 cmd_sym[i].val = val; 208 return (0); 209 } 210 } 211 212 tmp = realloc (cmd_sym, (cmd_sym_cnt + 1) * sizeof (cmd_sym_t)); 213 if (tmp == NULL) { 214 return (1); 215 } 216 217 i = cmd_sym_cnt; 218 while (i > 0) { 219 if (strcmp (tmp[i - 1].name, str) < 0) { 220 break; 221 } 222 223 tmp[i] = tmp[i - 1]; 224 225 i -= 1; 226 } 227 228 tmp[i].name = strdup (str); 229 tmp[i].val = val; 230 231 cmd_sym = tmp; 232 cmd_sym_cnt += 1; 233 234 return (0); 235} 236 237void cmd_del_sym (cmd_t *cmd, const char *sym, unsigned long *val) 238{ 239 unsigned i, j; 240 241 if (sym[0] == '%') { 242 return; 243 } 244 245 if (sym[0] == '$') { 246 sym += 1; 247 } 248 249 *val = 0; 250 251 j = 0; 252 253 for (i = 0; i < cmd_sym_cnt; i++) { 254 if (strcmp (cmd_sym[i].name, sym) == 0) { 255 *val = cmd_sym[i].val; 256 free (cmd_sym[i].name); 257 } 258 else { 259 cmd_sym[j] = cmd_sym[i]; 260 j += 1; 261 } 262 } 263 264 cmd_sym_cnt = j; 265} 266 267void cmd_list_syms (cmd_t *cmd) 268{ 269 unsigned i, k, n; 270 271 n = 0; 272 for (i = 0; i < cmd_sym_cnt; i++) { 273 k = strlen (cmd_sym[i].name); 274 if (k > n) { 275 n = k; 276 } 277 } 278 279 n += 1; 280 281 for (i = 0; i < cmd_sym_cnt; i++) { 282 k = strlen (cmd_sym[i].name); 283 284 pce_printf ("$%s", cmd_sym[i].name); 285 286 while (k < n) { 287 pce_puts (" "); 288 k += 1; 289 } 290 291 pce_printf ("= %08lX\n", cmd_sym[i].val); 292 } 293} 294 295void cmd_error (cmd_t *cmd, const char *str) 296{ 297 pce_printf ("*** %s [%s]\n", str, cmd->str + cmd->i); 298} 299 300int cmd_match_space (cmd_t *cmd) 301{ 302 int r; 303 unsigned i; 304 305 i = cmd->i; 306 307 while (cmd->str[i] != 0) { 308 if (str_is_space (cmd->str[i])) { 309 i += 1; 310 } 311 else if (cmd->str[i] == '#') { 312 while (cmd->str[i] != 0) { 313 i += 1; 314 } 315 } 316 else { 317 break; 318 } 319 } 320 321 r = (i > cmd->i); 322 323 cmd->i = i; 324 325 return (r); 326} 327 328static 329int str_is_ident (char c) 330{ 331 if ((c >= '0') && (c <= '9')) { 332 return (1); 333 } 334 335 if ((c >= 'a') && (c <= 'z')) { 336 return (1); 337 } 338 339 if ((c >= 'A') && (c <= 'Z')) { 340 return (1); 341 } 342 343 if (c == '_') { 344 return (1); 345 } 346 347 return (0); 348} 349 350int cmd_match_ident (cmd_t *cmd, char *str, unsigned max) 351{ 352 unsigned i, n; 353 354 cmd_match_space (cmd); 355 356 i = cmd->i; 357 n = 0; 358 359 switch (cmd->str[cmd->i]) { 360 case '%': 361 case '$': 362 *(str++) = cmd->str[cmd->i]; 363 i += 1; 364 n += 1; 365 break; 366 } 367 368 while (cmd->str[i] != 0) { 369 if (str_is_ident (cmd->str[i]) == 0) { 370 break; 371 } 372 373 *(str++) = cmd->str[i]; 374 i += 1; 375 n += 1; 376 377 if (n >= max) { 378 cmd_error (cmd, "identifier too long"); 379 return (0); 380 } 381 } 382 383 *str = 0; 384 385 cmd->i = i; 386 387 return (n > 0); 388} 389 390int cmd_match_str (cmd_t *cmd, char *str, unsigned max) 391{ 392 unsigned i, n; 393 int quote; 394 395 cmd_match_space (cmd); 396 397 i = cmd->i; 398 n = 0; 399 400 if (cmd->str[i] == '"') { 401 quote = 1; 402 i += 1; 403 } 404 else { 405 quote = 0; 406 } 407 408 while (cmd->str[i] != 0) { 409 if (quote) { 410 if (cmd->str[i] == '"') { 411 i += 1; 412 break; 413 } 414 } 415 else { 416 if (str_is_space (cmd->str[i])) { 417 break; 418 } 419 } 420 421 *(str++) = cmd->str[i]; 422 i += 1; 423 n += 1; 424 425 if (n >= max) { 426 cmd_error (cmd, "string too long"); 427 return (0); 428 } 429 } 430 431 *str = 0; 432 433 cmd->i = i; 434 435 return (n > 0); 436} 437 438int cmd_match_eol (cmd_t *cmd) 439{ 440 cmd_match_space (cmd); 441 442 if (cmd->str[cmd->i] == 0) { 443 return (1); 444 } 445 446 return (0); 447} 448 449int cmd_match_end (cmd_t *cmd) 450{ 451 if (cmd_match_eol (cmd)) { 452 return (1); 453 } 454 455 cmd_error (cmd, "syntax error"); 456 457 return (0); 458} 459 460int cmd_match (cmd_t *cmd, const char *str) 461{ 462 unsigned i; 463 464 cmd_match_space (cmd); 465 466 i = cmd->i; 467 468 while ((*str != 0) && (cmd->str[i] == *str)) { 469 i += 1; 470 str += 1; 471 } 472 473 if (*str != 0) { 474 return (0); 475 } 476 477 cmd->i = i; 478 479 return (1); 480} 481 482static 483int cmd_peek (cmd_t *cmd, const char *str) 484{ 485 unsigned i, s; 486 487 s = cmd->i; 488 489 cmd_match_space (cmd); 490 491 i = cmd->i; 492 493 while ((*str != 0) && (cmd->str[i] == *str)) { 494 i += 1; 495 str += 1; 496 } 497 498 if (*str != 0) { 499 return (0); 500 } 501 502 cmd->i = s; 503 504 return (1); 505} 506 507static 508int cmd_match_expr_const (cmd_t *cmd, unsigned long *val, unsigned base) 509{ 510 unsigned i; 511 unsigned cnt; 512 unsigned long ret; 513 514 cmd_match_space (cmd); 515 516 i = cmd->i; 517 518 ret = 0; 519 cnt = 0; 520 521 while (cmd->str[i] != 0) { 522 unsigned dig; 523 524 if ((cmd->str[i] >= '0') && (cmd->str[i] <= '9')) { 525 dig = cmd->str[i] - '0'; 526 } 527 else if ((cmd->str[i] >= 'a') && (cmd->str[i] <= 'f')) { 528 dig = cmd->str[i] - 'a' + 10; 529 } 530 else if ((cmd->str[i] >= 'A') && (cmd->str[i] <= 'F')) { 531 dig = cmd->str[i] - 'A' + 10; 532 } 533 else { 534 break; 535 } 536 537 if (dig >= base) { 538 break; 539 } 540 541 ret = (base * ret + dig) & 0xffffffff; 542 543 cnt += 1; 544 i += 1; 545 } 546 547 if (cnt == 0) { 548 return (0); 549 } 550 551 cmd->i = i; 552 *val = ret; 553 554 return (1); 555} 556 557static 558int cmd_match_expr_literal (cmd_t *cmd, unsigned long *val, unsigned base) 559{ 560 unsigned i; 561 char str[256]; 562 563 cmd_match_space (cmd); 564 565 i = cmd->i; 566 567 if (cmd_match_ident (cmd, str, 256)) { 568 /* 569 * If the identifier does not start with '%' or '$', check 570 * if it could be a constant. 571 */ 572 if ((str[0] != '%') && (str[0] != '$')) { 573 unsigned t; 574 575 t = cmd->i; 576 cmd->i = i; 577 578 if (cmd_match_expr_const (cmd, val, base)) { 579 /* check if the constant is at least as long 580 as the identifier. */ 581 if (cmd->i >= t) { 582 return (1); 583 } 584 } 585 586 cmd->i = t; 587 } 588 589 if (cmd_get_sym (cmd, str, val) == 0) { 590 return (1); 591 } 592 593 cmd->i = i; 594 } 595 596 if (cmd_match (cmd, "(")) { 597 if (cmd_match_expr (cmd, val, base)) { 598 if (cmd_match (cmd, ")")) { 599 return (1); 600 } 601 } 602 603 cmd->i = i; 604 605 return (0); 606 } 607 608 if (cmd_match_expr_const (cmd, val, base)) { 609 return (1); 610 } 611 612 return (0); 613} 614 615static 616int cmd_match_expr_neg (cmd_t *cmd, unsigned long *val, unsigned base) 617{ 618 unsigned i; 619 unsigned op; 620 621 i = cmd->i; 622 623 if (cmd_match (cmd, "!")) { 624 op = 1; 625 } 626 else if (cmd_match (cmd, "~")) { 627 op = 2; 628 } 629 else if (cmd_match (cmd, "+")) { 630 op = 3; 631 } 632 else if (cmd_match (cmd, "-")) { 633 op = 4; 634 } 635 else { 636 op = 0; 637 } 638 639 if (cmd_match_expr_literal (cmd, val, base) == 0) { 640 cmd->i = i; 641 return (0); 642 } 643 644 if (op == 1) { 645 *val = !*val; 646 } 647 else if (op == 2) { 648 *val = ~*val & 0xffffffff; 649 } 650 else if (op == 3) { 651 ; 652 } 653 else if (op == 4) { 654 *val = -*val & 0xffffffff; 655 } 656 657 return (1); 658} 659 660static 661int cmd_match_expr_product (cmd_t *cmd, unsigned long *val, unsigned base) 662{ 663 unsigned i; 664 unsigned op; 665 unsigned long val2; 666 667 i = cmd->i; 668 669 if (cmd_match_expr_neg (cmd, val, base) == 0) { 670 return (0); 671 } 672 673 while (1) { 674 if (cmd_match (cmd, "*")) { 675 op = 1; 676 } 677 else if (cmd_match (cmd, "/")) { 678 op = 2; 679 } 680 else if (cmd_match (cmd, "%")) { 681 op = 3; 682 } 683 else { 684 return (1); 685 } 686 687 if (cmd_match_expr_neg (cmd, &val2, base) == 0) { 688 cmd->i = i; 689 return (0); 690 } 691 692 if (op == 1) { 693 *val = (*val * val2) & 0xffffffff; 694 } 695 else if (op == 2) { 696 if (val2 != 0) { 697 *val = *val / val2; 698 } 699 else { 700 *val = 0xffffffff; 701 } 702 } 703 else { 704 if (val2 != 0) { 705 *val = *val % val2; 706 } 707 else { 708 *val = 0; 709 } 710 } 711 } 712 713 return (0); 714} 715 716static 717int cmd_match_expr_sum (cmd_t *cmd, unsigned long *val, unsigned base) 718{ 719 unsigned i; 720 unsigned op; 721 unsigned long val2; 722 723 i = cmd->i; 724 725 if (cmd_match_expr_product (cmd, val, base) == 0) { 726 return (0); 727 } 728 729 while (1) { 730 if (cmd_match (cmd, "+")) { 731 op = 1; 732 } 733 else if (cmd_match (cmd, "-")) { 734 op = 2; 735 } 736 else { 737 return (1); 738 } 739 740 if (cmd_match_expr_product (cmd, &val2, base) == 0) { 741 cmd->i = i; 742 return (0); 743 } 744 745 if (op == 1) { 746 *val = (*val + val2) & 0xffffffff; 747 } 748 else { 749 *val = (*val - val2) & 0xffffffff; 750 } 751 } 752 753 return (0); 754} 755 756static 757int cmd_match_expr_shift (cmd_t *cmd, unsigned long *val, unsigned base) 758{ 759 unsigned i; 760 unsigned op; 761 unsigned long val2; 762 763 i = cmd->i; 764 765 if (cmd_match_expr_sum (cmd, val, base) == 0) { 766 return (0); 767 } 768 769 while (1) { 770 if (cmd_match (cmd, "<<<")) { 771 op = 1; 772 } 773 else if (cmd_match (cmd, ">>>")) { 774 op = 2; 775 } 776 else if (cmd_match (cmd, "<<")) { 777 op = 3; 778 } 779 else if (cmd_match (cmd, ">>")) { 780 op = 4; 781 } 782 else { 783 return (1); 784 } 785 786 if (cmd_match_expr_sum (cmd, &val2, base) == 0) { 787 cmd->i = i; 788 return (0); 789 } 790 791 val2 &= 0x1f; 792 793 if (op == 1) { 794 *val = (*val << val2) | (*val >> (32 - val2)); 795 } 796 else if (op == 2) { 797 *val = (*val >> val2) | (*val << (32 - val2)); 798 } 799 else if (op == 3) { 800 *val = *val << val2; 801 } 802 else if (op == 4) { 803 *val = *val >> val2; 804 } 805 806 *val &= 0xffffffff; 807 } 808 809 return (0); 810} 811 812static 813int cmd_match_expr_cmp (cmd_t *cmd, unsigned long *val, unsigned base) 814{ 815 unsigned i; 816 unsigned op; 817 unsigned long val2; 818 819 i = cmd->i; 820 821 if (cmd_match_expr_shift (cmd, val, base) == 0) { 822 return (0); 823 } 824 825 while (1) { 826 if (cmd_match (cmd, "<=")) { 827 op = 1; 828 } 829 else if (cmd_match (cmd, "<")) { 830 op = 2; 831 } 832 else if (cmd_match (cmd, ">=")) { 833 op = 3; 834 } 835 else if (cmd_match (cmd, ">")) { 836 op = 4; 837 } 838 else { 839 return (1); 840 } 841 842 if (cmd_match_expr_shift (cmd, &val2, base) == 0) { 843 cmd->i = i; 844 return (0); 845 } 846 847 if (op == 1) { 848 *val = *val <= val2; 849 } 850 else if (op == 2) { 851 *val = *val < val2; 852 } 853 else if (op == 3) { 854 *val = *val >= val2; 855 } 856 else if (op == 4) { 857 *val = *val > val2; 858 } 859 } 860 861 return (0); 862} 863 864static 865int cmd_match_expr_equ (cmd_t *cmd, unsigned long *val, unsigned base) 866{ 867 unsigned i; 868 unsigned op; 869 unsigned long val2; 870 871 i = cmd->i; 872 873 if (cmd_match_expr_cmp (cmd, val, base) == 0) { 874 return (0); 875 } 876 877 while (1) { 878 if (cmd_match (cmd, "==")) { 879 op = 1; 880 } 881 else if (cmd_match (cmd, "!=")) { 882 op = 2; 883 } 884 else { 885 return (1); 886 } 887 888 if (cmd_match_expr_cmp (cmd, &val2, base) == 0) { 889 cmd->i = i; 890 return (0); 891 } 892 893 if (op == 1) { 894 *val = *val == val2; 895 } 896 else if (op == 2) { 897 *val = *val != val2; 898 } 899 } 900 901 return (0); 902} 903 904static 905int cmd_match_expr_band (cmd_t *cmd, unsigned long *val, unsigned base) 906{ 907 unsigned i; 908 unsigned op; 909 unsigned long val2; 910 911 i = cmd->i; 912 913 if (cmd_match_expr_equ (cmd, val, base) == 0) { 914 return (0); 915 } 916 917 while (1) { 918 if (cmd_peek (cmd, "&&")) { 919 return (1); 920 } 921 922 if (cmd_match (cmd, "&")) { 923 op = 1; 924 } 925 else { 926 return (1); 927 } 928 929 if (cmd_match_expr_equ (cmd, &val2, base) == 0) { 930 cmd->i = i; 931 return (0); 932 } 933 934 if (op == 1) { 935 *val = *val & val2; 936 } 937 } 938 939 return (0); 940} 941 942static 943int cmd_match_expr_bxor (cmd_t *cmd, unsigned long *val, unsigned base) 944{ 945 unsigned i; 946 unsigned op; 947 unsigned long val2; 948 949 i = cmd->i; 950 951 if (cmd_match_expr_band (cmd, val, base) == 0) { 952 return (0); 953 } 954 955 while (1) { 956 if (cmd_match (cmd, "^")) { 957 op = 1; 958 } 959 else { 960 return (1); 961 } 962 963 if (cmd_match_expr_band (cmd, &val2, base) == 0) { 964 cmd->i = i; 965 return (0); 966 } 967 968 if (op == 1) { 969 *val = *val ^ val2; 970 } 971 } 972 973 return (0); 974} 975 976static 977int cmd_match_expr_bor (cmd_t *cmd, unsigned long *val, unsigned base) 978{ 979 unsigned i; 980 unsigned op; 981 unsigned long val2; 982 983 i = cmd->i; 984 985 if (cmd_match_expr_bxor (cmd, val, base) == 0) { 986 return (0); 987 } 988 989 while (1) { 990 if (cmd_peek (cmd, "||")) { 991 return (1); 992 } 993 994 if (cmd_match (cmd, "|")) { 995 op = 1; 996 } 997 else { 998 return (1); 999 } 1000 1001 if (cmd_match_expr_bxor (cmd, &val2, base) == 0) { 1002 cmd->i = i; 1003 return (0); 1004 } 1005 1006 if (op == 1) { 1007 *val = *val | val2; 1008 } 1009 } 1010 1011 return (0); 1012} 1013 1014static 1015int cmd_match_expr_land (cmd_t *cmd, unsigned long *val, unsigned base) 1016{ 1017 unsigned i; 1018 unsigned op; 1019 unsigned long val2; 1020 1021 i = cmd->i; 1022 1023 if (cmd_match_expr_bor (cmd, val, base) == 0) { 1024 return (0); 1025 } 1026 1027 while (1) { 1028 if (cmd_match (cmd, "&&")) { 1029 op = 1; 1030 } 1031 else { 1032 return (1); 1033 } 1034 1035 if (cmd_match_expr_bor (cmd, &val2, base) == 0) { 1036 cmd->i = i; 1037 return (0); 1038 } 1039 1040 if (op == 1) { 1041 *val = *val && val2; 1042 } 1043 } 1044 1045 return (0); 1046} 1047 1048static 1049int cmd_match_expr_lor (cmd_t *cmd, unsigned long *val, unsigned base) 1050{ 1051 unsigned i; 1052 unsigned op; 1053 unsigned long val2; 1054 1055 i = cmd->i; 1056 1057 if (cmd_match_expr_land (cmd, val, base) == 0) { 1058 return (0); 1059 } 1060 1061 while (1) { 1062 if (cmd_match (cmd, "||")) { 1063 op = 1; 1064 } 1065 else { 1066 return (1); 1067 } 1068 1069 if (cmd_match_expr_land (cmd, &val2, base) == 0) { 1070 cmd->i = i; 1071 return (0); 1072 } 1073 1074 if (op == 1) { 1075 *val = *val || val2; 1076 } 1077 } 1078 1079 return (0); 1080} 1081 1082static 1083int cmd_match_expr_cond (cmd_t *cmd, unsigned long *val, unsigned base) 1084{ 1085 unsigned i; 1086 unsigned long val2, val3; 1087 1088 i = cmd->i; 1089 1090 if (cmd_match_expr_lor (cmd, val, base) == 0) { 1091 return (0); 1092 } 1093 1094 if (cmd_match (cmd, "?") == 0) { 1095 return (1); 1096 } 1097 1098 if (cmd_match_expr_lor (cmd, &val2, base) == 0) { 1099 cmd->i = i; 1100 return (0); 1101 } 1102 1103 if (cmd_match (cmd, ":") == 0) { 1104 cmd->i = i; 1105 return (0); 1106 } 1107 1108 if (cmd_match_expr_lor (cmd, &val3, base) == 0) { 1109 cmd->i = i; 1110 return (0); 1111 } 1112 1113 *val = *val ? val2 : val3; 1114 1115 return (1); 1116} 1117 1118static 1119int cmd_match_expr_assign (cmd_t *cmd, unsigned long *val, unsigned base) 1120{ 1121 unsigned i, j; 1122 unsigned op; 1123 char str[256]; 1124 1125 cmd_match_space (cmd); 1126 1127 i = cmd->i; 1128 1129 if (cmd_match_ident (cmd, str, 256)) { 1130 j = 0; 1131 while (str[j] == '%') { 1132 j += 1; 1133 } 1134 1135 if (cmd_match (cmd, "=")) { 1136 op = 1; 1137 } 1138 else if (cmd_match (cmd, "+=")) { 1139 op = 2; 1140 } 1141 else if (cmd_match (cmd, "-=")) { 1142 op = 3; 1143 } 1144 else if (cmd_match (cmd, "*=")) { 1145 op = 4; 1146 } 1147 else if (cmd_match (cmd, "/=")) { 1148 op = 5; 1149 } 1150 else if (cmd_match (cmd, "<<=")) { 1151 op = 6; 1152 } 1153 else if (cmd_match (cmd, ">>=")) { 1154 op = 7; 1155 } 1156 else if (cmd_match (cmd, "|=")) { 1157 op = 8; 1158 } 1159 else if (cmd_match (cmd, "&=")) { 1160 op = 9; 1161 } 1162 else if (cmd_match (cmd, "^=")) { 1163 op = 10; 1164 } 1165 else { 1166 op = 0; 1167 } 1168 1169 if (op != 0) { 1170 unsigned long tmp; 1171 1172 if (cmd_match (cmd, ";")) { 1173 cmd_del_sym (cmd, str + j, val); 1174 return (1); 1175 } 1176 1177 if (cmd_get_sym (cmd, str + j, val)) { 1178 *val = 0; 1179 } 1180 1181 if (cmd_match_expr_cond (cmd, &tmp, base)) { 1182 switch (op) { 1183 case 1: 1184 *val = tmp; 1185 break; 1186 case 2: 1187 *val += tmp; 1188 break; 1189 case 3: 1190 *val -= tmp; 1191 break; 1192 case 4: 1193 *val *= tmp; 1194 break; 1195 case 5: 1196 if (tmp != 0) { 1197 *val /= tmp; 1198 } 1199 else { 1200 *val = 0xffffffff; 1201 } 1202 break; 1203 case 6: 1204 *val <<= tmp; 1205 break; 1206 case 7: 1207 *val >>= tmp; 1208 break; 1209 case 8: 1210 *val |= tmp; 1211 break; 1212 case 9: 1213 *val &= tmp; 1214 break; 1215 case 10: 1216 *val ^= tmp; 1217 break; 1218 default: 1219 *val = tmp; 1220 break; 1221 } 1222 1223 *val &= 0xffffffff; 1224 1225 cmd_set_sym (cmd, str + j, *val); 1226 1227 return (1); 1228 } 1229 } 1230 } 1231 1232 cmd->i = i; 1233 1234 return (cmd_match_expr_cond (cmd, val, base)); 1235} 1236 1237int cmd_match_expr (cmd_t *cmd, unsigned long *val, unsigned base) 1238{ 1239 while (1) { 1240 if (cmd_match_expr_assign (cmd, val, base) == 0) { 1241 return (0); 1242 } 1243 1244 if (cmd_match (cmd, ",") == 0) { 1245 return (1); 1246 } 1247 } 1248 1249 return (0); 1250} 1251 1252int cmd_match_ulng (cmd_t *cmd, unsigned long *val, unsigned base) 1253{ 1254 if (cmd_match_expr_const (cmd, val, base)) { 1255 return (1); 1256 } 1257 1258 return (0); 1259} 1260 1261int cmd_match_uint (cmd_t *cmd, unsigned *val, unsigned base) 1262{ 1263 unsigned long tmp; 1264 1265 if (cmd_match_expr_const (cmd, &tmp, base)) { 1266 *val = tmp; 1267 return (1); 1268 } 1269 1270 return (0); 1271} 1272 1273int cmd_match_uint16b (cmd_t *cmd, unsigned short *val, unsigned base) 1274{ 1275 unsigned long tmp; 1276 1277 if (cmd_match_expr (cmd, &tmp, base)) { 1278 *val = tmp & 0xffff; 1279 return (1); 1280 } 1281 1282 return (0); 1283} 1284 1285int cmd_match_uint16 (cmd_t *cmd, unsigned short *val) 1286{ 1287 return (cmd_match_uint16b (cmd, val, 16)); 1288} 1289 1290int cmd_match_uint32b (cmd_t *cmd, unsigned long *val, unsigned base) 1291{ 1292 return (cmd_match_expr (cmd, val, base)); 1293} 1294 1295int cmd_match_uint32 (cmd_t *cmd, unsigned long *val) 1296{ 1297 return (cmd_match_uint32b (cmd, val, 16)); 1298} 1299 1300int cmd_match_uint16_16 (cmd_t *cmd, unsigned short *seg, unsigned short *ofs) 1301{ 1302 unsigned short val; 1303 1304 if (!cmd_match_uint16 (cmd, &val)) { 1305 return (0); 1306 } 1307 1308 if (!cmd_match (cmd, ":")) { 1309 *ofs = val; 1310 return (1); 1311 } 1312 1313 *seg = val; 1314 1315 cmd_match_uint16 (cmd, ofs); 1316 1317 return (1); 1318} 1319 1320void cmd_init (void *ext, void *getsym, void *setsym) 1321{ 1322 cmd_get_sym_ext = ext; 1323 cmd_get_sym_fct = getsym; 1324 1325 cmd_set_sym_ext = ext; 1326 cmd_set_sym_fct = setsym; 1327}