[9] | 1 | /*
|
---|
| 2 | * mdbexp.c - MINIX expresion parser
|
---|
| 3 | *
|
---|
| 4 | * Written by Bruce D. Szablak
|
---|
| 5 | *
|
---|
| 6 | * This free software is provided for non-commerical use. No warrantee
|
---|
| 7 | * of fitness for any use is implied. You get what you pay for. Anyone
|
---|
| 8 | * may make modifications and distribute them, but please keep this header
|
---|
| 9 | * in the distribution.
|
---|
| 10 | */
|
---|
| 11 |
|
---|
| 12 | #include "mdb.h"
|
---|
| 13 | #include <ctype.h>
|
---|
| 14 | #include <stdio.h>
|
---|
| 15 | #include <stdlib.h>
|
---|
| 16 | #include <string.h>
|
---|
| 17 | #include "proto.h"
|
---|
| 18 |
|
---|
| 19 | FORWARD _PROTOTYPE(long value , (char *s , char **s_p , int *seg_p ));
|
---|
| 20 | FORWARD _PROTOTYPE(long lookup , (char *s , char **s_p , int *seg_p ));
|
---|
| 21 |
|
---|
| 22 | #define idchar(c) (isalpha(c) || isdigit(c) || (c) == '_')
|
---|
| 23 |
|
---|
| 24 | /*
|
---|
| 25 | * Get an expression for mdb
|
---|
| 26 | */
|
---|
| 27 | PUBLIC char *getexp(buf, exp_p, seg_p)
|
---|
| 28 | char *buf;
|
---|
| 29 | int *seg_p;
|
---|
| 30 | long *exp_p;
|
---|
| 31 | {
|
---|
| 32 | long v = 0L;
|
---|
| 33 |
|
---|
| 34 | buf = skip(buf);
|
---|
| 35 | if ((isalpha(*buf) && (isspace(buf[1]) || buf[1] == ';'))
|
---|
| 36 | || *buf == '\n'
|
---|
| 37 | || *buf == ';'
|
---|
| 38 | || *buf == '/'
|
---|
| 39 | || *buf == '!'
|
---|
| 40 | || *buf == '?'
|
---|
| 41 | || *buf == '@'
|
---|
| 42 | || *buf == '#') {
|
---|
| 43 | *exp_p = 0L;
|
---|
| 44 | return buf;
|
---|
| 45 | }
|
---|
| 46 | v = value(buf, &buf, seg_p);
|
---|
| 47 | buf = skip(buf);
|
---|
| 48 | if (*buf == '+')
|
---|
| 49 | v += value(skip(buf + 1), &buf, seg_p);
|
---|
| 50 | else if (*buf == '-')
|
---|
| 51 | v -= value(skip(buf + 1), &buf, seg_p);
|
---|
| 52 | *exp_p = v;
|
---|
| 53 | return skip(buf);
|
---|
| 54 | }
|
---|
| 55 |
|
---|
| 56 | /*
|
---|
| 57 | * Get value
|
---|
| 58 | *
|
---|
| 59 | * \c escaped characters
|
---|
| 60 | * digits number
|
---|
| 61 | * $xx registers
|
---|
| 62 | * \n 0L
|
---|
| 63 | * then calls lookup for symbols
|
---|
| 64 | */
|
---|
| 65 | PRIVATE long value(s, s_p, seg_p)
|
---|
| 66 | char *s, **s_p;
|
---|
| 67 | int *seg_p;
|
---|
| 68 | {
|
---|
| 69 | long k;
|
---|
| 70 |
|
---|
| 71 | if (*s == '\'') { /* handle character constants here */
|
---|
| 72 | *s_p = s + 2;
|
---|
| 73 | return s[1];
|
---|
| 74 | }
|
---|
| 75 | if (*s == '-' || isdigit(*s))
|
---|
| 76 | return strtol(s, s_p, 0);
|
---|
| 77 | if (*s == '$') {
|
---|
| 78 | k = reg_addr(s + 1);
|
---|
| 79 | *s_p = s + 3;
|
---|
| 80 | return get_reg(curpid, k);
|
---|
| 81 | k = reg_addr(s + 1);
|
---|
| 82 | *s_p = s + 3;
|
---|
| 83 | return get_reg(curpid, k);
|
---|
| 84 | }
|
---|
| 85 | if (*s == '\n') {
|
---|
| 86 | *s_p = s + 1;
|
---|
| 87 | return 0L;
|
---|
| 88 | }
|
---|
| 89 | return lookup(s, s_p, seg_p);
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | /*
|
---|
| 93 | * Lookup symbol - return value
|
---|
| 94 | * Handle special cases: _start T: D: S:
|
---|
| 95 | * then call symbolvalue()
|
---|
| 96 | */
|
---|
| 97 | PRIVATE long lookup(s, s_p, seg_p)
|
---|
| 98 | char *s, **s_p;
|
---|
| 99 | int *seg_p;
|
---|
| 100 | {
|
---|
| 101 | long value;
|
---|
| 102 | char c;
|
---|
| 103 | int l;
|
---|
| 104 |
|
---|
| 105 | for (l = 1; idchar(s[l]); ++l) {}
|
---|
| 106 | c = s[l];
|
---|
| 107 | s[l] = 0;
|
---|
| 108 |
|
---|
| 109 | if (strcmp("_start", s) == 0) {
|
---|
| 110 | *seg_p = T;
|
---|
| 111 | if (c == ':') c = '+';
|
---|
| 112 | *(*s_p = s + 6) = c;
|
---|
| 113 | return st_addr;
|
---|
| 114 | }
|
---|
| 115 | if (strcmp("T", s) == 0) {
|
---|
| 116 | *seg_p = T;
|
---|
| 117 | if (c == ':') c = '+';
|
---|
| 118 | *(*s_p = s + 1) = c;
|
---|
| 119 | return st_addr;
|
---|
| 120 | }
|
---|
| 121 | if (strcmp("D", s) == 0) {
|
---|
| 122 | *seg_p = D;
|
---|
| 123 | if (c == ':') c = '+';
|
---|
| 124 | *(*s_p = s + 1) = c;
|
---|
| 125 | return sd_addr;
|
---|
| 126 | }
|
---|
| 127 | if (strcmp("S", s) == 0) {
|
---|
| 128 | *seg_p = S;
|
---|
| 129 | if (c == ':') c = '+';
|
---|
| 130 | *(*s_p = s + 1) = c;
|
---|
| 131 | return sk_addr;
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | if ((value = symbolvalue(s, TRUE)) != 0L) {
|
---|
| 135 | *seg_p = T;
|
---|
| 136 | *(*s_p = s + l) = c;
|
---|
| 137 | return value;
|
---|
| 138 | }
|
---|
| 139 |
|
---|
| 140 | if ((value = symbolvalue(s, FALSE)) != 0L) {
|
---|
| 141 | *seg_p = D;
|
---|
| 142 | *(*s_p = s + l) = c;
|
---|
| 143 | return value;
|
---|
| 144 | }
|
---|
| 145 |
|
---|
| 146 | Printf("%s: ", s);
|
---|
| 147 | mdb_error("symbol not found\n");
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | /* Skip spaces */
|
---|
| 151 | PUBLIC char *skip(s)
|
---|
| 152 | register char *s;
|
---|
| 153 | {
|
---|
| 154 | while (isspace(*s)) ++s;
|
---|
| 155 | return *s ? s : s - 1;
|
---|
| 156 | }
|
---|
| 157 |
|
---|