From 15cd4d35ac610a0f789c74484db86ed87c430084 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Fri, 8 Jun 2018 18:09:10 -0700 Subject: [PATCH] SCP: Enhance command procedure processing and add debugging support - push new action commands ahead of any previously unprocessed pending action commands. - Add ACTION and DO debug to CPU (SCP) command processing support - Insert %n command arguments before storing command line for potential deferred processing of action parameters to some commands (IF, BREAK, EXPECT, etc.) --- scp.c | 170 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 122 insertions(+), 48 deletions(-) diff --git a/scp.c b/scp.c index 61f8646d..e17ed424 100644 --- a/scp.c +++ b/scp.c @@ -519,7 +519,6 @@ t_stat do_cmd_label (int32 flag, CONST char *cptr, CONST char *label); void int_handler (int signal); t_stat set_prompt (int32 flag, CONST char *cptr); t_stat sim_set_asynch (int32 flag, CONST char *cptr); -t_stat sim_set_environment (int32 flag, CONST char *cptr); static const char *get_dbg_verb (uint32 dbits, DEVICE* dptr, UNIT *uptr); /* Global data */ @@ -2507,8 +2506,10 @@ while (stat != SCPE_EXIT) { /* in case exit */ if (sim_on_actions[sim_do_depth][ON_SIGINT_ACTION]) sim_brk_setact (sim_on_actions[sim_do_depth][ON_SIGINT_ACTION]); } - if ((cptr = sim_brk_getact (cbuf, sizeof(cbuf)))) /* pending action? */ - printf ("%s%s\n", sim_prompt, cptr); /* echo */ + if ((cptr = sim_brk_getact (cbuf, sizeof(cbuf)))) { /* pending action? */ + if (sim_do_echo) + printf ("%s+ %s\n", sim_prompt, cptr); /* echo */ + } else { if (sim_vm_read != NULL) { /* sim routine? */ printf ("%s", sim_prompt); /* prompt */ @@ -3347,6 +3348,7 @@ if (flag >= 0) { /* Only bump nesting fro } } +sim_debug (SIM_DBG_DO, sim_dflt_dev, "do_cmd_label(%d, flag=%d, '%s', '%s')\n", sim_do_depth, flag, fcptr, label ? label : ""); strlcpy( sim_do_filename[sim_do_depth], do_arg[0], sizeof (sim_do_filename[sim_do_depth])); /* stash away do file name for possible use by 'call' command */ sim_do_label[sim_do_depth] = label; /* stash away do label for possible use in messages */ @@ -3483,9 +3485,11 @@ if ((flag >= 0) || (!sim_on_inherit)) { } sim_on_check[sim_do_depth] = 0; /* clear on mode */ } -if (flag >= 0) +sim_debug (SIM_DBG_DO, sim_dflt_dev, "do_cmd_label - exiting - stat:%d (%d, flag=%d, '%s', '%s')\n", stat, sim_do_depth, flag, fcptr, label ? label : ""); +if (flag >= 0) { + sim_brk_clract (); /* defang breakpoint actions */ --sim_do_depth; /* unwind nesting */ -sim_brk_clract (); /* defang breakpoint actions */ + } if (cmdp && (cmdp->action == &return_cmd) && (0 != *cptr)) { /* return command with argument? */ sim_string_to_stat (cptr, &stat); sim_last_cmd_stat = stat; /* save explicit status as command error status */ @@ -3730,18 +3734,95 @@ if (!ap) { /* no environment variable found? */ return ap; } +/* Substitute_args - replace %n tokens in 'instr' with the do command's arguments + + Calling sequence + instr = input string + tmpbuf = temp buffer + maxstr = min (len (instr), len (tmpbuf)) + do_arg[10] = arguments + + Token "%0" represents the command file name. + + The input sequence "\%" represents a literal "%", and "\\" represents a + literal "\". All other character combinations are rendered literally. + + Omitted parameters result in null-string substitutions. +*/ + +static void +_sub_args (char *instr, char *tmpbuf, size_t str_size, char *do_arg[]) +{ +char *ip, *op, *ap, *oend = tmpbuf + str_size - 2; +int i; +char rbuf[CBUFSIZE]; + +for (ip = instr, op = tmpbuf; *ip && (op < oend); ) { + if ((ip [0] == '\\') && /* literal escape? */ + ((ip [1] == '%') || (ip [1] == '\\'))) { /* and followed by '%' or '\'? */ + *op++ = *ip++; /* copy \ */ + *op++ = *ip++; /* copy escaped char */ + } + else { + if ((*ip == '%') && /* %n = sub */ + ((sim_isdigit(ip[1]) && !sim_isdigit(ip[2])) || + (ip[1] == '*'))) { + if ((ip[1] >= '0') && (ip[1] <= '9')) { + ap = do_arg[ip[1] - '0']; + for (i=0; i sim_sub_instr_size) { @@ -3782,46 +3863,14 @@ for (; *ip && (op < oend); ) { ip++; /* skip one */ *op++ = *ip++; /* copy insert % */ } - else + else { if ((*ip == '%') && - (sim_isalnum(ip[1]) || (ip[1] == '*') || (ip[1] == '_'))) {/* sub? */ - if ((ip[1] >= '0') && (ip[1] <= ('9'))) { /* %n = sub */ - ap = do_arg[ip[1] - '0']; - for (i=0; i