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 |
|
---|