Too many changes and fixes to mention them all here
This commit is contained in:
		
							parent
							
								
									7f8a099a15
								
							
						
					
					
						commit
						3672f835fe
					
				
					 23 changed files with 942 additions and 426 deletions
				
			
		|  | @ -61,6 +61,7 @@ CSRC = { | |||
| 	value.c, | ||||
| 	type.c, | ||||
| 	rd.c, | ||||
| 	help.c, | ||||
| 	modula-2.c, | ||||
| 	c.c | ||||
| } ; | ||||
|  | @ -101,7 +102,7 @@ LIBRARIES = { | |||
| 	$EMHOME/modules/lib/libsystem.a | ||||
| } ; | ||||
| 
 | ||||
| DBFLAGS = { -g, -DDEBUG } ; | ||||
| DBFLAGS = { -O, -DDEBUG } ; | ||||
| PROFFLAGS = { } ; | ||||
| 
 | ||||
| LDFLAGS = { | ||||
|  |  | |||
|  | @ -57,8 +57,8 @@ static struct langdep c = { | |||
| 	print_string, | ||||
| 	print_char, | ||||
| 	array_elsize, | ||||
| 	unop_prio, | ||||
| 	binop_prio, | ||||
| 	unop_prio, | ||||
| 	get_string, | ||||
| 	get_name, | ||||
| 	get_number, | ||||
|  | @ -69,11 +69,46 @@ static struct langdep c = { | |||
| 
 | ||||
| struct langdep *c_dep = &c; | ||||
| 
 | ||||
| static int | ||||
| printchar(c, esc) | ||||
|   int	c; | ||||
| { | ||||
|   switch(c) { | ||||
|   case '\n': | ||||
| 	fputs("\\n", db_out); | ||||
| 	break; | ||||
|   case '\t': | ||||
| 	fputs("\\t", db_out); | ||||
| 	break; | ||||
|   case '\b': | ||||
| 	fputs("\\b", db_out); | ||||
| 	break; | ||||
|   case '\r': | ||||
| 	fputs("\\r", db_out); | ||||
| 	break; | ||||
|   case '\f': | ||||
| 	fputs("\\f", db_out); | ||||
| 	break; | ||||
|   case '\\': | ||||
| 	fputs("\\\\", db_out); | ||||
| 	break; | ||||
|   case '\'': | ||||
|   case '"': | ||||
| 	fprintf(db_out, c == esc ? "\\%c" : "%c", c); | ||||
| 	break; | ||||
|   default: | ||||
|   	fprintf(db_out, (c >= 040 && c < 0177) ? "%c" : "\\%03o", c); | ||||
| 	break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| print_char(c) | ||||
|   int	c; | ||||
| { | ||||
|   fprintf(db_out, (c >= 040 && c < 0177) ? "'%c'" : "'\\0%o'", c); | ||||
|   fputc('\'', db_out); | ||||
|   printchar(c, '\''); | ||||
|   fputc('\'', db_out); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
|  | @ -82,12 +117,10 @@ print_string(s, len) | |||
|   int	len; | ||||
| { | ||||
|   register char	*str = s; | ||||
|   int delim = '\''; | ||||
| 
 | ||||
|   while (*str) { | ||||
| 	if (*str++ == '\'') delim = '"'; | ||||
|   } | ||||
|   fprintf(db_out, "%c%.*s%c", delim, len, s, delim); | ||||
|   fputc('"', db_out); | ||||
|   while (*str && len-- > 0) printchar(*str++, '"'); | ||||
|   fputc('"', db_out); | ||||
| } | ||||
| 
 | ||||
| extern long	int_size; | ||||
|  | @ -110,7 +143,6 @@ unop_prio(op) | |||
|   case E_BNOT: | ||||
|   case E_MIN: | ||||
|   case E_DEREF: | ||||
|   case E_SELECT: | ||||
|   case E_PLUS: | ||||
|   case E_ADDR: | ||||
| 	return 12; | ||||
|  | @ -153,6 +185,11 @@ binop_prio(op) | |||
|   case E_MOD: | ||||
|   case E_ZMOD: | ||||
| 	return 11; | ||||
|   case E_ARRAY: | ||||
|   case E_SELECT: | ||||
| 	return 12; | ||||
|   case E_DERSELECT: | ||||
| 	return 13; | ||||
|   } | ||||
|   return 1; | ||||
| } | ||||
|  | @ -236,15 +273,19 @@ get_token(c) | |||
|   register int	c; | ||||
| { | ||||
|   switch(c) { | ||||
|   case '[': | ||||
| 	tok.ival = E_ARRAY; | ||||
| 	/* fall through */ | ||||
|   case '(': | ||||
|   case ')': | ||||
|   case '[': | ||||
|   case ']': | ||||
|   case '`': | ||||
|   case ':': | ||||
|   case ',': | ||||
|   case '}': | ||||
|   case '{': | ||||
|   case '\\': | ||||
| 	return c; | ||||
| 
 | ||||
|   case '.': | ||||
| 	tok.ival = E_SELECT; | ||||
| 	return SEL_OP; | ||||
|  | @ -340,7 +381,7 @@ get_token(c) | |||
| 	tok.ival = E_BNOT; | ||||
| 	return PREF_OP; | ||||
|   default: | ||||
| 	error("illegal character 0%o", c); | ||||
| 	error((c >= 040 && c < 0177) ? "%s'%c'" : "%s'\\0%o'", "illegal character ", c); | ||||
| 	return LLlex(); | ||||
|   } | ||||
| } | ||||
|  | @ -397,6 +438,7 @@ get_string(c) | |||
|   while (ch = getc(db_in), ch != c) { | ||||
| 	if (ch == '\n') { | ||||
| 		error("newline in string"); | ||||
| 		ungetc(ch, db_in); | ||||
| 		break; | ||||
| 	} | ||||
| 	if (ch == '\\') { | ||||
|  | @ -406,6 +448,15 @@ get_string(c) | |||
| 	buf[len++] = ch; | ||||
|   } | ||||
|   buf[len++] = 0; | ||||
|   if (c == '\'') { | ||||
| 	long val = 0; | ||||
| 	ch = 0; | ||||
| 	while (buf[ch] != 0) { | ||||
| 		val = (val << 8) + (buf[ch++] & 0377); | ||||
| 	} | ||||
| 	tok.ival = val; | ||||
| 	return INTEGER; | ||||
|   } | ||||
|   tok.str = Salloc(buf, (unsigned) len); | ||||
|   return STRING; | ||||
| } | ||||
|  | @ -418,28 +469,34 @@ print_op(p) | |||
|   case OP_UNOP: | ||||
|   	switch(p->t_whichoper) { | ||||
| 	case E_MIN: | ||||
| 		fputs("-", db_out); | ||||
| 		fputs("-(", db_out); | ||||
| 		print_node(p->t_args[0], 0); | ||||
| 		fputc(')', db_out); | ||||
| 		break; | ||||
| 	case E_PLUS: | ||||
| 		fputs("+", db_out); | ||||
| 		fputs("+(", db_out); | ||||
| 		print_node(p->t_args[0], 0); | ||||
| 		fputc(')', db_out); | ||||
| 		break; | ||||
| 	case E_NOT: | ||||
| 		fputs("!", db_out); | ||||
| 		fputs("!(", db_out); | ||||
| 		print_node(p->t_args[0], 0); | ||||
| 		fputc(')', db_out); | ||||
| 		break; | ||||
| 	case E_DEREF: | ||||
| 		fputs("*", db_out); | ||||
| 		fputs("*(", db_out); | ||||
| 		print_node(p->t_args[0], 0); | ||||
| 		fputc(')', db_out); | ||||
| 		break; | ||||
| 	case E_BNOT: | ||||
| 		fputs("~", db_out); | ||||
| 		fputs("~(", db_out); | ||||
| 		print_node(p->t_args[0], 0); | ||||
| 		fputc(')', db_out); | ||||
| 		break; | ||||
| 	case E_ADDR: | ||||
| 		fputs("&", db_out); | ||||
| 		fputs("&(", db_out); | ||||
| 		print_node(p->t_args[0], 0); | ||||
| 		fputc(')', db_out); | ||||
| 		break; | ||||
| 	} | ||||
| 	break; | ||||
|  |  | |||
|  | @ -8,11 +8,11 @@ | |||
| %iSTGARB | ||||
| STSKIP: \t\013\014\015 | ||||
| STNL:;\012 | ||||
| STIDF:a-zA-Z_$ | ||||
| STIDF:a-zA-Z_ | ||||
| STSTR:"' | ||||
| STDOT:. | ||||
| STNUM:0-9 | ||||
| STSIMP:,<>{}:` | ||||
| STSIMP:-,<>{}:`?\\ | ||||
| %T#include "class.h" | ||||
| %Tchar tkclass[] = { | ||||
| %p | ||||
|  |  | |||
|  | @ -4,7 +4,6 @@ | |||
| { | ||||
| #include	<stdio.h> | ||||
| #include	<alloc.h> | ||||
| #include	<setjmp.h> | ||||
| #include	<signal.h> | ||||
| 
 | ||||
| #include	"ops.h" | ||||
|  | @ -19,15 +18,17 @@ | |||
| #include	"expr.h" | ||||
| 
 | ||||
| extern char	*Salloc(); | ||||
| extern char	*strindex(); | ||||
| extern FILE	*db_in; | ||||
| extern int	disable_intr; | ||||
| extern p_tree	run_command, print_command; | ||||
| 
 | ||||
| int		errorgiven; | ||||
| int		errorgiven = 0; | ||||
| int		child_interrupted = 0; | ||||
| int		interrupted = 0; | ||||
| int		eof_seen = 0; | ||||
| static int	extended_charset = 0; | ||||
| static int	in_expression = 0; | ||||
| jmp_buf		jmpbuf; | ||||
| 
 | ||||
| static int	init_del(); | ||||
| static int	skip_to_eol(); | ||||
| 
 | ||||
| struct token	tok, aside; | ||||
| 
 | ||||
|  | @ -40,50 +41,51 @@ struct token	tok, aside; | |||
| 
 | ||||
| commands | ||||
|   { p_tree com, lastcom = 0; | ||||
|     int give_prompt; | ||||
|   } | ||||
| : | ||||
| 			{ if (! setjmp(jmpbuf)) { | ||||
| 				init_del(); | ||||
| 			  } | ||||
| 			  else { | ||||
| 				skip_to_eol(); | ||||
| 				goto prmpt; | ||||
| 			  } | ||||
| 			} | ||||
|   [ %persistent command_line(&com) | ||||
|     [	'\n'		{ give_prompt = 1; } | ||||
|     |	%default ';'	{ give_prompt = 0; } | ||||
|     ] | ||||
| 			{ if (com) { | ||||
| 				if (errorgiven) { | ||||
| 					freenode(com); | ||||
| 					com = 0; | ||||
| 				} | ||||
| 				if (lastcom && !in_status(lastcom) && | ||||
| 				    lastcom != run_command) { | ||||
| 				if (lastcom) { | ||||
| 					freenode(lastcom); | ||||
| 					lastcom = 0; | ||||
| 				} | ||||
| 
 | ||||
| 				if (com) { | ||||
| 					eval(com); | ||||
| 			  		if (repeatable(com)) { | ||||
| 						lastcom = com; | ||||
| 					} | ||||
| 					eval(com); | ||||
| 					if (! repeatable(com) && | ||||
| 					    ! in_status(com) && | ||||
| 					    com != run_command) { | ||||
| 					else if (! in_status(com) && | ||||
| 					        com != run_command && | ||||
| 						com != print_command) { | ||||
| 						freenode(com); | ||||
| 					} | ||||
| 				} | ||||
| 			  } else if (lastcom && ! errorgiven) eval(lastcom); | ||||
| 			  } else if (lastcom && ! errorgiven) { | ||||
| 				eval(lastcom); | ||||
| 			  } | ||||
| 			  if (give_prompt) { | ||||
| 			  	errorgiven = 0; | ||||
| 				interrupted = 0; | ||||
| 				prompt(); | ||||
| 			  } | ||||
| 			} | ||||
|     [	'\n' 		{ prmpt: prompt(); } | ||||
|     |	';' | ||||
|     ]			{ errorgiven = 0; } | ||||
|   ]* | ||||
| 			{ signal_child(SIGKILL); } | ||||
| ; | ||||
| 
 | ||||
| command_line(p_tree *p;) | ||||
| : | ||||
| 			{ *p = 0; } | ||||
| [ | ||||
|   list_command(p) | ||||
| | file_command(p) | ||||
| | run_command(p) | ||||
|  | @ -102,9 +104,12 @@ command_line(p_tree *p;) | |||
| | display_command(p) | ||||
| | trace_command(p) | ||||
| | set_command(p) | ||||
| | help_command(p) | ||||
| | FIND qualified_name(p){ *p = mknode(OP_FIND, *p); } | ||||
| | WHICH qualified_name(p){ *p = mknode(OP_WHICH, *p); } | ||||
| |			{ *p = 0; } | ||||
| | able_command(p) | ||||
| | | ||||
| ] | ||||
| ; | ||||
| 
 | ||||
| where_command(p_tree *p;) | ||||
|  | @ -112,6 +117,7 @@ where_command(p_tree *p;) | |||
| : | ||||
|   WHERE | ||||
|   [ INTEGER		{ l = tok.ival; } | ||||
|   | '-' INTEGER		{ l = - tok.ival; } | ||||
|   |			{ l = 0x7fffffff; } | ||||
|   ]			{ *p = mknode(OP_WHERE, l); } | ||||
| ; | ||||
|  | @ -121,12 +127,17 @@ list_command(p_tree *p;) | |||
| : | ||||
|   LIST | ||||
|   [ | ||||
|   | lin_num(&t1) | ||||
|     [ ',' lin_num(&t2) | ||||
|     |			{ t2 = mknode(OP_INTEGER, t1->t_ival); } | ||||
|     ] | ||||
|   | count(&t1) | ||||
|   | qualified_name(&t1) | ||||
|   ]			{ *p = mknode(OP_LIST, t1, t2); } | ||||
|   ] | ||||
|   [ ',' count(&t2) | ||||
|   | '-'  | ||||
|     [	count(&t2)	{ t2->t_ival = - t2->t_ival; } | ||||
|     |			{ t2 = mknode(OP_INTEGER, -100000000L); } | ||||
|     ] | ||||
|   | | ||||
|   ] | ||||
| 			{ *p = mknode(OP_LIST, t1, t2); } | ||||
| ; | ||||
| 
 | ||||
| file_command(p_tree *p;) | ||||
|  | @ -139,13 +150,20 @@ file_command(p_tree *p;) | |||
| 			} | ||||
| ; | ||||
| 
 | ||||
| help_command(p_tree *p;) | ||||
| : | ||||
|   [ HELP | '?' ] | ||||
|   [			{ *p = mknode(OP_HELP, (struct idf *) 0, (char *) 0); } | ||||
|   | name(p)		{ (*p)->t_oper = OP_HELP; } | ||||
|   | '?'			{ *p = mknode(OP_HELP, str2idf("help",0), (char *) 0); } | ||||
|   ] | ||||
| ; | ||||
| 
 | ||||
| run_command(p_tree *p;) | ||||
| : | ||||
|   RUN			{ extended_charset = 1; *p = 0; } | ||||
|   RUN			{ extended_charset = 1; } | ||||
|   args(p)		{ *p = mknode(OP_RUN, *p); | ||||
| 			  extended_charset = 0; | ||||
| 			  freenode(run_command); | ||||
| 			  run_command = *p; | ||||
| 			} | ||||
| | RERUN			{ if (! run_command) { | ||||
| 				error("no run command given yet"); | ||||
|  | @ -171,7 +189,7 @@ trace_command(p_tree *p;) | |||
|   { p_tree whr = 0, cond = 0, exp = 0; } | ||||
| : | ||||
|   TRACE | ||||
|   [ ON expression(&exp, 1) ]? | ||||
|   [ ON expression(&exp, 0) ]? | ||||
|   where(&whr)? | ||||
|   condition(&cond)?	{ *p = mknode(OP_TRACE, whr, cond, exp); } | ||||
| ; | ||||
|  | @ -195,8 +213,10 @@ when_command(p_tree *p;) | |||
|   condition(&cond)? | ||||
|   '{'  | ||||
|   command_line(p) | ||||
|   [ ';'			{ *p = mknode(OP_LINK, *p, (p_tree) 0); | ||||
| 			  p = &((*p)->t_args[1]); | ||||
|   [ ';'			{ if (*p) { | ||||
| 				*p = mknode(OP_LINK, *p, (p_tree) 0); | ||||
| 			  	p = &((*p)->t_args[1]); | ||||
| 			  } | ||||
| 			} | ||||
|     command_line(p) | ||||
|   ]* | ||||
|  | @ -206,6 +226,9 @@ when_command(p_tree *p;) | |||
| 				freenode(*p); | ||||
| 				*p = 0; | ||||
| 			  } | ||||
| 			  else if (! *p) { | ||||
| 				error("no commands given"); | ||||
| 			  } | ||||
| 			  else *p = mknode(OP_WHEN, whr, cond, *p); | ||||
| 			} | ||||
| ; | ||||
|  | @ -239,41 +262,81 @@ regs_command(p_tree *p;) | |||
| 
 | ||||
| delete_command(p_tree *p;) | ||||
| : | ||||
|   DELETE | ||||
|   INTEGER		{ *p = mknode(OP_DELETE, tok.ival); } | ||||
|   DELETE count_list(p)	{ *p = mknode(OP_DELETE, *p); } | ||||
| ; | ||||
| 
 | ||||
| print_command(p_tree *p;) | ||||
| : | ||||
|   PRINT expression_list(p) | ||||
|   PRINT  | ||||
|   [ format_expression_list(p) | ||||
| 			{ *p = mknode(OP_PRINT, *p); } | ||||
|   | | ||||
| 			{ *p = mknode(OP_PRINT, (p_tree) 0); } | ||||
|   ] | ||||
| ; | ||||
| 
 | ||||
| display_command(p_tree *p;) | ||||
| : | ||||
|   DISPLAY expression_list(p) | ||||
|   DISPLAY format_expression_list(p) | ||||
| 			{ *p = mknode(OP_DISPLAY, *p); } | ||||
| ; | ||||
| 
 | ||||
| expression_list(p_tree *p;) | ||||
| format_expression_list(p_tree *p;) | ||||
| : | ||||
|   expression(p, 1) | ||||
|   format_expression(p) | ||||
|   [ ','			{ *p = mknode(OP_LINK, *p, (p_tree) 0); | ||||
| 			  p = &((*p)->t_args[1]); | ||||
| 			} | ||||
|     expression(p, 1) | ||||
|     format_expression(p) | ||||
|   ]* | ||||
| ; | ||||
| 
 | ||||
| format_expression(p_tree *p;) | ||||
|   { p_tree	p1; } | ||||
| : | ||||
|   expression(p, 0) | ||||
|   [ '\\'  | ||||
| 	[ name(&p1)	{ register char *c = p1->t_str; | ||||
| 			  while (*c) { | ||||
| 				if (! strindex("doshcax", *c)) { | ||||
| 					error("illegal format: %c", *c); | ||||
| 					break; | ||||
| 				} | ||||
| 				c++; | ||||
| 			  } | ||||
| 			  *p = mknode(OP_FORMAT, *p, p1); | ||||
| 			} | ||||
| 	| | ||||
| 	] | ||||
|   | | ||||
|   ] | ||||
| ; | ||||
| 
 | ||||
| set_command(p_tree *p;) | ||||
| : | ||||
|   SET expression(p, 1)	{ *p = mknode(OP_SET, *p, (p_tree) 0); } | ||||
|   TO expression(&((*p)->t_args[1]), 1) | ||||
|   SET expression(p, 0)	{ *p = mknode(OP_SET, *p, (p_tree) 0); } | ||||
|   TO expression(&((*p)->t_args[1]), 0) | ||||
| ; | ||||
| 
 | ||||
| able_command(p_tree *p;) | ||||
| : | ||||
|   [ ENABLE 		{ *p = mknode(OP_ENABLE, (p_tree) 0); } | ||||
|   | DISABLE 		{ *p = mknode(OP_DISABLE, (p_tree) 0); } | ||||
|   ] | ||||
|   count_list(&(*p)->t_args[0]) | ||||
| ; | ||||
| 
 | ||||
| count_list(p_tree *p;) | ||||
| : | ||||
|   count(p) | ||||
|   [ ','			{ *p = mknode(OP_LIST, *p, (p_tree) 0); } | ||||
|     count(&(*p)->t_args[1]) | ||||
|   ]* | ||||
| ; | ||||
| 
 | ||||
| condition(p_tree *p;) | ||||
| : | ||||
|   IF expression(p, 1) | ||||
|   IF expression(p, 0) | ||||
| ; | ||||
| 
 | ||||
| where(p_tree *p;) | ||||
|  | @ -293,36 +356,7 @@ expression(p_tree *p; int level;) | |||
| 			  (*p)->t_whichoper = currop; | ||||
| 			} | ||||
| 	expression(&((*p)->t_args[1]), currprio) | ||||
| 			{ adjust_oper(p); } | ||||
|   ]* | ||||
| 			{ in_expression--; } | ||||
| ; | ||||
| 
 | ||||
| factor(p_tree *p;) | ||||
| : | ||||
|   '(' expression(p, 1) ')' | ||||
| | | ||||
|   INTEGER		{ *p = mknode(OP_INTEGER, tok.ival); } | ||||
| | | ||||
|   REAL			{ *p = mknode(OP_REAL, tok.fval); } | ||||
| | | ||||
|   STRING		{ *p = mknode(OP_STRING, tok.str); } | ||||
| | | ||||
|   designator(p) | ||||
| | | ||||
|   			{ *p = mknode(OP_UNOP, (p_tree) 0); | ||||
| 			  (*p)->t_whichoper = (int) tok.ival; | ||||
| 			} | ||||
|   [ PREF_OP  | ||||
|   | PREF_OR_BIN_OP 	{ (*currlang->fix_bin_to_pref)(*p); } | ||||
|   ] | ||||
|   expression(&(*p)->t_args[0], unprio((*p)->t_whichoper)) | ||||
| ; | ||||
| 
 | ||||
| designator(p_tree *p;) | ||||
| : | ||||
|   qualified_name(p) | ||||
|   [ | ||||
|   | | ||||
| 	SEL_OP		{ *p = mknode(OP_BINOP, *p, (p_tree) 0); | ||||
| 			  (*p)->t_whichoper = (int) tok.ival; | ||||
| 			} | ||||
|  | @ -331,9 +365,43 @@ designator(p_tree *p;) | |||
| 	'['		{ *p = mknode(OP_BINOP, *p, (p_tree) 0); | ||||
| 			  (*p)->t_whichoper = E_ARRAY; | ||||
| 			} | ||||
| 	expression(&(*p)->t_args[1], 1) | ||||
| 	expression(&(*p)->t_args[1], 0) | ||||
| 	[	','	{ *p = mknode(OP_BINOP, *p, (p_tree) 0); | ||||
| 			  (*p)->t_whichoper = E_ARRAY; | ||||
| 			} | ||||
| 		expression(&(*p)->t_args[1], 0) | ||||
| 	]* | ||||
| 	']' | ||||
|   ]* | ||||
| 			{ in_expression--; } | ||||
| ; | ||||
| 
 | ||||
| factor(p_tree *p;) | ||||
| : | ||||
|   [ | ||||
|   	%default EXPRESSION	/* lexical analyzer will never return this token */ | ||||
| 			{ *p = mknode(OP_INTEGER, 0L); } | ||||
|   | | ||||
|   	'(' expression(p, 0) ')' | ||||
|   | | ||||
|   	INTEGER		{ *p = mknode(OP_INTEGER, tok.ival); } | ||||
|   | | ||||
|   	REAL		{ *p = mknode(OP_REAL, tok.fval); } | ||||
|   | | ||||
|   	STRING		{ *p = mknode(OP_STRING, tok.str); } | ||||
|   | | ||||
|   	qualified_name(p) | ||||
|   | | ||||
|   			{ *p = mknode(OP_UNOP, (p_tree) 0); | ||||
| 			  (*p)->t_whichoper = (int) tok.ival; | ||||
| 			} | ||||
|   	[ PREF_OP  | ||||
|   	| PREF_OR_BIN_OP | ||||
| 			{ (*currlang->fix_bin_to_pref)(*p); } | ||||
|   	] | ||||
|   	expression(&(*p)->t_args[0], unprio((*p)->t_whichoper)) | ||||
|   ] | ||||
|   [ %while(1) | ||||
| 	POST_OP		{ *p = mknode(OP_UNOP, *p); | ||||
| 			  (*p)->t_whichoper = (int) tok.ival; | ||||
| 			} | ||||
|  | @ -352,7 +420,7 @@ position(p_tree *p;) | |||
| 			  else str = listfile->sy_idf->id_text; | ||||
| 			} | ||||
|   ] | ||||
|   lin_num(&lin)		{ *p = mknode(OP_AT, lin->t_ival, str); | ||||
|   count(&lin)		{ *p = mknode(OP_AT, lin->t_ival, str); | ||||
| 			  freenode(lin); | ||||
| 			} | ||||
| ; | ||||
|  | @ -379,7 +447,7 @@ arg(p_tree *p;) | |||
|   '<' name(p)		{ (*p)->t_oper = OP_INPUT; } | ||||
| ; | ||||
| 
 | ||||
| lin_num(p_tree *p;) | ||||
| count(p_tree *p;) | ||||
| : | ||||
|   INTEGER		{ *p = mknode(OP_INTEGER, tok.ival); } | ||||
| ; | ||||
|  | @ -403,7 +471,7 @@ name(p_tree *p;) | |||
|   | AT | ||||
|   | IN | ||||
|   | IF | ||||
|   | NAME | ||||
|   | %default NAME | ||||
|   | CONT | ||||
|   | STEP | ||||
|   | NEXT | ||||
|  | @ -421,6 +489,9 @@ name(p_tree *p;) | |||
|   | FIND | ||||
|   | DISPLAY | ||||
|   | WHICH | ||||
|   | HELP | ||||
|   | DISABLE | ||||
|   | ENABLE | ||||
|   ]			{ *p = mknode(OP_NAME, tok.idf, tok.str); } | ||||
| ; | ||||
| 
 | ||||
|  | @ -438,7 +509,10 @@ LLlex() | |||
|   do { | ||||
| 	c = getc(db_in); | ||||
|   } while (c != EOF && class(c) == STSKIP); | ||||
|   if (c == EOF) return c; | ||||
|   if (c == EOF) { | ||||
| 	eof_seen = 1; | ||||
| 	return c; | ||||
|   } | ||||
|   if (extended_charset && in_ext(c)) { | ||||
| 	TOK = get_name(c); | ||||
| 	return TOK; | ||||
|  | @ -483,7 +557,7 @@ get_name(c) | |||
| 	c = getc(db_in); | ||||
|   } while ((extended_charset && in_ext(c)) || in_idf(c)); | ||||
|   ungetc(c, db_in); | ||||
|   *p = 0; | ||||
|   *p++ = 0; | ||||
|   if (extended_charset) { | ||||
| 	tok.idf = 0; | ||||
| 	tok.str = Salloc(buf, (unsigned) (p - buf)); | ||||
|  | @ -520,20 +594,16 @@ static int | |||
| catch_del() | ||||
| { | ||||
|   signal(SIGINT, catch_del); | ||||
|   signal_child(SIGEMT); | ||||
|   longjmp(jmpbuf, 1); | ||||
|   if (! disable_intr) { | ||||
|   	signal_child(SIGEMT); | ||||
|   	child_interrupted = 1; | ||||
|   } | ||||
|   interrupted = 1; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| int | ||||
| init_del() | ||||
| { | ||||
|   signal(SIGINT, catch_del); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| skip_to_eol() | ||||
| { | ||||
|   while (TOK != '\n' && TOK > 0) LLlex(); | ||||
|   wait_for_child("interrupted"); | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -56,8 +56,13 @@ debugger_string | |||
|   | /* type name */ | ||||
| 			{ s = NewSymbol(str, CurrentScope, TYPE, currnam); } | ||||
| 	't' type_name(&(s->sy_type), s) | ||||
| 			{ if (! s->sy_type->ty_sym) s->sy_type->ty_sym = s; } | ||||
| 
 | ||||
| 			{ if (! s->sy_type->ty_sym) s->sy_type->ty_sym = s;  | ||||
| 			  if ((s->sy_type->ty_class == T_ENUM || | ||||
| 			       s->sy_type->ty_class == T_SUBRANGE) && | ||||
| 			      currnam->on_desc != 0) { | ||||
| 				s->sy_type->ty_size = currnam->on_desc; | ||||
| 			  } | ||||
| 			} | ||||
|   | /* tag name (only C?) */ | ||||
| 			{ s = NewSymbol(str, CurrentScope, TAG, currnam); } | ||||
| 	'T' tag_name(s) | ||||
|  | @ -225,7 +230,7 @@ type_name(p_type *t; p_symbol sy;) | |||
| 	type(t, type_index, sy) | ||||
| 				{ p = tp_lookup(type_index); | ||||
| 				  if (*p && *p != incomplete_type) { | ||||
| 					if (!((*p)->ty_flags & T_CROSS)) | ||||
| 					if ((*p)->ty_class != T_CROSS) | ||||
| 						error("Redefining (%d,%d) %d", | ||||
| 						  type_index[0], | ||||
| 						  type_index[1], | ||||
|  | @ -264,7 +269,7 @@ tag_name(p_symbol t;) | |||
|   type(&(t->sy_type), type_index, t) | ||||
| 				{ p = tp_lookup(type_index); | ||||
| 				  if (*p && *p != incomplete_type) { | ||||
| 					if (!((*p)->ty_flags & T_CROSS)) | ||||
| 					if ((*p)->ty_class != T_CROSS) | ||||
| 						error("Redefining (%d,%d) %d", | ||||
| 						  type_index[0], | ||||
| 						  type_index[1], | ||||
|  | @ -275,6 +280,11 @@ tag_name(p_symbol t;) | |||
| 				  } | ||||
| 				  if (t->sy_type) *p = t->sy_type;  | ||||
| 				  if (*p == 0) *p = incomplete_type; | ||||
| 			  	  if (t->sy_type && | ||||
| 				      t->sy_type->ty_class == T_ENUM && | ||||
| 			              currnam->on_desc != 0) { | ||||
| 					t->sy_type->ty_size = currnam->on_desc; | ||||
| 			  	  } | ||||
| 				} | ||||
| ; | ||||
| 
 | ||||
|  | @ -348,14 +358,15 @@ type(p_type *ptp; int *type_index; p_symbol sy;) | |||
|   	] | ||||
| 			{ AllowName = 1; } | ||||
|   	name(&str) | ||||
| 			{ sy = Lookfromscope(str2idf(str,0),CurrentScope,TAG); | ||||
| 			  if (sy && sy->sy_type->ty_class == tclass) { | ||||
| 			{ sy = Lookfromscope(str2idf(str,0),TAG,CurrentScope); | ||||
| 			  if (sy &&  | ||||
| 			      (sy->sy_type->ty_class == tclass || | ||||
| 			       sy->sy_type->ty_class == T_CROSS)) { | ||||
| 				tp = sy->sy_type; | ||||
| 			  } | ||||
| 			  else { | ||||
| 				tp = new_type(); | ||||
| 				tp->ty_flags = T_CROSS; | ||||
| 				tp->ty_class = tclass; | ||||
| 				tp->ty_class = T_CROSS; | ||||
| 				tp->ty_tag = str; | ||||
| 				sy = NewSymbol(str, CurrentScope, TAG, (struct outname *) 0); | ||||
| 			  } | ||||
|  |  | |||
|  | @ -38,11 +38,11 @@ DbxRead(f) | |||
| 
 | ||||
|   /* Open file, read header, and check magic word */ | ||||
|   if (! rd_open(f)) { | ||||
|   	fatal("%s: not an ACK object file", f); | ||||
|   	fatal("%s: could not open", f); | ||||
|   } | ||||
|   rd_ohead(&h); | ||||
|   if (BADMAGIC(h) && h.oh_magic != O_CONVERTED) { | ||||
|   	fatal("%s: not an ACK object file", f); | ||||
|   	fatal("%s: not an object file", f); | ||||
|   } | ||||
| 
 | ||||
|   /* Allocate space for name table and read it */ | ||||
|  |  | |||
|  | @ -229,10 +229,10 @@ eval_cond(p) | |||
|   if (eval_expr(p, &buf, &size, &tp)) { | ||||
| 	if (convert(&buf, &size, &tp, target_tp, target_tp->ty_size)) { | ||||
| 		val = get_int(buf, size, T_UNSIGNED); | ||||
| 		if (buf) free(buf); | ||||
| 		free(buf); | ||||
| 		return (int) (val != 0); | ||||
| 	} | ||||
| 	if (buf) free(buf); | ||||
| 	free(buf); | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
|  | @ -298,6 +298,7 @@ ptr_addr(p, paddr, psize, ptp) | |||
| 		return 1; | ||||
|   	default: | ||||
| 		error("illegal operand of DEREF"); | ||||
| 		free(buf); | ||||
| 		break; | ||||
| 	} | ||||
|   } | ||||
|  | @ -318,6 +319,9 @@ do_deref(p, pbuf, psize, ptp) | |||
| 	malloc_succeeded(*pbuf); | ||||
| 	if (! get_bytes(*psize, addr, *pbuf)) { | ||||
| 		error("could not get value"); | ||||
| 		free(*pbuf); | ||||
| 		*pbuf = 0; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return 1; | ||||
|   } | ||||
|  | @ -337,6 +341,8 @@ do_addr(p, pbuf, psize, ptp) | |||
| 	*pbuf = malloc((unsigned) pointer_size); | ||||
| 	malloc_succeeded(*pbuf); | ||||
| 	put_int(*pbuf, pointer_size, (long) addr); | ||||
| 	address_type->ty_ptrto = *ptp; | ||||
| 	*ptp = address_type; | ||||
| 	return 1; | ||||
|   } | ||||
|   return 0; | ||||
|  | @ -505,7 +511,7 @@ do_andor(p, pbuf, psize, ptp) | |||
|   p_type	*ptp; | ||||
| { | ||||
|   long		l1, l2; | ||||
|   char		*buf; | ||||
|   char		*buf = 0; | ||||
|   long		size; | ||||
|   p_type	tp; | ||||
|   p_type	target_tp = currlang->has_bool_type ? bool_type : int_type; | ||||
|  | @ -524,7 +530,7 @@ do_andor(p, pbuf, psize, ptp) | |||
| 	free(buf); | ||||
| 	return 1; | ||||
|   } | ||||
|   free(buf); | ||||
|   if (buf) free(buf); | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -541,9 +547,44 @@ do_arith(p, pbuf, psize, ptp) | |||
|   long		size; | ||||
|   p_type	tp, balance_tp; | ||||
| 
 | ||||
|   if (eval_expr(p->t_args[0], pbuf, psize, ptp) && | ||||
|       eval_expr(p->t_args[1], &buf, &size, &tp) && | ||||
|       (balance_tp = balance(*ptp, tp)) && | ||||
|   if (!(eval_expr(p->t_args[0], pbuf, psize, ptp) && | ||||
|         eval_expr(p->t_args[1], &buf, &size, &tp))) { | ||||
| 	return 0; | ||||
|   } | ||||
|   if ((*ptp)->ty_class == T_POINTER) { | ||||
| 	if (currlang != c_dep || | ||||
| 	    (p->t_whichoper != E_PLUS && p->t_whichoper != E_MIN)) { | ||||
| 		error("illegal operand type(s)"); | ||||
| 		free(buf); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	l1 = get_int(*pbuf, *psize, T_UNSIGNED); | ||||
| 	if (tp->ty_class == T_POINTER) { | ||||
| 		if (p->t_whichoper != E_MIN) { | ||||
| 			error("illegal operand type(s)"); | ||||
| 			free(buf); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		l2 = get_int(buf, size, T_UNSIGNED); | ||||
| 		free(buf); | ||||
| 		*pbuf = Realloc(*pbuf, (unsigned) long_size); | ||||
| 		put_int(*pbuf, long_size, (l1 - l2)/(*ptp)->ty_ptrto->ty_size); | ||||
| 		*ptp = long_type; | ||||
| 		return 1; | ||||
| 	} | ||||
| 	if (! convert(&buf, &size, &tp, long_type, long_size)) { | ||||
| 		free(buf); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	l2 = get_int(buf, size, T_INTEGER) * (*ptp)->ty_ptrto->ty_size; | ||||
| 	free(buf); | ||||
| 	buf = 0; | ||||
| 	if (p->t_whichoper == E_PLUS) l1 += l2; | ||||
| 	else l1 -= l2; | ||||
| 	put_int(*pbuf, *psize, l1); | ||||
| 	return 1; | ||||
|   } | ||||
|   if ((balance_tp = balance(*ptp, tp)) && | ||||
|       convert(pbuf, psize, ptp, balance_tp, balance_tp->ty_size) && | ||||
|       convert(&buf, &size, &tp, balance_tp, balance_tp->ty_size)) { | ||||
| 	switch(balance_tp->ty_class) { | ||||
|  | @ -795,6 +836,10 @@ do_cmp(p, pbuf, psize, ptp) | |||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		error("illegal operand type(s)"); | ||||
| 		free(buf); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if (*psize < int_size) { | ||||
| 		*psize = int_size; | ||||
|  | @ -976,6 +1021,9 @@ do_select(p, pbuf, psize, ptp) | |||
| 	*pbuf = malloc((unsigned int) *psize); | ||||
| 	malloc_succeeded(*pbuf); | ||||
| 	if (! get_bytes(*psize, a, *pbuf)) { | ||||
| 		error("could not get value"); | ||||
| 		free(*pbuf); | ||||
| 		*pbuf = 0; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return 1; | ||||
|  | @ -983,6 +1031,27 @@ do_select(p, pbuf, psize, ptp) | |||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| do_derselect(p, pbuf, psize, ptp) | ||||
|   p_tree	p; | ||||
|   char		**pbuf; | ||||
|   long		*psize; | ||||
|   p_type	*ptp; | ||||
| { | ||||
|   int	retval; | ||||
|   t_tree	t; | ||||
| 
 | ||||
|   t.t_oper = OP_UNOP; | ||||
|   t.t_whichoper = E_DEREF; | ||||
|   t.t_args[0] = p->t_args[0]; | ||||
|   p->t_args[0] = &t; | ||||
|   p->t_whichoper = E_SELECT; | ||||
|   retval = eval_expr(p, pbuf, psize, ptp); | ||||
|   p->t_args[0] = t.t_args[0]; | ||||
|   p->t_whichoper = E_DERSELECT; | ||||
|   return retval; | ||||
| } | ||||
| 
 | ||||
| static int (*bin_op[])() = { | ||||
|   0, | ||||
|   0, | ||||
|  | @ -1009,7 +1078,7 @@ static int (*bin_op[])() = { | |||
|   do_arith, | ||||
|   do_arith, | ||||
|   0, | ||||
|   0, | ||||
|   do_derselect, | ||||
|   do_sft, | ||||
|   do_sft, | ||||
|   0 | ||||
|  | @ -1023,9 +1092,14 @@ eval_expr(p, pbuf, psize, ptp) | |||
|   p_type	*ptp; | ||||
| { | ||||
|   register p_symbol	sym; | ||||
|   int	retval = 0; | ||||
|   int		retval = 0; | ||||
| 
 | ||||
|   *pbuf = 0; | ||||
| 
 | ||||
|   switch(p->t_oper) { | ||||
|   case OP_FORMAT: | ||||
| 	if (eval_expr(p->t_args[0], pbuf, psize, ptp)) retval = 1; | ||||
| 	break; | ||||
|   case OP_NAME: | ||||
|   case OP_SELECT: | ||||
| 	sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR|CONST); | ||||
|  | @ -1148,7 +1222,7 @@ eval_desig(p, paddr, psize, ptp) | |||
| 	} | ||||
| 	break; | ||||
|   default: | ||||
| 	assert(0); | ||||
| 	error("illegal designator"); | ||||
| 	break; | ||||
|   } | ||||
|   if (! retval) { | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| .\" $Header$ | ||||
| .TH GRIND 1ACK | ||||
| .TH GRIND 1 | ||||
| .SH NAME | ||||
| grind \- source-level debugger for ACK | ||||
| .SH SYNOPSIS | ||||
|  | @ -21,15 +21,15 @@ available on many Unix systems. However, some | |||
| .B grind | ||||
| commands are not available in | ||||
| .IR dbx , | ||||
| some more | ||||
| some | ||||
| .I dbx | ||||
| commands are not available in | ||||
| .BR grind , | ||||
| and some things are just plain different. | ||||
| and some things are just different. | ||||
| .LP | ||||
| .I <object file> | ||||
| is an object file, produced by | ||||
| .IR ack (1ACK) | ||||
| .IR ack (1) | ||||
| with the | ||||
| .B \-g | ||||
| option to include a symbol table. | ||||
|  | @ -40,7 +40,7 @@ is specified, "a.out" is used. | |||
| .LP | ||||
| For some machines, the debugger does not recognize the object file | ||||
| format. For these machines, the result of the | ||||
| .IR led (6ACK) | ||||
| .IR led (6) | ||||
| program must be saved and offered to | ||||
| .BR grind . | ||||
| .SH USAGE | ||||
|  | @ -164,10 +164,10 @@ when the | |||
| is reached, and then when | ||||
| .I condition | ||||
| becomes true. | ||||
| If no position is given, stop when | ||||
| If no position is given, do this when | ||||
| .I condition | ||||
| becomes true. | ||||
| If no condition is given, stop when | ||||
| If no condition is given, do this when | ||||
| .I position | ||||
| is reached. | ||||
| Either a position or a condition (or both) must be given. | ||||
|  | @ -273,6 +273,9 @@ If the types do not match, | |||
| tries to apply conversions. | ||||
| .TP | ||||
| \fBwhere\fP [ \fIn\fP ] | ||||
| .ti -0.5i | ||||
| \fBw\fP [ \fIn\fP ] | ||||
| .br | ||||
| List all, or the top | ||||
| .IR n , | ||||
| active functions on the stack. | ||||
|  | @ -302,13 +305,11 @@ the first statement of | |||
| Exit | ||||
| .BR grind . | ||||
| .LP | ||||
| Some commands can be repeated by entering an empty command line: step, | ||||
| next, print, list, status, cont. | ||||
| .SH ENVIRONMENT | ||||
| P.M. | ||||
| Some commands can be repeated without arguments by entering an empty command line: | ||||
| step, next, list, cont. | ||||
| .SH SEE ALSO | ||||
| .IR ack (1ACK). | ||||
| .IR led (6ACK). | ||||
| .IR ack (1). | ||||
| .IR led (6). | ||||
| .SH REMARKS | ||||
| .LP | ||||
| .B Grind | ||||
|  |  | |||
|  | @ -7,13 +7,16 @@ | |||
| #include "position.h" | ||||
| #include "tree.h" | ||||
| #include "operator.h" | ||||
| #include "message.h" | ||||
| 
 | ||||
| extern FILE	*db_out; | ||||
| extern int	db_ss; | ||||
| 
 | ||||
| typedef struct item { | ||||
|   struct item		*i_next; | ||||
|   struct tree		*i_node; | ||||
|   struct item	*i_next; | ||||
|   struct tree	*i_node; | ||||
|   int		i_disabled; | ||||
|   int		i_itemno; | ||||
| } t_item, *p_item; | ||||
| 
 | ||||
| /* STATICALLOCDEF "item" 10 */ | ||||
|  | @ -25,7 +28,7 @@ struct itemlist { | |||
| 
 | ||||
| static struct itemlist	item_list; | ||||
| 
 | ||||
| int | ||||
| static int | ||||
| in_item_list(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|  | @ -38,8 +41,17 @@ in_item_list(p) | |||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static | ||||
| pr_item(i) | ||||
|   p_item	i; | ||||
| { | ||||
|   fprintf(db_out, "(%d)\t", i->i_itemno); | ||||
|   print_node(i->i_node, 0); | ||||
|   fputs(i->i_disabled ? " (disabled)\n": "\n", db_out); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| item_addr_actions(a) | ||||
| item_addr_actions(a, mess_type) | ||||
|   t_addr	a; | ||||
| { | ||||
|   /* Perform actions associated with position 'a', and return 1 if we must stop
 | ||||
|  | @ -51,16 +63,14 @@ item_addr_actions(a) | |||
|   while (i) { | ||||
| 	register p_tree	p = i->i_node; | ||||
| 
 | ||||
| 	if (p->t_address == a || p->t_address == NO_ADDR) { | ||||
| 	if (! i->i_disabled && (p->t_address == a || p->t_address == NO_ADDR)) { | ||||
| 		switch(p->t_oper) { | ||||
| 		case OP_TRACE: | ||||
| 		case OP_WHEN: | ||||
| 			if (! p->t_args[1] || | ||||
| 			    eval_cond(p->t_args[1])) { | ||||
| 				perform(p, a); | ||||
| 			} | ||||
| 			perform(p, a); | ||||
| 			break; | ||||
| 		case OP_STOP: | ||||
| 			if (mess_type != DB_SS && mess_type != OK) break; | ||||
| 			if (! p->t_args[1] || | ||||
| 			    eval_cond(p->t_args[1])) stopping = 1; | ||||
| 			break; | ||||
|  | @ -83,7 +93,7 @@ handle_displays() | |||
|   while (i) { | ||||
| 	register p_tree p = i->i_node; | ||||
| 
 | ||||
| 	if (p->t_oper == OP_DISPLAY) do_print(p); | ||||
| 	if (! i->i_disabled && p->t_oper == OP_DISPLAY) do_print(p); | ||||
| 	i = i->i_next; | ||||
|   } | ||||
| } | ||||
|  | @ -105,9 +115,9 @@ add_to_item_list(p) | |||
|   else { | ||||
| 	item_list.il_last->i_next = i; | ||||
|   } | ||||
|   p->t_itemno = ++item_list.il_count; | ||||
|   i->i_itemno = ++item_list.il_count; | ||||
|   item_list.il_last = i; | ||||
|   pr_item(p); | ||||
|   pr_item(i); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
|  | @ -119,7 +129,7 @@ remove_from_item_list(n) | |||
|   p_tree	p = 0; | ||||
| 
 | ||||
|   while (i) { | ||||
| 	if (i->i_node->t_itemno == n) break; | ||||
| 	if (i->i_itemno == n) break; | ||||
| 	prev = i; | ||||
| 	i = i->i_next; | ||||
|   } | ||||
|  | @ -144,33 +154,61 @@ get_from_item_list(n) | |||
|   register p_item i = item_list.il_first; | ||||
| 
 | ||||
|   while (i) { | ||||
| 	if (i->i_node->t_itemno == n) return i->i_node; | ||||
| 	if (i->i_itemno == n) return i->i_node; | ||||
| 	i = i->i_next; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| able_item(n, kind) | ||||
|   int	n; | ||||
| { | ||||
|   register p_item i = item_list.il_first; | ||||
|   register p_tree p; | ||||
| 
 | ||||
|   while (i) { | ||||
| 	if (i->i_itemno == n) break; | ||||
| 	i = i->i_next; | ||||
|   } | ||||
|   if (! i) { | ||||
| 	error("no item %d in current status", n); | ||||
| 	return; | ||||
|   } | ||||
|   p = i->i_node; | ||||
|   if (i->i_disabled == kind) { | ||||
| 	warning("item %d already %sabled", n, kind ? "dis" : "en"); | ||||
| 	return; | ||||
|   } | ||||
|   if (p->t_address == NO_ADDR && | ||||
|       (p->t_oper != OP_TRACE || ! p->t_args[0])) { | ||||
| 	db_ss += kind == 1 ? (-1) : 1; | ||||
|   } | ||||
|   i->i_disabled = kind; | ||||
|   switch(p->t_oper) { | ||||
|   case OP_STOP: | ||||
|   case OP_WHEN: | ||||
| 	setstop(p, kind ? CLRBP : SETBP); | ||||
| 	break; | ||||
|   case OP_TRACE: | ||||
| 	settrace(p, kind ? CLRTRACE : SETTRACE); | ||||
| 	break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| print_items() | ||||
| { | ||||
|   register p_item i = item_list.il_first; | ||||
| 
 | ||||
|   for (; i; i = i->i_next) { | ||||
| 	pr_item(i->i_node); | ||||
| 	pr_item(i); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| pr_item(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   fprintf(db_out, "(%d)\t", p->t_itemno); | ||||
|   print_node(p, 1); | ||||
| } | ||||
| 
 | ||||
| do_items() | ||||
| { | ||||
|   register p_item i = item_list.il_first; | ||||
| 
 | ||||
|   for (; i; i = i->i_next) { | ||||
| 	if (i->i_node->t_oper != OP_DUMP) eval(i->i_node); | ||||
| 	if (! i->i_disabled && i->i_node->t_oper != OP_DUMP) eval(i->i_node); | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ extern char	*dirs[]; | |||
| extern FILE	*fopen(); | ||||
| extern FILE	*db_out; | ||||
| extern t_lineno	currline; | ||||
| extern int	interrupted; | ||||
| 
 | ||||
| static int | ||||
| mk_filnm(dir, file, newname) | ||||
|  | @ -81,16 +82,14 @@ lines(file, l1, l2) | |||
|   else f = last_f; | ||||
| 
 | ||||
|   if (l1 < 1) l1 = 1; | ||||
|   if (l2 > file->f_nlines) l2 = file->f_nlines; | ||||
|   if (l1 > l2) { | ||||
| 	error("%s has only %d lines", file->f_sym->sy_idf->id_text, file->f_nlines); | ||||
| 	return; | ||||
|   } | ||||
|   if (l1 > file->f_nlines) l1 = file->f_nlines; | ||||
|   if (l1+l2-1 > file->f_nlines) l2 = file->f_nlines - l1 + 1; | ||||
| 
 | ||||
|   fseek(f, *(file->f_linepos+(l1-1)), 0); | ||||
|   for (n = l1; n <= l2; n++) { | ||||
|   for (n = l1; n < l1 + l2; n++) { | ||||
| 	register int	c; | ||||
| 
 | ||||
| 	if (interrupted) return; | ||||
| 	fprintf(db_out, "%c%5d\t", currfile && file == currfile->sy_file && n == currline ? '>' : ' ', n); | ||||
| 	do { | ||||
| 		c = getc(f); | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
| #include "Lpars.h" | ||||
| 
 | ||||
| static char	*usage = "Usage: %s [<ack.out>] [<a.out>]"; | ||||
| static char	*progname; | ||||
| char		*progname; | ||||
| char		*AckObj; | ||||
| char		*AObj; | ||||
| char		*dirs[] = { "", 0 }; | ||||
|  | @ -18,6 +18,7 @@ FILE		*db_in; | |||
| int		debug; | ||||
| extern struct tokenname tkidf[]; | ||||
| extern char	*strindex(); | ||||
| extern int	eof_seen; | ||||
| 
 | ||||
| static struct tokenname shorts[] = { | ||||
| 	{LIST, "l"}, | ||||
|  | @ -28,6 +29,7 @@ static struct tokenname shorts[] = { | |||
| 	{PRINT, "p"}, | ||||
| 	{RESTORE, "r"}, | ||||
| 	{TRACE, "t"}, | ||||
| 	{WHERE, "w"}, | ||||
| 	{ 0, 0} | ||||
| }; | ||||
| 
 | ||||
|  | @ -39,6 +41,7 @@ main(argc, argv) | |||
|   db_out = stdout; | ||||
|   db_in = stdin; | ||||
|   progname = argv[0]; | ||||
|   init_del(); | ||||
|   while (p = strindex(progname, '/')) { | ||||
| 	progname = p + 1; | ||||
|   } | ||||
|  | @ -66,20 +69,19 @@ main(argc, argv) | |||
|   else if (AObj == 0) AObj = "a.out"; | ||||
|   reserve(tkidf); | ||||
|   reserve(shorts); | ||||
|   if (currfile) CurrentScope = currfile->sy_file->f_scope; | ||||
|   if (! init_run()) { | ||||
| 	fatal("something wrong with file descriptors"); | ||||
|   } | ||||
|   prompt(); | ||||
|   Commands(); | ||||
|   fputc( '\n', db_out); | ||||
|   if (eof_seen) fputc('\n', db_out); | ||||
|   exit(0); | ||||
| } | ||||
| 
 | ||||
| prompt() | ||||
| { | ||||
|   if (isatty(fileno(db_in))) { | ||||
| 	fprintf(db_out, "%s -> ", progname); | ||||
| 	fprintf(db_out, "-> "); | ||||
| 	fflush(db_out); | ||||
|   } | ||||
| } | ||||
|  | @ -94,12 +96,11 @@ fatal(va_alist) | |||
|   va_start(ap); | ||||
|   { | ||||
| 	fmt = va_arg(ap, char *); | ||||
| 	fprintf(stderr, "%s: ", progname); | ||||
| 	vfprintf(stderr, fmt, ap); | ||||
| 	fprintf(stderr, "\n"); | ||||
| 	fprintf(db_out, "%s: ", progname); | ||||
| 	vfprintf(db_out, fmt, ap); | ||||
| 	fprintf(db_out, "\n"); | ||||
|   } | ||||
|   va_end(ap); | ||||
|   abort(); | ||||
|   exit(1); | ||||
| } | ||||
| 
 | ||||
|  | @ -115,9 +116,9 @@ error(va_alist) | |||
|   va_start(ap); | ||||
|   { | ||||
| 	fmt = va_arg(ap, char *); | ||||
| 	fprintf(stderr, "%s: ", progname); | ||||
| 	vfprintf(stderr, fmt, ap); | ||||
| 	fprintf(stderr, "\n"); | ||||
| 	fprintf(db_out, "%s: ", progname); | ||||
| 	vfprintf(db_out, fmt, ap); | ||||
| 	fprintf(db_out, "\n"); | ||||
|   } | ||||
|   va_end(ap); | ||||
|   errorgiven = 1; | ||||
|  | @ -133,9 +134,9 @@ warning(va_alist) | |||
|   va_start(ap); | ||||
|   { | ||||
| 	fmt = va_arg(ap, char *); | ||||
| 	fprintf(stderr, "%s: ", progname); | ||||
| 	vfprintf(stderr, fmt, ap); | ||||
| 	fprintf(stderr, "\n"); | ||||
| 	fprintf(db_out, "%s: ", progname); | ||||
| 	vfprintf(db_out, fmt, ap); | ||||
| 	fprintf(db_out, "\n"); | ||||
|   } | ||||
|   va_end(ap); | ||||
| } | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ struct message_hdr { | |||
| #define FAIL	51	/* answer of child when something goes wrong */ | ||||
| #define DATA	52	/* answer of child when data requested */ | ||||
| #define END_SS	53	/* when stopped because of user single stepping */ | ||||
| #define INTR	54	/* sent on interrupt */ | ||||
|   long	m_size;		/* size */ | ||||
|   char	m_buf[BUFLEN];	/* some of the data required included in message */ | ||||
| }; | ||||
|  |  | |||
|  | @ -110,8 +110,6 @@ unop_prio(op) | |||
|   case E_MIN: | ||||
|   case E_PLUS: | ||||
| 	return 3; | ||||
|   case E_SELECT: | ||||
| 	return 9; | ||||
|   } | ||||
|   return 1; | ||||
| } | ||||
|  | @ -121,6 +119,10 @@ binop_prio(op) | |||
|   int	op; | ||||
| { | ||||
|   switch(op) { | ||||
|   case E_SELECT: | ||||
| 	return 9; | ||||
|   case E_ARRAY: | ||||
| 	return 5; | ||||
|   case E_AND: | ||||
|   case E_MUL: | ||||
|   case E_DIV: | ||||
|  | @ -357,15 +359,18 @@ get_token(c) | |||
|   register int	c; | ||||
| { | ||||
|   switch(c) { | ||||
|   case '[': | ||||
| 	tok.ival = E_ARRAY; | ||||
| 	/* fall through */ | ||||
|   case '(': | ||||
|   case ')': | ||||
|   case '[': | ||||
|   case ']': | ||||
|   case '`': | ||||
|   case '{': | ||||
|   case '}': | ||||
|   case ':': | ||||
|   case ',': | ||||
|   case '\\': | ||||
| 	return c; | ||||
| 
 | ||||
|   case '.': | ||||
|  | @ -424,7 +429,7 @@ get_token(c) | |||
| 	tok.ival = E_NOT; | ||||
| 	return PREF_OP; | ||||
|   default: | ||||
| 	error("illegal character 0%o", c); | ||||
| 	error((c >= 040 && c < 0177) ? "%s'%c'" : "%s'\\0%o'", "illegal character ", c); | ||||
| 	return LLlex(); | ||||
|   } | ||||
| } | ||||
|  | @ -440,6 +445,7 @@ get_string(c) | |||
|   while (ch = getc(db_in), ch != c) { | ||||
| 	if (ch == '\n') { | ||||
| 		error("newline in string"); | ||||
| 		ungetc(ch, db_in); | ||||
| 		break; | ||||
| 	} | ||||
| 	buf[len++] = ch; | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ OP_STRING	0	0 | |||
| OP_NAME		0	0 | ||||
| OP_AT		0	0 | ||||
| OP_IN		1	0 | ||||
| OP_HELP		0	do_help | ||||
| OP_STOP		2	do_stop | ||||
| OP_WHEN		3	do_stop | ||||
| OP_CONT		2	do_continue | ||||
|  | @ -17,8 +18,8 @@ OP_STEP		0	do_step | |||
| OP_NEXT		0	do_next | ||||
| OP_REGS		0	do_regs | ||||
| OP_WHERE	0	do_where | ||||
| OP_STATUS	0	do_status | ||||
| OP_DELETE	0	do_delete | ||||
| OP_STATUS	0	print_items | ||||
| OP_DELETE	1	do_delete | ||||
| OP_SELECT	2	0 | ||||
| OP_SET		2	do_set | ||||
| OP_PRINT	1	do_print | ||||
|  | @ -30,3 +31,6 @@ OP_DISPLAY	1	add_to_item_list | |||
| OP_WHICH	1	do_which | ||||
| OP_UNOP		1	0 | ||||
| OP_BINOP	2	0 | ||||
| OP_FORMAT	2	0 | ||||
| OP_DISABLE	1	do_disable | ||||
| OP_ENABLE	1	do_enable | ||||
|  |  | |||
|  | @ -127,9 +127,11 @@ add_position_addr(filename, n) | |||
| 	map->f_start = n; | ||||
|   } | ||||
|   else map = lastmap; | ||||
|   map->f_end = n; | ||||
|   setnext_outname(n, map->f_line_addr[HASH(n->on_desc)]); | ||||
|   map->f_line_addr[HASH(n->on_desc)] = n; | ||||
|   if (map) { | ||||
|   	map->f_end = n; | ||||
|   	setnext_outname(n, map->f_line_addr[HASH(n->on_desc)]); | ||||
|   	map->f_line_addr[HASH(n->on_desc)] = n; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /* extern p_position print_position(t_addr a, int print_function);
 | ||||
|  |  | |||
|  | @ -15,46 +15,99 @@ | |||
| 
 | ||||
| extern FILE *db_out; | ||||
| extern long float_size, pointer_size, int_size; | ||||
| extern char *strindex(); | ||||
| 
 | ||||
| static | ||||
| print_literal(tp, v) | ||||
| print_unsigned(tp, v, format) | ||||
|   p_type	tp; | ||||
|   long		v; | ||||
|   register char	*format; | ||||
| { | ||||
|   while (format && *format) { | ||||
| 	if (strindex("cdohx", *format)) break; | ||||
| 	format++; | ||||
|   } | ||||
|   switch(format == 0 ? 0 : *format) { | ||||
|   default: | ||||
| 	if (tp != uchar_type) { | ||||
|   		fprintf(db_out, currlang->uns_fmt, v); | ||||
| 		break; | ||||
| 	} | ||||
| 	/* fall through */ | ||||
|   case 'c': | ||||
| 	(*currlang->printchar)((int) v); | ||||
| 	break; | ||||
|   case 'd': | ||||
|   	fprintf(db_out, currlang->decint_fmt, v); | ||||
| 	break; | ||||
|   case 'o': | ||||
|   	fprintf(db_out, currlang->octint_fmt, v); | ||||
| 	break; | ||||
|   case 'x': | ||||
|   case 'h': | ||||
|   	fprintf(db_out, currlang->hexint_fmt, v); | ||||
| 	break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| static | ||||
| print_literal(tp, v, compressed, format) | ||||
|   p_type	tp; | ||||
|   long		v; | ||||
|   int		compressed; | ||||
|   char		*format; | ||||
| { | ||||
|   register struct literal *lit = tp->ty_literals; | ||||
|   register int i; | ||||
| 
 | ||||
|   if (format) { | ||||
| 	print_unsigned(tp, v, format); | ||||
| 	return; | ||||
|   } | ||||
|   for (i = tp->ty_nenums; i; i--, lit++) { | ||||
| 	if (lit->lit_val == v) { | ||||
| 		fprintf(db_out, lit->lit_name); | ||||
| 		fputs(lit->lit_name, db_out); | ||||
| 		break; | ||||
| 	} | ||||
|   } | ||||
|   if (! i) { | ||||
| 	fprintf(db_out, "unknown enumeration value %d", v); | ||||
| 	fprintf(db_out, | ||||
| 		compressed ? "?%ld?" : "unknown enumeration value %ld", | ||||
| 		v); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| static | ||||
| print_unsigned(tp, v) | ||||
| print_integer(tp, v, format) | ||||
|   p_type	tp; | ||||
|   long		v; | ||||
|   register char	*format; | ||||
| { | ||||
|   if (tp == uchar_type) { | ||||
| 	(*currlang->printchar)((int) v); | ||||
|   while (format && *format) { | ||||
| 	if (strindex("cdohx", *format)) break; | ||||
| 	format++; | ||||
|   } | ||||
|   else	fprintf(db_out, currlang->uns_fmt, v); | ||||
| } | ||||
| 
 | ||||
| static | ||||
| print_integer(tp, v) | ||||
|   p_type	tp; | ||||
|   long		v; | ||||
| { | ||||
|   if (tp == char_type) { | ||||
|   switch(format == 0 ? 0 : *format) { | ||||
|   default: | ||||
| 	if (tp != char_type) { | ||||
|   		fprintf(db_out, currlang->decint_fmt, v); | ||||
| 		break; | ||||
| 	} | ||||
| 	/* fall through */ | ||||
|   case 'c': | ||||
| 	(*currlang->printchar)((int) v); | ||||
| 	break; | ||||
|   case 'd': | ||||
|   	fprintf(db_out, currlang->decint_fmt, v); | ||||
| 	break; | ||||
|   case 'o': | ||||
|   	fprintf(db_out, currlang->octint_fmt, v); | ||||
| 	break; | ||||
|   case 'x': | ||||
|   case 'h': | ||||
|   	fprintf(db_out, currlang->hexint_fmt, v); | ||||
| 	break; | ||||
|   } | ||||
|   else	fprintf(db_out, currlang->decint_fmt, v); | ||||
| } | ||||
| 
 | ||||
| print_params(tp, AB, static_link) | ||||
|  | @ -83,7 +136,6 @@ print_params(tp, AB, static_link) | |||
|   } | ||||
|   if (static_link) p += pointer_size; | ||||
|   if (! get_bytes(size, AB, param_bytes)) { | ||||
| 	error("no debuggee"); | ||||
| 	free(param_bytes); | ||||
| 	return; | ||||
|   } | ||||
|  | @ -110,11 +162,11 @@ print_params(tp, AB, static_link) | |||
| 			fprintf(db_out, currlang->addr_fmt, (long) addr); | ||||
| 		} | ||||
| 		else { | ||||
| 			print_val(par->par_type, size, q, 1, 0); | ||||
| 			print_val(par->par_type, size, q, 1, 0, (char *)0); | ||||
| 		} | ||||
| 		free(q); | ||||
| 	} | ||||
| 	else print_val(par->par_type, par->par_type->ty_size, p, 1, 0); | ||||
| 	else print_val(par->par_type, par->par_type->ty_size, p, 1, 0, (char *)0); | ||||
| 	if (i) fputs(", ", db_out); | ||||
| 	p += param_size(par->par_type, par->par_kind); | ||||
| 	par++; | ||||
|  | @ -122,12 +174,13 @@ print_params(tp, AB, static_link) | |||
|   free(param_bytes); | ||||
| } | ||||
| 
 | ||||
| print_val(tp, tp_sz, addr, compressed, indent) | ||||
| print_val(tp, tp_sz, addr, compressed, indent, format) | ||||
|   p_type	tp;		/* type of value to be printed */ | ||||
|   long		tp_sz;		/* size of object to be printed */ | ||||
|   char		*addr;		/* address to get value from */ | ||||
|   int		compressed;	/* for parameter lists */ | ||||
|   int		indent;		/* indentation */ | ||||
|   register char	*format;	/* format given or 0 */ | ||||
| { | ||||
|   register int i; | ||||
|   long elsize; | ||||
|  | @ -135,12 +188,13 @@ print_val(tp, tp_sz, addr, compressed, indent) | |||
|   if (indent == 0) indent = 4; | ||||
|   switch(tp->ty_class) { | ||||
|   case T_SUBRANGE: | ||||
| 	print_val(tp->ty_base, tp_sz, addr, compressed, indent); | ||||
| 	print_val(tp->ty_base, tp_sz, addr, compressed, indent, format); | ||||
| 	break; | ||||
|   case T_ARRAY: | ||||
| 	if (tp->ty_elements == char_type || | ||||
| 	    tp->ty_elements == uchar_type) { | ||||
| 		print_val(string_type, tp_sz, addr, compressed, indent); | ||||
| 	if ((!format || strindex(format, 'a') == 0) && | ||||
| 	    (tp->ty_elements == char_type || | ||||
| 	     tp->ty_elements == uchar_type)) { | ||||
| 		print_val(string_type, tp_sz, addr, compressed, indent, format); | ||||
| 		break; | ||||
| 	} | ||||
| 	if (compressed) { | ||||
|  | @ -156,7 +210,7 @@ print_val(tp, tp_sz, addr, compressed, indent) | |||
| 	indent += 4; | ||||
| 	elsize = (*currlang->arrayelsize)(tp->ty_elements->ty_size); | ||||
| 	for (i = tp_sz/elsize; i; i--) { | ||||
| 		print_val(tp->ty_elements, tp->ty_elements->ty_size, addr, compressed, indent); | ||||
| 		print_val(tp->ty_elements, tp->ty_elements->ty_size, addr, compressed, indent, format); | ||||
| 		addr += elsize; | ||||
| 		if (compressed && i > 1) { | ||||
| 			fprintf(db_out, ", ..."); | ||||
|  | @ -192,7 +246,7 @@ print_val(tp, tp_sz, addr, compressed, indent) | |||
| 			/* ??? */ | ||||
| 			fprintf(db_out, "<bitfield, %d, %ld>", fld->fld_bitsize, sz); | ||||
| 		} | ||||
| 		else print_val(fld->fld_type, sz, addr+(fld->fld_pos>>3), compressed, indent); | ||||
| 		else print_val(fld->fld_type, sz, addr+(fld->fld_pos>>3), compressed, indent, format); | ||||
| 		if (compressed && i > 1) { | ||||
| 			fprintf(db_out, ", ..."); | ||||
| 			break; | ||||
|  | @ -210,7 +264,7 @@ print_val(tp, tp_sz, addr, compressed, indent) | |||
| 	fprintf(db_out, "<union>"); | ||||
| 	break; | ||||
|   case T_ENUM: | ||||
| 	print_literal(tp, get_int(addr, tp_sz, T_ENUM)); | ||||
| 	print_literal(tp, get_int(addr, tp_sz, T_ENUM), compressed, format); | ||||
| 	break; | ||||
|   case T_PROCEDURE: { | ||||
| 	register p_scope sc = get_scope_from_addr((t_addr) get_int(addr, pointer_size, T_UNSIGNED)); | ||||
|  | @ -220,8 +274,21 @@ print_val(tp, tp_sz, addr, compressed, indent) | |||
| 		break; | ||||
| 	} | ||||
| 	} | ||||
| 	/* Fall through */ | ||||
| 	fprintf(db_out, currlang->addr_fmt, get_int(addr, pointer_size, T_UNSIGNED)); | ||||
| 	break; | ||||
|   case T_POINTER: | ||||
| 	if (format && strindex(format,'s') && | ||||
| 	    (tp->ty_ptrto == char_type || tp->ty_ptrto == uchar_type)) { | ||||
| 		t_addr a = get_int(addr, tp_sz, T_UNSIGNED); | ||||
| 		char *naddr = malloc(512); | ||||
| 
 | ||||
| 		if (naddr && get_string(511L, a, naddr)) { | ||||
| 			print_val(string_type, 512L, naddr, 0, indent, format); | ||||
| 			free(naddr); | ||||
| 			break; | ||||
| 		} | ||||
| 		if (naddr) free(naddr); | ||||
| 	} | ||||
| 	fprintf(db_out, currlang->addr_fmt, get_int(addr, pointer_size, T_UNSIGNED)); | ||||
| 	break; | ||||
|   case T_FILE: | ||||
|  | @ -259,13 +326,13 @@ print_val(tp, tp_sz, addr, compressed, indent) | |||
| 			} | ||||
| 			switch(base->ty_class) { | ||||
| 			case T_INTEGER: | ||||
| 				print_integer(base, val+i); | ||||
| 				print_integer(base, val+i, format); | ||||
| 				break; | ||||
| 			case T_UNSIGNED: | ||||
| 				print_unsigned(base, val+i); | ||||
| 				print_unsigned(base, val+i, format); | ||||
| 				break; | ||||
| 			case T_ENUM: | ||||
| 				print_literal(base, val+i); | ||||
| 				print_literal(base, val+i, compressed, format); | ||||
| 				break; | ||||
| 			default: | ||||
| 				assert(0); | ||||
|  | @ -283,10 +350,10 @@ print_val(tp, tp_sz, addr, compressed, indent) | |||
| 	fprintf(db_out, currlang->real_fmt, get_real(addr, tp->ty_size)); | ||||
| 	break; | ||||
|   case T_UNSIGNED: | ||||
| 	print_unsigned(tp, get_int(addr, tp_sz, T_UNSIGNED)); | ||||
| 	print_unsigned(tp, get_int(addr, tp_sz, T_UNSIGNED), format); | ||||
| 	break; | ||||
|   case T_INTEGER: | ||||
| 	print_integer(tp, get_int(addr, tp_sz, T_INTEGER)); | ||||
| 	print_integer(tp, get_int(addr, tp_sz, T_INTEGER), format); | ||||
| 	break; | ||||
|   case T_STRING: | ||||
| 	(*currlang->printstring)(addr, (int) tp_sz); | ||||
|  |  | |||
							
								
								
									
										182
									
								
								util/grind/run.c
									
										
									
									
									
								
							
							
						
						
									
										182
									
								
								util/grind/run.c
									
										
									
									
									
								
							|  | @ -27,20 +27,25 @@ extern char	*AObj; | |||
| extern FILE	*db_out; | ||||
| extern int	debug; | ||||
| extern long	pointer_size; | ||||
| extern char	*progname; | ||||
| extern int	child_interrupted; | ||||
| extern int	interrupted; | ||||
| 
 | ||||
| static int	child_pid;		/* process id of child */ | ||||
| static int	to_child, from_child;	/* file descriptors for communication */ | ||||
| static int	child_status; | ||||
| static int	restoring; | ||||
| static int	fild1[2], fild2[2];	/* pipe file descriptors */ | ||||
| int		disable_intr = 1; | ||||
| 
 | ||||
| int		db_ss; | ||||
| t_lineno	currline, listline; | ||||
| t_lineno	currline; | ||||
| 
 | ||||
| static int	catch_sigpipe(); | ||||
| static int	stopped(); | ||||
| static int	uputm(), ugetm(); | ||||
| static t_addr	curr_stop; | ||||
| p_tree		run_command; | ||||
| 
 | ||||
| int | ||||
| init_run() | ||||
|  | @ -57,9 +62,13 @@ init_run() | |||
|   } | ||||
|   to_child = fild1[1]; | ||||
|   from_child = fild2[0]; | ||||
|   child_pid = 0; | ||||
|   if (currfile) CurrentScope = currfile->sy_file->f_scope; | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| extern int errno; | ||||
| 
 | ||||
| int | ||||
| start_child(p) | ||||
|   p_tree	p; | ||||
|  | @ -76,6 +85,10 @@ start_child(p) | |||
| 			    allowed one child | ||||
| 			 */ | ||||
| 
 | ||||
|   if (p != run_command) { | ||||
| 	freenode(run_command); | ||||
| 	run_command = p; | ||||
|   } | ||||
|   /* first check arguments and redirections and build argument list */ | ||||
|   while (pt) { | ||||
|   	switch(pt->t_oper) { | ||||
|  | @ -133,7 +146,7 @@ start_child(p) | |||
| 		close(0); | ||||
| 		if ((fd = open(in_redirect, 0)) < 0 || | ||||
| 		    (fd != 0 && dup2(fd, 0) < 0)) { | ||||
| 			error("could not open input file"); | ||||
| 			perror(progname); | ||||
| 			exit(1); | ||||
| 		} | ||||
| 		if (fd != 0) { | ||||
|  | @ -142,10 +155,11 @@ start_child(p) | |||
| 	} | ||||
| 	if (out_redirect) { | ||||
| 		int fd; | ||||
| 
 | ||||
| 		close(1); | ||||
| 		if ((fd = creat(in_redirect, 0666)) < 0 || | ||||
| 		if ((fd = creat(out_redirect, 0666)) < 0 || | ||||
| 		    (fd != 1 && dup2(fd, 1) < 0)) { | ||||
| 			error("could not open output file"); | ||||
| 			perror(progname); | ||||
| 			exit(1); | ||||
| 		} | ||||
| 		if (fd != 1) { | ||||
|  | @ -165,32 +179,23 @@ start_child(p) | |||
| 
 | ||||
|   pipe(fild1);		/* to occupy file descriptors */ | ||||
|   signal(SIGPIPE, catch_sigpipe); | ||||
|   if (! wait_for_child((char *) 0)) { | ||||
| 	error("child not responding"); | ||||
| 	return 0; | ||||
|   { | ||||
| 	struct message_hdr m; | ||||
| 
 | ||||
|   	if (! ugetm(&m)) { | ||||
| 		error("child not responding"); | ||||
| 		init_run(); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	curr_stop = m.m_size; | ||||
| 	CurrentScope = get_scope_from_addr(curr_stop); | ||||
|   } | ||||
|   do_items(); | ||||
|   if (! restoring && ! item_addr_actions(curr_stop)) { | ||||
|   if (! restoring && ! item_addr_actions(curr_stop, OK)) { | ||||
| 	send_cont(1); | ||||
|   } | ||||
|   else if (! restoring) { | ||||
| 	stopped("stopped", curr_stop); | ||||
| 	handle_displays(); | ||||
|   } | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| wait_for_child(s) | ||||
|   char	*s;		/* to pass on to 'stopped' */ | ||||
| { | ||||
|   struct message_hdr m; | ||||
| 
 | ||||
|   if (child_pid) { | ||||
|   	if (ugetm(&m)) { | ||||
| 		return stopped(s, (t_addr) m.m_size); | ||||
|   	} | ||||
|   	return 0; | ||||
|   } | ||||
|   return 1; | ||||
| } | ||||
|  | @ -212,7 +217,6 @@ catch_sigpipe() | |||
|   child_pid = 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int | ||||
| ureceive(p, c) | ||||
|   char	*p; | ||||
|  | @ -252,6 +256,7 @@ usend(p, c) | |||
| { | ||||
|   int	i; | ||||
| 
 | ||||
|   if (! child_pid) return 0; | ||||
|   while (c >= 0x1000) { | ||||
| 	i = write(to_child, p, 0x1000); | ||||
| 	if (i < 0) return 0; | ||||
|  | @ -299,11 +304,12 @@ stopped(s, a) | |||
| { | ||||
|   p_position pos; | ||||
| 
 | ||||
|   if (s) { | ||||
|   if (s && a) { | ||||
| 	fprintf(db_out, "%s ", s); | ||||
| 	pos = print_position(a, 1); | ||||
| 	fputs("\n", db_out); | ||||
| 	list_position(pos); | ||||
| 	handle_displays(); | ||||
|   } | ||||
|   curr_stop = a; | ||||
|   return 1; | ||||
|  | @ -315,16 +321,37 @@ could_send(m, stop_message) | |||
| { | ||||
|   int	type; | ||||
|   t_addr a; | ||||
|   static int level = 0; | ||||
| 
 | ||||
|   level++; | ||||
|   for (;;) { | ||||
|   	if (child_pid) { | ||||
| 		if (! uputm(m) || | ||||
| 		    ! ugetm(&answer)) { | ||||
| 			if (child_pid) { | ||||
| 				error("something wrong!"); | ||||
| 		int child_dead = 0; | ||||
| 		if (m->m_type & DB_RUN) disable_intr = 0; | ||||
| 		if (!child_interrupted && (! uputm(m) || ! ugetm(&answer))) { | ||||
| 			child_dead = 1; | ||||
| 		} | ||||
| 		disable_intr = 1; | ||||
| 		if ((interrupted || child_interrupted) && ! child_dead) { | ||||
| 			while (child_interrupted && answer.m_type != INTR) { | ||||
| 				if (! ugetm(&answer)) { | ||||
| 					child_dead = 1; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (interrupted && ! child_dead) { | ||||
| 				level--; | ||||
| 				if (! level) { | ||||
| 					child_interrupted = 0; | ||||
| 					CurrentScope = get_scope_from_addr((t_addr) answer.m_size); | ||||
| 					interrupted = 0; | ||||
| 					stopped("interrupted", (t_addr) answer.m_size); | ||||
| 				} | ||||
| 				return 1; | ||||
| 			} | ||||
| 		} | ||||
| 		if (child_dead) { | ||||
| 			wait(&child_status); | ||||
| 			init_run(); | ||||
| 			if (child_status & 0177) { | ||||
| 				fprintf(db_out, | ||||
| 					"child died with signal %d\n", | ||||
|  | @ -335,6 +362,8 @@ could_send(m, stop_message) | |||
| 					"child terminated, exit status %d\n", | ||||
| 					child_status >> 8); | ||||
| 			} | ||||
| 			init_run(); | ||||
| 			level--; | ||||
| 			return 1; | ||||
| 		} | ||||
| 		a = answer.m_size; | ||||
|  | @ -342,7 +371,7 @@ could_send(m, stop_message) | |||
| 		if (m->m_type & DB_RUN) { | ||||
| 			/* run command */ | ||||
| 			CurrentScope = get_scope_from_addr((t_addr) a); | ||||
| 		    	if (! item_addr_actions(a) && | ||||
| 		    	if (! item_addr_actions(a, type) && | ||||
| 		            ( type == DB_SS || type == OK)) { | ||||
| 				/* no explicit breakpoints at this position.
 | ||||
| 				   Also, child did not stop because of | ||||
|  | @ -363,38 +392,61 @@ could_send(m, stop_message) | |||
| 		} | ||||
| 		if (stop_message) { | ||||
| 			stopped("stopped", a); | ||||
| 			handle_displays(); | ||||
| 		} | ||||
| 		return 1; | ||||
| 		level--; | ||||
| 		return type; | ||||
| 	} | ||||
| 	level--; | ||||
| 	return 0; | ||||
|   } | ||||
|   /*NOTREACHED*/ | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| getbytes(size, from, to, kind) | ||||
|   long	size; | ||||
|   t_addr from; | ||||
|   char	*to; | ||||
| { | ||||
|   struct message_hdr	m; | ||||
| 
 | ||||
|   m.m_type = kind; | ||||
|   m.m_size = size; | ||||
|   put_int(m.m_buf, pointer_size, (long)from); | ||||
| 
 | ||||
|   if (! could_send(&m, 0)) { | ||||
| 	error("no process"); | ||||
| 	return 0; | ||||
|   } | ||||
| 
 | ||||
|   if (answer.m_type == FAIL || answer.m_type == INTR) { | ||||
| 	return 0; | ||||
|   } | ||||
| 
 | ||||
|   assert(answer.m_type == DATA); | ||||
| 
 | ||||
|   return ureceive(to, answer.m_size); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| get_bytes(size, from, to) | ||||
|   long	size; | ||||
|   t_addr from; | ||||
|   char	*to; | ||||
| { | ||||
|   struct message_hdr	m; | ||||
|   return getbytes(size, from, to, GETBYTES); | ||||
| } | ||||
| 
 | ||||
|   m.m_type = GETBYTES; | ||||
|   m.m_size = size; | ||||
|   put_int(m.m_buf, pointer_size, (long)from); | ||||
| int | ||||
| get_string(size, from, to) | ||||
|   long	size; | ||||
|   t_addr from; | ||||
|   char	*to; | ||||
| { | ||||
|   int retval = getbytes(size, from, to, GETSTR); | ||||
| 
 | ||||
|   if (! could_send(&m, 0)) { | ||||
| 	return 0; | ||||
|   } | ||||
| 
 | ||||
|   if (answer.m_type == FAIL) { | ||||
| 	return 0; | ||||
|   } | ||||
| 
 | ||||
|   assert(answer.m_type == DATA && answer.m_size == m.m_size); | ||||
| 
 | ||||
|   return ureceive(to, answer.m_size); | ||||
|   to[(int)answer.m_size] = 0; | ||||
|   return retval; | ||||
| } | ||||
| 
 | ||||
| int | ||||
|  | @ -409,8 +461,7 @@ set_bytes(size, from, to) | |||
|   m.m_size = size; | ||||
|   put_int(m.m_buf, pointer_size, (long) to); | ||||
| 
 | ||||
|   return uputm(&m) | ||||
| 	 && usend(from, size) | ||||
|   return uputm(&m) && usend(from, size) | ||||
| 	 && ugetm(&m) | ||||
| 	 && m.m_type != FAIL; | ||||
| } | ||||
|  | @ -424,16 +475,16 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf) | |||
| 
 | ||||
|   m.m_type = DUMP; | ||||
|   if (! could_send(&m, 0)) { | ||||
| 	error("no debuggee"); | ||||
| 	error("no process"); | ||||
| 	return 0; | ||||
|   } | ||||
|   if (answer.m_type == FAIL) return 0; | ||||
|   if (answer.m_type == FAIL || answer.m_type == INTR) return 0; | ||||
|   assert(answer.m_type == DGLOB); | ||||
|   *globmessage = answer; | ||||
|   *globbuf = malloc((unsigned) answer.m_size); | ||||
|   if (! ureceive(*globbuf, answer.m_size) || ! ugetm(stackmessage)) { | ||||
| 	if (*globbuf) free(*globbuf); | ||||
| 	error("no debuggee"); | ||||
| 	error("no process"); | ||||
| 	return 0; | ||||
|   } | ||||
|   assert(stackmessage->m_type == DSTACK); | ||||
|  | @ -441,7 +492,7 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf) | |||
|   if (! ureceive(*stackbuf, stackmessage->m_size)) { | ||||
| 	if (*globbuf) free(*globbuf); | ||||
| 	if (*stackbuf) free(*stackbuf); | ||||
| 	error("no debuggee"); | ||||
| 	error("no process"); | ||||
| 	return 0; | ||||
|   } | ||||
|   put_int(globmessage->m_buf+SP_OFF*pointer_size, pointer_size, | ||||
|  | @ -461,17 +512,17 @@ put_dump(globmessage, globbuf, stackmessage, stackbuf) | |||
|   char *globbuf, *stackbuf; | ||||
| { | ||||
|   struct message_hdr m; | ||||
|   int retval; | ||||
| 
 | ||||
|   if (! child_pid) { | ||||
| 	restoring = 1; | ||||
| 	start_child(run_command); | ||||
| 	restoring = 0; | ||||
|   } | ||||
|   return	uputm(globmessage) && | ||||
| 		usend(globbuf, globmessage->m_size) && | ||||
| 		uputm(stackmessage) && | ||||
| 		usend(stackbuf, stackmessage->m_size) && | ||||
|   retval =	uputm(globmessage) && usend(globbuf, globmessage->m_size) && | ||||
| 		uputm(stackmessage) && usend(stackbuf, stackmessage->m_size) && | ||||
| 		ugetm(&m) && stopped("restored", m.m_size); | ||||
|   return retval; | ||||
| } | ||||
| 
 | ||||
| t_addr * | ||||
|  | @ -486,9 +537,10 @@ get_EM_regs(level) | |||
|   m.m_size = level; | ||||
| 
 | ||||
|   if (! could_send(&m, 0)) { | ||||
| 	error("no process"); | ||||
| 	return 0; | ||||
|   } | ||||
|   if (answer.m_type == FAIL) return 0; | ||||
|   if (answer.m_type == FAIL || answer.m_type == INTR) return 0; | ||||
|   *to++ = (t_addr) get_int(answer.m_buf, pointer_size, T_UNSIGNED); | ||||
|   *to++ = (t_addr) get_int(answer.m_buf+pointer_size, pointer_size, T_UNSIGNED); | ||||
|   *to++ = (t_addr) get_int(answer.m_buf+2*pointer_size, pointer_size, T_UNSIGNED); | ||||
|  | @ -506,7 +558,7 @@ set_pc(PC) | |||
|   m.m_type = SETEMREGS; | ||||
|   m.m_size = 0; | ||||
|   put_int(m.m_buf+PC_OFF*pointer_size, pointer_size, (long)PC); | ||||
|   return could_send(&m, 0) && answer.m_type != FAIL; | ||||
|   return could_send(&m, 0) && answer.m_type != FAIL && answer.m_type != INTR; | ||||
| } | ||||
| 
 | ||||
| int | ||||
|  | @ -530,7 +582,7 @@ do_single_step(type, count) | |||
|   m.m_type = type | (db_ss ? DB_SS : 0); | ||||
|   m.m_size = count; | ||||
|   single_stepping = 1; | ||||
|   if (could_send(&m, 1) && answer.m_type != FAIL) { | ||||
|   if (could_send(&m, 1) && answer.m_type != FAIL && answer.m_type != INTR) { | ||||
| 	return 1; | ||||
|   } | ||||
|   single_stepping = 0; | ||||
|  | @ -549,7 +601,8 @@ set_or_clear_breakpoint(a, type) | |||
|   m.m_type = type; | ||||
|   m.m_size = a; | ||||
|   if (debug) printf("%s breakpoint at 0x%lx\n", type == SETBP ? "setting" : "clearing", (long) a); | ||||
|   if (! could_send(&m, 0)) { } | ||||
|   if (! could_send(&m, 0)) { | ||||
|   } | ||||
| 
 | ||||
|   return 1; | ||||
| } | ||||
|  | @ -565,7 +618,8 @@ set_or_clear_trace(start, end, type) | |||
|   put_int(m.m_buf, pointer_size, (long)start); | ||||
|   put_int(m.m_buf+pointer_size, pointer_size, (long)end); | ||||
|   if (debug) printf("%s trace at [0x%lx,0x%lx]\n", type == SETTRACE ? "setting" : "clearing", (long) start, (long) end); | ||||
|   if (! could_send(&m, 0)) { } | ||||
|   if (! could_send(&m, 0)) { | ||||
|   } | ||||
| 
 | ||||
|   return 1; | ||||
| } | ||||
|  |  | |||
|  | @ -117,11 +117,12 @@ add_file(s) | |||
| 	p_symbol sym1; | ||||
| 
 | ||||
| 	*p = 0; | ||||
| 	sym1 = NewSymbol(Salloc(s, (unsigned) strlen(s)+1), | ||||
| 	s = Salloc(s, (unsigned) strlen(s)+1); | ||||
| 	*p = c; | ||||
| 	sym1 = NewSymbol(s, | ||||
| 		  	 PervasiveScope, | ||||
| 		 	 FILELINK, | ||||
| 			 (struct outname *) 0); | ||||
| 	*p = c; | ||||
| 	sym1->sy_filelink = sym; | ||||
| 	sym->sy_file->f_base = sym1; | ||||
|   } | ||||
|  | @ -171,11 +172,14 @@ consistent(p, sc) | |||
| #define CLASS	(FILELINK|FILESYM|PROC|FUNCTION|MODULE|TYPE|VAR|REGVAR|LOCVAR|VARPAR) | ||||
| 	sym = Lookfromscope(p->t_idf, CLASS, sc->sc_static_encl); | ||||
| 	if (sym) { | ||||
| 		int precise = 1; | ||||
| 
 | ||||
| 		target_sc = def_scope(sym); | ||||
| 		while (sc && sc != target_sc) { | ||||
| 			precise = 0; | ||||
| 			sc = sc->sc_static_encl; | ||||
| 		} | ||||
| 		return sc != 0; | ||||
| 		return sc == 0 ? 0 : precise + 1 ; | ||||
| 	} | ||||
| 	return 0; | ||||
| 
 | ||||
|  | @ -183,11 +187,16 @@ consistent(p, sc) | |||
| 	arg = p->t_args[1]; | ||||
| 	sym = Lookfromscope(arg->t_idf, CLASS, sc->sc_static_encl); | ||||
| 	if (sym) { | ||||
| 		int precise = 1; | ||||
| 
 | ||||
| 		target_sc = def_scope(sym); | ||||
| 		while (sc && sc != target_sc) { | ||||
| 			precise = 0; | ||||
| 			sc = sc->sc_static_encl; | ||||
| 		} | ||||
| 		return sc != 0 && consistent(p, sym->sy_scope); | ||||
| 		if (sc == 0) return 0; | ||||
| 		if (precise) return consistent(p, sym->sy_scope); | ||||
| 		return consistent(p, sym->sy_scope) != 0; | ||||
| 	} | ||||
| 	return 0; | ||||
| 
 | ||||
|  | @ -205,9 +214,10 @@ identify(p, class_set) | |||
|   p_tree	p; | ||||
|   int		class_set; | ||||
| { | ||||
|   p_symbol	sym = 0; | ||||
|   p_symbol	sym = 0, sym1 = 0; | ||||
|   register p_symbol s; | ||||
|   p_tree	arg; | ||||
|   int precise = 0; | ||||
| 
 | ||||
|   switch(p->t_oper) { | ||||
|   case OP_NAME: | ||||
|  | @ -243,19 +253,26 @@ identify(p, class_set) | |||
| 	arg = p->t_args[1]; | ||||
| 	assert(arg->t_oper == OP_NAME); | ||||
| 	s = arg->t_idf->id_def; | ||||
| 	sym = 0; | ||||
| 	while (s) { | ||||
| 		if ((s->sy_class & class_set) && consistent(p, s->sy_scope)) { | ||||
| 			if (sym) { | ||||
| 				error("could not identify \"%s\"", arg->t_str); | ||||
| 				sym = 0; | ||||
| 		int temp; | ||||
| 		if ((s->sy_class & class_set) && | ||||
| 		    (temp = consistent(p, s->sy_scope))) { | ||||
| 			if (temp > precise) { | ||||
| 				sym = s; | ||||
| 				precise = temp; | ||||
| 				sym1 = 0; | ||||
| 			} | ||||
| 			sym = s; | ||||
| 			else if (sym && temp == precise) sym1 = s; | ||||
| 		} | ||||
| 		s = s->sy_next; | ||||
| 	} | ||||
| 	if (sym && sym1) { | ||||
| 		error("could not identify \"%s\"", arg->t_str); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if (!sym && !s) { | ||||
| 		error("could not find \"%s\"", arg->t_str); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	break; | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ struct tokenname tkspec[] =	{	/* the names of the special tokens */ | |||
| 	{NAME, "name"}, | ||||
| 	{STRING, "string"}, | ||||
| 	{INTEGER, "number"}, | ||||
| 	{EXPRESSION, "<expression>"}, | ||||
| 	{REAL, "real"}, | ||||
| 	{CHAR, "char"}, | ||||
| 	{BIN_OP, "<operator>"}, | ||||
|  | @ -65,6 +66,9 @@ struct tokenname tkidf[] =	{	/* names of the identifier tokens */ | |||
| 	{FIND, "find"}, | ||||
| 	{DISPLAY, "display"}, | ||||
| 	{WHICH, "which"}, | ||||
| 	{HELP, "help"}, | ||||
| 	{DISABLE,"disable"}, | ||||
| 	{ENABLE,"enable"}, | ||||
| 	{-1, "quit"}, | ||||
| 	{0, ""} | ||||
| }; | ||||
|  |  | |||
|  | @ -19,12 +19,15 @@ | |||
| #include	"expr.h" | ||||
| 
 | ||||
| extern FILE	*db_out; | ||||
| extern t_lineno	currline, listline; | ||||
| extern t_lineno	currline; | ||||
| static t_lineno	listline; | ||||
| extern long	pointer_size; | ||||
| extern char	*strrindex(); | ||||
| extern int	interrupted; | ||||
| 
 | ||||
| p_tree		run_command; | ||||
| p_tree		print_command; | ||||
| 
 | ||||
| static int	wsize = 10; | ||||
| 
 | ||||
| /*VARARGS1*/ | ||||
| p_tree | ||||
|  | @ -41,6 +44,7 @@ mknode(va_alist) | |||
| 	p->t_oper = va_arg(ap, int); | ||||
| 	switch(p->t_oper) { | ||||
| 	case OP_NAME: | ||||
| 	case OP_HELP: | ||||
| 		p->t_idf = va_arg(ap, struct idf *); | ||||
| 		p->t_str = va_arg(ap, char *); | ||||
| 		break; | ||||
|  | @ -58,7 +62,6 @@ mknode(va_alist) | |||
| 	case OP_NEXT: | ||||
| 	case OP_STEP: | ||||
| 	case OP_REGS: | ||||
| 	case OP_DELETE: | ||||
| 	case OP_RESTORE: | ||||
| 	case OP_WHERE: | ||||
| 		p->t_ival = va_arg(ap, long); | ||||
|  | @ -76,21 +79,6 @@ mknode(va_alist) | |||
|   return p; | ||||
| } | ||||
| 
 | ||||
| adjust_oper(pp) | ||||
|   p_tree	*pp; | ||||
| { | ||||
|   register p_tree	p = *pp, p1; | ||||
| 
 | ||||
|   switch(p->t_whichoper) { | ||||
|   case E_DERSELECT: | ||||
| 	p1 = mknode(OP_UNOP, p->t_args[0]); | ||||
| 	p1->t_whichoper = E_DEREF; | ||||
| 	p->t_args[0] = p1; | ||||
| 	p->t_whichoper = E_SELECT; | ||||
| 	break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| freenode(p) | ||||
|   register p_tree	p; | ||||
| { | ||||
|  | @ -164,8 +152,16 @@ print_node(p, top_level) | |||
| 	if (p->t_args[0]) { | ||||
| 		print_node(p->t_args[0], 0); | ||||
| 		if (p->t_args[1]) { | ||||
| 			fputs(", ", db_out); | ||||
| 			print_node(p->t_args[1], 0); | ||||
| 			if (p->t_args[1]->t_ival >= 0) { | ||||
| 				fputs(", ", db_out); | ||||
| 				print_node(p->t_args[1], 0); | ||||
| 			} | ||||
| 			else  { | ||||
| 				if (p->t_args[1]->t_ival < -100000000) { | ||||
| 					fputs("-", db_out); | ||||
| 				} | ||||
| 				else print_node(p->t_args[1], 0); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	break; | ||||
|  | @ -173,10 +169,23 @@ print_node(p, top_level) | |||
| 	fputs("print ", db_out); | ||||
| 	print_node(p->t_args[0], 0); | ||||
| 	break; | ||||
|   case OP_ENABLE: | ||||
| 	fputs("enable ", db_out); | ||||
| 	print_node(p->t_args[0], 0); | ||||
| 	break; | ||||
|   case OP_DISABLE: | ||||
| 	fputs("disable ", db_out); | ||||
| 	print_node(p->t_args[0], 0); | ||||
| 	break; | ||||
|   case OP_DISPLAY: | ||||
| 	fputs("display ", db_out); | ||||
| 	print_node(p->t_args[0], 0); | ||||
| 	break; | ||||
|   case OP_LINK: | ||||
| 	print_node(p->t_args[0], 0); | ||||
| 	fputs(", ", db_out); | ||||
| 	print_node(p->t_args[1], 0); | ||||
| 	break; | ||||
|   case OP_FILE: | ||||
| 	fputs("file ", db_out); | ||||
| 	print_node(p->t_args[0], 0); | ||||
|  | @ -196,7 +205,8 @@ print_node(p, top_level) | |||
| 	print_node(p->t_args[0], 0); | ||||
| 	break; | ||||
|   case OP_DELETE: | ||||
| 	fprintf(db_out, "delete %ld", p->t_ival); | ||||
| 	fputs("delete ", db_out); | ||||
| 	print_node(p->t_args[0], 0); | ||||
| 	break; | ||||
|   case OP_REGS: | ||||
| 	fprintf(db_out, "regs %ld", p->t_ival); | ||||
|  | @ -221,6 +231,10 @@ print_node(p, top_level) | |||
| 	fputs("where", db_out); | ||||
| 	if (p->t_ival != 0x7fffffff) fprintf(db_out, " %ld", p->t_ival); | ||||
| 	break; | ||||
|   case OP_HELP: | ||||
| 	fputs("help", db_out); | ||||
| 	if (p->t_str != 0) fprintf(db_out, " %s", p->t_str); | ||||
| 	break; | ||||
|   case OP_CONT: | ||||
| 	fputs("cont", db_out); | ||||
| 	if (p->t_args[0]) { | ||||
|  | @ -303,6 +317,11 @@ print_node(p, top_level) | |||
|   case OP_REAL: | ||||
| 	fprintf(db_out, currlang->real_fmt, p->t_fval); | ||||
| 	break; | ||||
|   case OP_FORMAT: | ||||
| 	print_node(p->t_args[0], 0); | ||||
| 	fputs("\\", db_out); | ||||
| 	print_node(p->t_args[1], 0); | ||||
| 	break; | ||||
|   case OP_UNOP: | ||||
|   case OP_BINOP: | ||||
| 	(*currlang->printop)(p); | ||||
|  | @ -317,11 +336,19 @@ repeatable(com) | |||
| { | ||||
|   switch(com->t_oper) { | ||||
|   case OP_CONT: | ||||
| 	com->t_args[0]->t_ival = 1; | ||||
| 	freenode(com->t_args[1]); | ||||
| 	com->t_args[1] = 0; | ||||
| 	return 1; | ||||
|   case OP_NEXT: | ||||
|   case OP_STEP: | ||||
| 	com->t_ival = 1; | ||||
| 	return 1; | ||||
|   case OP_LIST: | ||||
|   case OP_STATUS: | ||||
|   case OP_PRINT: | ||||
| 	freenode(com->t_args[0]); | ||||
| 	com->t_args[0] = 0; | ||||
| 	freenode(com->t_args[1]); | ||||
| 	com->t_args[1] = 0; | ||||
| 	return 1; | ||||
|   } | ||||
|   return 0; | ||||
|  | @ -345,7 +372,7 @@ in_status(com) | |||
| eval(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   if (p) (*operators[p->t_oper].op_fun)(p); | ||||
|   if (p && operators[p->t_oper].op_fun) (*operators[p->t_oper].op_fun)(p); | ||||
| } | ||||
| 
 | ||||
| do_list(p) | ||||
|  | @ -353,15 +380,25 @@ do_list(p) | |||
| { | ||||
|   int	l1, l2; | ||||
| 
 | ||||
|   if (p->t_args[1]) { | ||||
| 	l2 = p->t_args[1]->t_ival; | ||||
| 	if (l2 >= 0) { | ||||
| 		if (l2 == 0) l2 = 1; | ||||
| 		wsize = l2; | ||||
| 	} | ||||
|   } | ||||
|   else l2 = wsize; | ||||
| 
 | ||||
|   if (! p->t_args[0]) { | ||||
| 	l1 = listline; | ||||
| 	l2 = listline + 9; | ||||
| 	if (! l1) { | ||||
| 		listline = currline - (wsize/2); | ||||
| 		l1 = listline; | ||||
| 	} | ||||
|   } | ||||
|   else { | ||||
| 	if (p->t_args[0]->t_oper == OP_INTEGER) { | ||||
| 		l1 = p->t_args[0]->t_ival; | ||||
| 		assert(p->t_args[1] != 0); | ||||
| 		l2 = p->t_args[1]->t_ival; | ||||
| 	} | ||||
| 	else { | ||||
|   		t_addr	a = get_addr_from_node(p->t_args[0]); | ||||
|  | @ -372,16 +409,20 @@ do_list(p) | |||
| 		} | ||||
| 		pos = get_position_from_addr(a); | ||||
|   		newfile(str2idf(pos->filename, 1)); | ||||
| 		l1 = pos->lineno - 5; | ||||
| 		l1 = pos->lineno - (l2 > 0 ? l2 : wsize)/2; | ||||
| 		if (l1 < 1) l1 = 1; | ||||
| 		l2 = l1+9; | ||||
| 	} | ||||
|   } | ||||
|   if (listfile) { | ||||
| 	if (l2 < 0) { | ||||
| 		l2 = -l2; | ||||
| 		if (l1 > l2) l2 = 1; | ||||
| 		else l2 -= l1 - 1; | ||||
| 	} | ||||
| 	lines(listfile->sy_file, l1, l2); | ||||
| 	listline = l2+1; | ||||
| 	listline = l1 + l2; | ||||
|   } | ||||
|   else fprintf(db_out, "no current file\n"); | ||||
|   else error("no current file"); | ||||
| } | ||||
| 
 | ||||
| do_file(p) | ||||
|  | @ -391,7 +432,7 @@ do_file(p) | |||
| 	newfile(p->t_args[0]->t_idf); | ||||
|   } | ||||
|   else if (listfile) fprintf(db_out, "%s\n", listfile->sy_idf->id_text); | ||||
|   else fprintf(db_out, "no current file\n"); | ||||
|   else error("no current file"); | ||||
| } | ||||
| 
 | ||||
| newfile(id) | ||||
|  | @ -409,55 +450,102 @@ newfile(id) | |||
|   find_language(strrindex(id->id_text, '.')); | ||||
| } | ||||
| 
 | ||||
| do_stop(p) | ||||
| setstop(p, kind) | ||||
|   p_tree	p; | ||||
|   int		kind; | ||||
| { | ||||
|   t_addr	a = get_addr_from_node(p->t_args[0]); | ||||
| 
 | ||||
|   if (a == ILL_ADDR) { | ||||
| 	return; | ||||
|   } | ||||
|   if (a == ILL_ADDR) return 0; | ||||
| 
 | ||||
|   p->t_address = a; | ||||
|   add_to_item_list(p); | ||||
|   if (a != NO_ADDR) { | ||||
| 	if (! set_or_clear_breakpoint(a, SETBP)) { | ||||
| 		error("could not set breakpoint"); | ||||
| 	if (! set_or_clear_breakpoint(a, kind)) { | ||||
| 		error("could not %s breakpoint", kind == SETBP ? "set" : "clear"); | ||||
| 		return 0; | ||||
| 	} | ||||
|   } | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| do_stop(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   if (! setstop(p, SETBP)) { | ||||
| 	return; | ||||
|   } | ||||
|   add_to_item_list(p); | ||||
| } | ||||
| 
 | ||||
| settrace(p, kind) | ||||
|   p_tree	p; | ||||
|   int		kind; | ||||
| { | ||||
|   t_addr	a, e; | ||||
| 
 | ||||
|   a = get_addr_from_node(p->t_args[0]); | ||||
|   if (a == NO_ADDR) return 1; | ||||
|   if (a == ILL_ADDR) return 0; | ||||
|   if (p->t_args[0]->t_oper == OP_AT) { | ||||
| 	e = a; | ||||
| 	p->t_address = a; | ||||
|   } | ||||
|   else { | ||||
| 	p_scope sc = get_next_scope_from_addr(a+1); | ||||
| 
 | ||||
| 	if (sc) e = sc->sc_start - 1; | ||||
| 	else e = 0xffffffff; | ||||
|   } | ||||
|   if (! set_or_clear_trace(a, e, kind)) { | ||||
| 	error("could not %s trace", kind == SETTRACE ? "set" : "clear"); | ||||
| 	return 0; | ||||
|   } | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| do_trace(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   t_addr a; | ||||
|   t_addr e; | ||||
| 
 | ||||
|   p->t_address = NO_ADDR; | ||||
|   if (p->t_args[0]) { | ||||
| 	a = get_addr_from_node(p->t_args[0]); | ||||
| 	if (a == ILL_ADDR) return; | ||||
| 	if (p->t_args[0]->t_oper == OP_AT) { | ||||
| 		e = a; | ||||
| 		p->t_address = a; | ||||
| 	} | ||||
| 	else { | ||||
| 		p_scope sc = get_next_scope_from_addr(a+1); | ||||
| 
 | ||||
| 		if (sc) e = sc->sc_start - 1; | ||||
| 		else e = 0xffffffff; | ||||
| 	} | ||||
| 	if (! set_or_clear_trace(a, e, SETTRACE)) { | ||||
| 		error("could not set trace"); | ||||
| 	} | ||||
|   if (! settrace(p, SETTRACE)) { | ||||
| 	return; | ||||
|   } | ||||
|   add_to_item_list(p); | ||||
| } | ||||
| 
 | ||||
| static | ||||
| able(p, kind) | ||||
|   p_tree	p; | ||||
|   int		kind; | ||||
| { | ||||
|   switch(p->t_oper) { | ||||
|   case OP_LINK: | ||||
| 	able(p->t_args[0], kind); | ||||
| 	able(p->t_args[1], kind); | ||||
| 	break; | ||||
|   case OP_INTEGER: | ||||
| 	able_item((int)p->t_ival, kind); | ||||
| 	break; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| do_enable(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   able(p->t_args[0], 0); | ||||
| } | ||||
| 
 | ||||
| do_disable(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   able(p->t_args[0], 1); | ||||
| } | ||||
| 
 | ||||
| do_continue(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   int count; | ||||
|   int first_time = 1; | ||||
| 
 | ||||
|   if (p) { | ||||
| 	count = p->t_args[0]->t_ival; | ||||
|  | @ -476,9 +564,10 @@ do_continue(p) | |||
|   else count = 1; | ||||
|   while (count--) { | ||||
| 	if (! send_cont(count==0)) { | ||||
| 		error("no debuggee"); | ||||
| 		if (first_time) error("no process"); | ||||
| 		break; | ||||
| 	} | ||||
| 	first_time = 0; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -486,7 +575,7 @@ do_step(p) | |||
|   p_tree	p; | ||||
| { | ||||
|   if (! do_single_step(SETSS, p->t_ival)) { | ||||
| 	error("no debuggee"); | ||||
| 	if (! interrupted) error("no process"); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -495,7 +584,7 @@ do_next(p) | |||
| { | ||||
| 
 | ||||
|   if (! do_single_step(SETSSF, p->t_ival)) { | ||||
| 	error("no debuggee"); | ||||
| 	if (! interrupted) error("no process"); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -508,7 +597,7 @@ do_regs(p) | |||
|   int		n = p->t_ival; | ||||
| 
 | ||||
|   if (! (buf = get_EM_regs(n))) { | ||||
| 	error("no debuggee"); | ||||
| 	if (! interrupted) error("no process"); | ||||
| 	return; | ||||
|   } | ||||
|   fprintf(db_out, "EM registers %d levels back:\n", n); | ||||
|  | @ -526,17 +615,30 @@ do_where(p) | |||
| { | ||||
|   int i = 0; | ||||
|   unsigned int cnt; | ||||
|   unsigned int maxcnt = p->t_ival; | ||||
|   p_scope sc; | ||||
|   t_addr *buf; | ||||
|   t_addr PC; | ||||
| 
 | ||||
|   for (cnt = p->t_ival; cnt != 0; cnt--) { | ||||
| 	t_addr AB; | ||||
| 	t_addr PC; | ||||
| 	p_scope sc; | ||||
| 	t_addr *buf; | ||||
| 
 | ||||
| 	if (! (buf = get_EM_regs(i++))) { | ||||
| 		error("no debuggee"); | ||||
| 		return; | ||||
|   if (p->t_ival < 0) { | ||||
| 	for (;;) { | ||||
| 		buf = get_EM_regs(i++); | ||||
| 		if (! buf || ! buf[AB_OFF]) break; | ||||
| 		PC = buf[PC_OFF]; | ||||
| 		sc = base_scope(get_scope_from_addr(PC)); | ||||
| 		if (! sc || sc->sc_start > PC) break; | ||||
| 		if (interrupted) return; | ||||
| 	} | ||||
| 	i--; | ||||
| 	maxcnt = - p->t_ival; | ||||
| 	i -= maxcnt; | ||||
| 	if (i < 0) i = 0; | ||||
|   } | ||||
|   for (cnt = maxcnt; cnt != 0; cnt--) { | ||||
| 	t_addr AB; | ||||
| 
 | ||||
| 	if (interrupted) return; | ||||
| 	if (! (buf = get_EM_regs(i++))) break; | ||||
| 	AB = buf[AB_OFF]; | ||||
| 	PC = buf[PC_OFF]; | ||||
| 	if (! AB) break; | ||||
|  | @ -550,63 +652,60 @@ do_where(p) | |||
|   } | ||||
| } | ||||
| 
 | ||||
| /*ARGSUSED*/ | ||||
| do_status(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   print_items(); | ||||
| } | ||||
| 
 | ||||
| extern p_tree	remove_from_item_list(); | ||||
| 
 | ||||
| do_delete(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   p = remove_from_item_list((int) p->t_ival); | ||||
| 
 | ||||
|   if (p) switch(p->t_oper) { | ||||
|   case OP_WHEN: | ||||
|   case OP_STOP: { | ||||
| 	t_addr a = get_addr_from_node(p->t_args[0]); | ||||
| 
 | ||||
| 	if (a != ILL_ADDR && a != NO_ADDR) { | ||||
| 		set_or_clear_breakpoint(a, CLRBP); | ||||
| 	} | ||||
|   switch(p->t_oper) { | ||||
|   case OP_DELETE: | ||||
| 	do_delete(p->t_args[0]); | ||||
| 	break; | ||||
| 	} | ||||
|   case OP_TRACE: { | ||||
| 	t_addr a = get_addr_from_node(p->t_args[0]); | ||||
| 	 | ||||
| 	if (a != ILL_ADDR && a != NO_ADDR) { | ||||
| 		t_addr e; | ||||
| 		if (p->t_args[0]->t_oper == OP_AT) { | ||||
| 			e = a; | ||||
| 		} | ||||
| 		else { | ||||
| 			p_scope sc = get_next_scope_from_addr(a+1); | ||||
| 
 | ||||
| 			if (sc) e = sc->sc_start - 1; | ||||
| 			else e = 0xffffffff; | ||||
| 		} | ||||
| 		set_or_clear_trace(a, e, CLRTRACE); | ||||
| 	} | ||||
|   case OP_LINK: | ||||
| 	do_delete(p->t_args[0]); | ||||
| 	do_delete(p->t_args[1]); | ||||
| 	break; | ||||
|   case OP_INTEGER: | ||||
|   	p = remove_from_item_list((int) p->t_ival); | ||||
| 
 | ||||
|   	if (p) switch(p->t_oper) { | ||||
|   	case OP_WHEN: | ||||
|   	case OP_STOP: | ||||
| 		setstop(p, CLRBP); | ||||
| 		break; | ||||
|   	case OP_TRACE: | ||||
| 		settrace(p, CLRTRACE); | ||||
| 		break; | ||||
|   	case OP_DUMP: | ||||
| 		free_dump(p); | ||||
|   	} | ||||
|   	freenode(p); | ||||
| 	break; | ||||
| 	} | ||||
|   case OP_DUMP: | ||||
| 	free_dump(p); | ||||
|   } | ||||
|   freenode(p); | ||||
| } | ||||
| 
 | ||||
| do_print(p) | ||||
|   p_tree	p; | ||||
| { | ||||
|   char	*buf; | ||||
|   char	*buf = 0; | ||||
|   char *format = 0; | ||||
|   long	size; | ||||
|   p_type tp; | ||||
| 
 | ||||
|   switch(p->t_oper) { | ||||
|   case OP_PRINT: | ||||
| 	if (p->t_args[0] == 0) { | ||||
| 		p = print_command; | ||||
| 		if (p == 0) { | ||||
| 			error("no previous print command"); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	else if (p != print_command) { | ||||
| 		freenode(print_command); | ||||
| 		print_command = p; | ||||
| 	} | ||||
| 	/* fall through */ | ||||
|   case OP_DISPLAY: | ||||
| 	do_print(p->t_args[0]); | ||||
| 	break; | ||||
|  | @ -615,10 +714,13 @@ do_print(p) | |||
| 	do_print(p->t_args[1]); | ||||
| 	break; | ||||
|   default: | ||||
| 	if (! eval_expr(p, &buf, &size, &tp)) return; | ||||
| 	if (interrupted || ! eval_expr(p, &buf, &size, &tp)) return; | ||||
| 	print_node(p, 0); | ||||
| 	fputs(" = ", db_out); | ||||
| 	print_val(tp, size, buf, 0, 0); | ||||
| 	if (p->t_oper == OP_FORMAT) { | ||||
| 		format = p->t_args[1]->t_str; | ||||
| 	} | ||||
| 	print_val(tp, size, buf, 0, 0, format); | ||||
| 	if (buf) free(buf); | ||||
| 	fputs("\n", db_out); | ||||
| 	break; | ||||
|  | @ -633,13 +735,17 @@ do_set(p) | |||
|   p_type tp, tp2; | ||||
|   t_addr a; | ||||
| 
 | ||||
|   if (! eval_desig(p->t_args[0], &a, &size, &tp) || | ||||
|   if (interrupted || ! eval_desig(p->t_args[0], &a, &size, &tp) || | ||||
|       ! eval_expr(p->t_args[1], &buf, &size2, &tp2) || | ||||
|       ! convert(&buf, &size2, &tp2, tp, size)) { | ||||
| 	if (buf) free(buf); | ||||
| 	return; | ||||
|   } | ||||
| 
 | ||||
|   if (interrupted) { | ||||
| 	free(buf); | ||||
| 	return; | ||||
|   } | ||||
|   if (! set_bytes(size, buf, a)) { | ||||
| 	error("could not handle this SET request"); | ||||
|   } | ||||
|  | @ -652,11 +758,14 @@ perform(p, a) | |||
| { | ||||
|   switch(p->t_oper) { | ||||
|   case OP_WHEN: | ||||
| 	if (p->t_args[1] && ! eval_cond(p->t_args[1])) break; | ||||
| 	p = p->t_args[2]; | ||||
| 	while (p->t_oper == OP_LINK) { | ||||
| 		if (interrupted) return; | ||||
| 		eval(p->t_args[0]); | ||||
| 		p = p->t_args[1]; | ||||
| 	} | ||||
| 	if (interrupted) return; | ||||
| 	eval(p); | ||||
| 	break; | ||||
|   case OP_TRACE: | ||||
|  | @ -667,6 +776,8 @@ perform(p, a) | |||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (interrupted) return; | ||||
| 	if (p->t_args[1] && ! eval_cond(p->t_args[1])) break; | ||||
| 	list_position(get_position_from_addr(a)); | ||||
| 	if (p->t_args[2]) do_print(p->t_args[2]); | ||||
| 	break; | ||||
|  | @ -681,6 +792,6 @@ list_position(pos) | |||
|   newfile(str2idf(pos->filename, 1)); | ||||
|   currfile = listfile; | ||||
|   currline = pos->lineno; | ||||
|   listline = currline-5; | ||||
|   lines(currfile->sy_file, (int)currline, (int)currline); | ||||
|   lines(currfile->sy_file, (int)currline, (int)1); | ||||
|   listline = 0; | ||||
| } | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ typedef struct tree { | |||
|   short	t_oper;		/* tree operator */ | ||||
|   short t_whichoper;	/* expression operator */ | ||||
|   t_addr t_address;	/* some operators use an address */ | ||||
|   int	t_itemno;	/* item number in status list */ | ||||
|   union { | ||||
| 	long tt_ival; | ||||
| 	char *tt_sval; | ||||
|  | @ -34,4 +33,3 @@ typedef struct tree { | |||
| /* ALLOCDEF "tree" 100 */ | ||||
| 
 | ||||
| extern p_tree	mknode(); | ||||
| extern p_tree	run_command; | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ p_type	int_type, char_type, short_type, long_type, bool_type; | |||
| p_type	uint_type, uchar_type, ushort_type, ulong_type; | ||||
| p_type	void_type, incomplete_type; | ||||
| p_type	float_type, double_type; | ||||
| p_type	string_type; | ||||
| p_type	string_type, address_type; | ||||
| 
 | ||||
| long	int_size = SZ_INT, | ||||
| 	char_size = 1, | ||||
|  | @ -255,6 +255,7 @@ init_types() | |||
|   ushort_type = basic_type(T_UNSIGNED, short_size); | ||||
|   uchar_type = basic_type(T_UNSIGNED, char_size); | ||||
|   string_type = basic_type(T_STRING, 0L); | ||||
|   address_type = basic_type(T_POINTER, pointer_size); | ||||
|   void_type = basic_type(T_VOID, 0L); | ||||
|   incomplete_type = basic_type(T_INCOMPLETE, 0L); | ||||
|   float_type = basic_type(T_REAL, float_size); | ||||
|  |  | |||
|  | @ -38,9 +38,8 @@ typedef struct type { | |||
| #define T_VOID		12 | ||||
| #define T_UNSIGNED	13 | ||||
| #define T_STRING	14	/* only for string constants ... */ | ||||
| #define T_CROSS		15	/* cross reference to type */ | ||||
| #define T_INCOMPLETE   100 | ||||
|   short		ty_flags; | ||||
| #define T_CROSS		0x0001 | ||||
|   long		ty_size; | ||||
|   struct symbol	*ty_sym; | ||||
|   union { | ||||
|  | @ -117,7 +116,7 @@ extern long | |||
| 	compute_size(); | ||||
| 
 | ||||
| extern p_type	char_type, uchar_type, bool_type, int_type, | ||||
| 		long_type, double_type, string_type; | ||||
| 		long_type, double_type, string_type, address_type; | ||||
| extern p_type	void_type, incomplete_type; | ||||
| extern long	int_size, pointer_size, long_size, double_size; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue