0.7.13.5
[sbcl/lichteblau.git] / src / runtime / parse.c
blobcb71dc4cfef4b453cd51d17d5bf2dc5b2ed02b26
1 /* parsing for LDB monitor */
3 /*
4 * This software is part of the SBCL system. See the README file for
5 * more information.
7 * This software is derived from the CMU CL system, which was
8 * written at Carnegie Mellon University and released into the
9 * public domain. The software is in the public domain and is
10 * provided with absolutely no warranty. See the COPYING and CREDITS
11 * files for more information.
14 #include <stdio.h>
15 #include <ctype.h>
16 #include <signal.h>
18 #include "runtime.h"
19 #include "sbcl.h"
21 #if defined(LISP_FEATURE_SB_LDB)
23 #include "globals.h"
24 #include "vars.h"
25 #include "parse.h"
26 #include "os.h"
27 #include "interrupt.h"
28 #include "lispregs.h"
29 #include "monitor.h"
30 #include "arch.h"
31 #include "search.h"
33 #include "genesis/simple-fun.h"
34 #include "genesis/fdefn.h"
35 #include "genesis/symbol.h"
36 #include "genesis/static-symbols.h"
38 static void skip_ws(char **ptr)
40 while (**ptr <= ' ' && **ptr != '\0')
41 (*ptr)++;
44 static boolean string_to_long(char *token, long *value)
46 int base, digit;
47 long num;
48 char *ptr;
50 if (token == 0)
51 return 0;
53 if (token[0] == '0')
54 if (token[1] == 'x') {
55 base = 16;
56 token += 2;
58 else {
59 base = 8;
60 token++;
62 else if (token[0] == '#') {
63 switch (token[1]) {
64 case 'x':
65 case 'X':
66 base = 16;
67 token += 2;
68 break;
69 case 'o':
70 case 'O':
71 base = 8;
72 token += 2;
73 break;
74 default:
75 return 0;
78 else
79 base = 10;
81 num = 0;
82 ptr = token;
83 while (*ptr != '\0') {
84 if (*ptr >= 'a' && *ptr <= 'f')
85 digit = *ptr + 10 - 'a';
86 else if (*ptr >= 'A' && *ptr <= 'F')
87 digit = *ptr + 10 - 'A';
88 else if (*ptr >= '0' && *ptr <= '9')
89 digit = *ptr - '0';
90 else
91 return 0;
92 if (digit < 0 || digit >= base)
93 return 0;
95 ptr++;
96 num = num * base + digit;
99 *value = num;
100 return 1;
103 static boolean lookup_variable(char *name, lispobj *result)
105 struct var *var = lookup_by_name(name);
107 if (var == NULL)
108 return 0;
109 else {
110 *result = var_value(var);
111 return 1;
116 boolean more_p(ptr)
117 char **ptr;
119 skip_ws(ptr);
121 if (**ptr == '\0')
122 return 0;
123 else
124 return 1;
127 char *parse_token(ptr)
128 char **ptr;
130 char *token;
132 skip_ws(ptr);
134 if (**ptr == '\0')
135 return NULL;
137 token = *ptr;
139 while (**ptr > ' ')
140 (*ptr)++;
142 if (**ptr != '\0') {
143 **ptr = '\0';
144 (*ptr)++;
147 return token;
150 #if 0
151 static boolean number_p(token)
152 char *token;
154 char *okay;
156 if (token == NULL)
157 return 0;
159 okay = "abcdefABCDEF987654321d0";
161 if (token[0] == '0')
162 if (token[1] == 'x' || token[1] == 'X')
163 token += 2;
164 else {
165 token++;
166 okay += 14;
168 else if (token[0] == '#') {
169 switch (token[1]) {
170 case 'x':
171 case 'X':
172 break;
173 case 'o':
174 case 'O':
175 okay += 14;
176 break;
177 default:
178 return 0;
181 else
182 okay += 12;
184 while (*token != '\0')
185 if (index(okay, *token++) == NULL)
186 return 0;
187 return 1;
189 #endif
191 long parse_number(ptr)
192 char **ptr;
194 char *token = parse_token(ptr);
195 long result;
197 if (token == NULL) {
198 printf("expected a number\n");
199 throw_to_monitor();
201 else if (string_to_long(token, &result))
202 return result;
203 else {
204 printf("invalid number: ``%s''\n", token);
205 throw_to_monitor();
207 return 0;
210 char *parse_addr(ptr)
211 char **ptr;
213 char *token = parse_token(ptr);
214 long result;
216 if (token == NULL) {
217 printf("expected an address\n");
218 throw_to_monitor();
220 else if (token[0] == '$') {
221 if (!lookup_variable(token+1, (lispobj *)&result)) {
222 printf("unknown variable: ``%s''\n", token);
223 throw_to_monitor();
225 result &= ~7;
227 else {
228 if (!string_to_long(token, &result)) {
229 printf("invalid number: ``%s''\n", token);
230 throw_to_monitor();
232 result &= ~3;
235 if (!is_valid_lisp_addr((os_vm_address_t)result)) {
236 printf("invalid Lisp-level address: 0x%lx\n", result);
237 throw_to_monitor();
240 return (char *)result;
243 static boolean lookup_symbol(char *name, lispobj *result)
245 int count;
246 lispobj *headerptr;
248 /* Search static space. */
249 headerptr = (lispobj *)STATIC_SPACE_START;
250 count =
251 (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER) -
252 (lispobj *)STATIC_SPACE_START;
253 if (search_for_symbol(name, &headerptr, &count)) {
254 *result = make_lispobj(headerptr,OTHER_POINTER_LOWTAG);
255 return 1;
258 /* Search dynamic space. */
259 headerptr = (lispobj *)DYNAMIC_SPACE_START;
260 #if !defined(__i386__)
261 count =
262 dynamic_space_free_pointer -
263 (lispobj *)DYNAMIC_SPACE_START;
264 #else
265 count =
266 (lispobj *)SymbolValue(ALLOCATION_POINTER) -
267 (lispobj *)DYNAMIC_SPACE_START;
268 #endif
269 if (search_for_symbol(name, &headerptr, &count)) {
270 *result = make_lispobj(headerptr, OTHER_POINTER_LOWTAG);
271 return 1;
274 return 0;
277 static int
278 parse_regnum(char *s)
280 if ((s[1] == 'R') || (s[1] == 'r')) {
281 int regnum;
283 if (s[2] == '\0')
284 return -1;
286 /* skip the $R part and call atoi on the number */
287 regnum = atoi(s + 2);
288 if ((regnum >= 0) && (regnum < NREGS))
289 return regnum;
290 else
291 return -1;
292 } else {
293 int i;
295 for (i = 0; i < NREGS ; i++)
296 if (strcasecmp(s + 1, lisp_register_names[i]) == 0)
297 #ifdef __i386__
298 return i*2;
299 #else
300 return i;
301 #endif
303 return -1;
307 lispobj parse_lispobj(ptr)
308 char **ptr;
310 char *token = parse_token(ptr);
311 long pointer;
312 lispobj result;
314 if (token == NULL) {
315 printf("expected an object\n");
316 throw_to_monitor();
317 } else if (token[0] == '$') {
318 if (isalpha(token[1])) {
319 int free;
320 int regnum;
321 os_context_t *context;
323 free = SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX)>>2;
325 if (free == 0) {
326 printf("Variable ``%s'' is not valid -- there is no current interrupt context.\n", token);
327 throw_to_monitor();
330 context = lisp_interrupt_contexts[free - 1];
332 regnum = parse_regnum(token);
333 if (regnum < 0) {
334 printf("bogus register: ``%s''\n", token);
335 throw_to_monitor();
338 result = *os_context_register_addr(context, regnum);
339 } else if (!lookup_variable(token+1, &result)) {
340 printf("unknown variable: ``%s''\n", token);
341 throw_to_monitor();
343 } else if (token[0] == '@') {
344 if (string_to_long(token+1, &pointer)) {
345 pointer &= ~3;
346 if (is_valid_lisp_addr((os_vm_address_t)pointer))
347 result = *(lispobj *)pointer;
348 else {
349 printf("invalid Lisp-level address: ``%s''\n", token+1);
350 throw_to_monitor();
353 else {
354 printf("invalid address: ``%s''\n", token+1);
355 throw_to_monitor();
358 else if (string_to_long(token, (long *)&result))
360 else if (lookup_symbol(token, &result))
362 else {
363 printf("invalid Lisp object: ``%s''\n", token);
364 throw_to_monitor();
367 return result;
370 #endif /* defined(LISP_FEATURE_SB_LDB) */