vm: fix potential null deref
[minix.git] / commands / mdb / mdbexp.c
blob1d16cb7ea9a428df11c58e87fea942de30be4739
1 /*
2 * mdbexp.c - MINIX expresion parser
4 * Written by Bruce D. Szablak
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.
12 #include "mdb.h"
13 #include <ctype.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "proto.h"
19 static long value(char *s , char **s_p , int *seg_p );
20 static long lookup(char *s , char **s_p , int *seg_p );
22 #define idchar(c) (isalpha(c) || isdigit(c) || (c) == '_')
24 /*
25 * Get an expression for mdb
27 char *getexp(buf, exp_p, seg_p)
28 char *buf;
29 int *seg_p;
30 long *exp_p;
32 long v = 0L;
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;
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);
56 /*
57 * Get value
59 * \c escaped characters
60 * digits number
61 * $xx registers
62 * \n 0L
63 * then calls lookup for symbols
65 static long value(s, s_p, seg_p)
66 char *s, **s_p;
67 int *seg_p;
69 long k;
71 if (*s == '\'') { /* handle character constants here */
72 *s_p = s + 2;
73 return s[1];
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);
85 if (*s == '\n') {
86 *s_p = s + 1;
87 return 0L;
89 return lookup(s, s_p, seg_p);
92 /*
93 * Lookup symbol - return value
94 * Handle special cases: _start T: D: S:
95 * then call symbolvalue()
97 static long lookup(s, s_p, seg_p)
98 char *s, **s_p;
99 int *seg_p;
101 long value;
102 char c;
103 int l;
105 for (l = 1; idchar(s[l]); ++l) {}
106 c = s[l];
107 s[l] = 0;
109 if (strcmp("_start", s) == 0) {
110 *seg_p = T;
111 if (c == ':') c = '+';
112 *(*s_p = s + 6) = c;
113 return st_addr;
115 if (strcmp("T", s) == 0) {
116 *seg_p = T;
117 if (c == ':') c = '+';
118 *(*s_p = s + 1) = c;
119 return st_addr;
121 if (strcmp("D", s) == 0) {
122 *seg_p = D;
123 if (c == ':') c = '+';
124 *(*s_p = s + 1) = c;
125 return sd_addr;
127 if (strcmp("S", s) == 0) {
128 *seg_p = S;
129 if (c == ':') c = '+';
130 *(*s_p = s + 1) = c;
131 return sk_addr;
134 if ((value = symbolvalue(s, TRUE)) != 0L) {
135 *seg_p = T;
136 *(*s_p = s + l) = c;
137 return value;
140 if ((value = symbolvalue(s, FALSE)) != 0L) {
141 *seg_p = D;
142 *(*s_p = s + l) = c;
143 return value;
146 Printf("%s: ", s);
147 mdb_error("symbol not found\n");
150 /* Skip spaces */
151 char *skip(s)
152 register char *s;
154 while (isspace(*s)) ++s;
155 return *s ? s : s - 1;