diff --git a/scp.c b/scp.c index 73817d4..6a6dbc2 100644 --- a/scp.c +++ b/scp.c @@ -959,6 +959,14 @@ static const char simh_help[] = "+++++++++D MQ 0\n" "++BREAK 100; delete action on break at 100\n\n" /***************** 80 character line width template *************************/ +#define HLP_DEBUG "*Commands Stopping_The_Simulator User_Specified_Stop_Conditions DEBUG" +#define HLP_NODEBUG "*Commands Stopping_The_Simulator User_Specified_Stop_Conditions DEBUG" + "4Debug\n" + " The DEBUG snd NODEBUG commands are aliases for the \"SET DEBUG\" and\n" + " \"SET NODEBUG\" commands. Additionally, support is provided that is\n" + " equivalent to the \"SET DEBUG=opt1{;opt2}\" and\n" + " \"SET NODEBUG=opt1{;opt2}\" commands.\n\n" + /***************** 80 character line width template *************************/ "2Connecting and Disconnecting Devices\n" " Except for main memory and network devices, units are simulated as\n" " unstructured binary disk files in the host file system. Before using a\n" @@ -1611,15 +1619,57 @@ ASSERT failure have several different actions: #endif -#define HLP_ECHO "*Commands Executing_Command_Files Displaying_Arbitrary_Text" +#define HLP_ECHO "*Commands Executing_Command_Files Displaying_Arbitrary_Text ECHO_Command" /***************** 80 character line width template *************************/ "3Displaying Arbitrary Text\n" - " The ECHO command is a useful way of annotating command files. ECHO prints\n" - " out its arguments on the console (and log):\n\n" + " The ECHO and ECHOF commands are useful ways of annotating command files.\n\n" + "4ECHO command\n" + " The ECHO command prints out its arguments on the console (and log)\n" + " followed by a newline:\n\n" "++ECHO output string to console\n\n" " If there is no argument, ECHO prints a blank line on the console. This\n" " may be used to provide spacing in the console display or log.\n" /***************** 80 character line width template *************************/ +#define HLP_ECHOF "*Commands Executing_Command_Files Displaying_Arbitrary_Text ECHOF_Command" + /***************** 80 character line width template *************************/ + "4ECHOF command\n" + " The ECHOF command prints out its arguments on the console (and log)\n" + " followed by a newline:\n\n" + /***************** 80 character line width template *************************/ + "++ECHOF {-n} \"\"| output string to console\n\n" + " If there is no argument, ECHOF prints a blank line on the console.\n" + " The string argument may be delimited by quote characters. Quotes may\n" + " be either single or double but the opening and closing quote characters\n" + " must match. If the string is enclosed in quotes, the string may\n" + " contain escaped character strings which is interpreted as described\n" + " in Quoted_String_Data and the resulting string is output.\n\n" + " A command alias can be used to replace the ECHO command with the ECHOF\n" + " command:\n\n" + "++sim> SET ENV ECHO=ECHOF\n" + "5Switches\n" + " Switches can be used to influence the behavior of ECHOF commands\n\n" + "6-n\n" + " The -n switch indicates that the supplied string should be output\n" + " without a newline after the string is written.\n" + "5Quoted String Data\n" + " String data enclosed in quotes is transformed interpreting character\n" + " escapes. The following character escapes are explicitly supported:\n" + "++\\r Sends the ASCII Carriage Return character (Decimal value 13)\n" + "++\\n Sends the ASCII Linefeed character (Decimal value 10)\n" + "++\\f Sends the ASCII Formfeed character (Decimal value 12)\n" + "++\\t Sends the ASCII Horizontal Tab character (Decimal value 9)\n" + "++\\v Sends the ASCII Vertical Tab character (Decimal value 11)\n" + "++\\b Sends the ASCII Backspace character (Decimal value 8)\n" + "++\\\\ Sends the ASCII Backslash character (Decimal value 92)\n" + "++\\' Sends the ASCII Single Quote character (Decimal value 39)\n" + "++\\\" Sends the ASCII Double Quote character (Decimal value 34)\n" + "++\\? Sends the ASCII Question Mark character (Decimal value 63)\n" + "++\\e Sends the ASCII Escape character (Decimal value 27)\n" + " as well as octal character values of the form:\n" + "++\\n{n{n}} where each n is an octal digit (0-7)\n" + " and hext character values of the form:\n" + "++\\xh{h} where each h is a hex digit (0-9A-Fa-f)\n" + /***************** 80 character line width template *************************/ #define HLP_SEND "*Commands Executing_Command_Files Injecting_Console_Input" /***************** 80 character line width template *************************/ "3Injecting Console Input\n" @@ -1956,6 +2006,8 @@ static CTAB cmd_table[] = { { "BOOT", &run_cmd, RU_BOOT, HLP_BOOT, NULL, &run_cmd_message }, { "BREAK", &brk_cmd, SSH_ST, HLP_BREAK }, { "NOBREAK", &brk_cmd, SSH_CL, HLP_NOBREAK }, + { "DEBUG", &debug_cmd, 1, HLP_DEBUG}, + { "NODEBUG", &debug_cmd, 0, HLP_NODEBUG }, { "ATTACH", &attach_cmd, 0, HLP_ATTACH }, { "DETACH", &detach_cmd, 0, HLP_DETACH }, { "ASSIGN", &assign_cmd, 0, HLP_ASSIGN }, @@ -1990,6 +2042,7 @@ static CTAB cmd_table[] = { { "PROCEED", &noop_cmd, 0, HLP_PROCEED }, { "IGNORE", &noop_cmd, 0, HLP_IGNORE }, { "ECHO", &echo_cmd, 0, HLP_ECHO }, + { "ECHOF", &echof_cmd, 0, HLP_ECHOF }, { "ASSERT", &assert_cmd, 1, HLP_ASSERT }, { "SEND", &send_cmd, 1, HLP_SEND }, { "NOSEND", &send_cmd, 0, HLP_SEND }, @@ -2970,6 +3023,30 @@ sim_printf ("%s\n", cptr); return SCPE_OK; } +/* EchoF command */ + +t_stat echof_cmd (int32 flag, CONST char *cptr) +{ +char gbuf[CBUFSIZE]; +uint8 dbuf[CBUFSIZE]; +uint32 dsize = 0; + +GET_SWITCHES (cptr); +if (!*cptr) + return SCPE_2FARG; +if ((*cptr == '"') || (*cptr == '\'')) { + cptr = get_glyph_quoted (cptr, gbuf, 0); + if (*cptr != '\0') + return SCPE_2MARG; /* No more arguments */ + if (SCPE_OK != sim_decode_quoted_string (gbuf, dbuf, &dsize)) + return sim_messagef (SCPE_ARG, "Invalid String\n"); + dbuf[dsize] = 0; + cptr = (char *)dbuf; + } +sim_printf ("%s%s", cptr, (sim_switches & SWMASK('N')) ? "" : "\n"); +return SCPE_OK; +} + /* Do command Syntax: DO {-E} {-V} {...} @@ -3153,7 +3230,8 @@ do { ((cmdp->action != &return_cmd) && (cmdp->action != &goto_cmd) && (cmdp->action != &on_cmd) && - (cmdp->action != &echo_cmd))) + (cmdp->action != &echo_cmd) && + (cmdp->action != &echof_cmd))) sim_last_cmd_stat = stat; /* save command error status */ switch (stat) { case SCPE_AFAIL: @@ -3298,6 +3376,26 @@ while (sim_isspace (*ip)) { /* skip leading spac sim_sub_instr_off[outstr_off++] = ip - instr; *op++ = *ip++; } +/* If entire string is within quotes, strip the quotes */ +if ((*ip == '"') || (*ip == '\'')) { /* start with a quote character? */ + const char *cptr = ip; + char *tp = op; /* use remainder of output buffer as temp buffer */ + + cptr = get_glyph_quoted (cptr, tp, 0); /* get quoted string */ + while (sim_isspace (*cptr)) + ++cptr; /* skip over trailing spaces */ + if (*cptr == '\0') { /* full string was quoted? */ + uint32 dsize; + + if (SCPE_OK == sim_decode_quoted_string (tp, (uint8 *)tp, &dsize)) { + tp[dsize] = '\0'; + while (sim_isspace (*tp)) + memmove (tp, tp + 1, strlen (tp)); + strlcpy (ip, tp, instr_size - (ip - instr));/* copy quoted contents to input buffer */ + strlcpy (sim_sub_instr + (ip - instr), tp, instr_size - (ip - instr)); + } + } + } istart = ip; for (; *ip && (op < oend); ) { if ((ip [0] == '%') && (ip [1] == '%')) { /* literal % insert? */ @@ -5477,9 +5575,7 @@ if (dir) { #endif t_offset FileSize; char FileName[PATH_MAX + 1]; -#if defined (HAVE_FNMATCH) char *MatchName = 1 + strrchr (cptr, '/');; -#endif char *p_name; struct tm *local; #if defined (HAVE_GLOB) @@ -5494,6 +5590,9 @@ if (dir) { #if defined (HAVE_FNMATCH) if (fnmatch(MatchName, ent->d_name, 0)) continue; +#else + if (strcmp(MatchName, ent->d_name) != 0) + continue; #endif sprintf (FileName, "%s/%s", DirName, ent->d_name); #endif @@ -5742,6 +5841,25 @@ if ((stat == SCPE_OK) && (copy_state.count)) return copy_state.stat; } +/* Debug command */ + +t_stat debug_cmd (int32 flg, CONST char *cptr) +{ +char gbuf[CBUFSIZE]; +CONST char *svptr; +DEVICE *dptr; + +GET_SWITCHES (cptr); /* get switches */ +cptr = get_glyph (svptr = cptr, gbuf, 0); /* get next glyph */ +if ((dptr = find_dev (gbuf))) /* device match? */ +return set_dev_debug (dptr, NULL, flg, *cptr ? cptr : NULL); +cptr = svptr; +if (flg) + return sim_set_debon (0, cptr); +else + return sim_set_deboff (0, cptr); +} + /* Breakpoint commands */ t_stat brk_cmd (int32 flg, CONST char *cptr) @@ -7155,16 +7273,14 @@ if (sim_deb && (sim_deb != stdout) && (sim_deb != sim_log)) {/* debug if enabled t_stat sim_run_boot_prep (int32 flag) { -UNIT *uptr; t_stat r; sim_interval = 0; /* reset queue */ sim_time = sim_rtime = 0; -noqueue_time = 0; -for (uptr = sim_clock_queue; uptr != QUEUE_LIST_END; uptr = sim_clock_queue) { - sim_clock_queue = uptr->next; - uptr->next = NULL; - } +noqueue_time = 0; /* reset queue */ +while (sim_clock_queue != QUEUE_LIST_END) + sim_cancel (sim_clock_queue); +noqueue_time = sim_interval = 0; r = reset_all (0); if ((r == SCPE_OK) && (flag == RU_RUN)) { if ((run_cmd_did_reset) && (0 == (sim_switches & SWMASK ('Q')))) { @@ -9888,6 +10004,7 @@ if (nptr != QUEUE_LIST_END) nptr->time += (uptr->next) ? 0 : uptr->time; if (!uptr->next) uptr->time = 0; +uptr->usecs_remaining = 0; if (sim_clock_queue != QUEUE_LIST_END) sim_interval = sim_clock_queue->time; else sim_interval = noqueue_time = NOQUEUE_WAIT; @@ -10423,7 +10540,19 @@ while (sim_isspace (*sim_brk_act[sim_do_depth])) /* skip spaces */ if (*sim_brk_act[sim_do_depth] == 0) { /* now empty? */ return sim_brk_clract (); } -if ((ep = strchr (sim_brk_act[sim_do_depth], ';'))) { /* cmd delimiter? */ +ep = strpbrk (sim_brk_act[sim_do_depth], ";\"'"); /* search for a semicolon or single or double quote */ +if ((ep != NULL) && (*ep != ';')) { /* if a quoted string is present */ + char quote = *ep++; /* then save the opening quotation mark */ + + while (ep [0] != '\0' && ep [0] != quote) /* while characters remain within the quotes */ + if (ep [0] == '\\' && ep [1] == quote) /* if an escaped quote sequence follows */ + ep = ep + 2; /* then skip over the pair */ + else /* otherwise */ + ep = ep + 1; /* skip the non-quote character */ + ep = strchr (ep, ';'); /* the next semicolon is outside the quotes if it exists */ + } + +if (ep != NULL) { /* if a semicolon is present */ lnt = ep - sim_brk_act[sim_do_depth]; /* cmd length */ memcpy (buf, sim_brk_act[sim_do_depth], lnt + 1); /* copy with ; */ buf[lnt] = 0; /* erase ; */ @@ -10457,6 +10586,14 @@ else sim_brk_clract (); } +char *sim_brk_replace_act (char *new_action) +{ +char *old_action = sim_brk_act_buf[sim_do_depth]; + +sim_brk_act_buf[sim_do_depth] = new_action; +return old_action; +} + /* New PC */ void sim_brk_npc (uint32 cnt) @@ -10779,7 +10916,8 @@ if (switches & EXP_TYP_REGEX) { } else { sim_data_trace(exp->dptr, exp->dptr->units, (const uint8 *)match, "", strlen(match)+1, "Expect Match String", exp->dbit); - sim_decode_quoted_string (match, match_buf, &match_size); + /* quoted string was validated above, this decode operation will always succeed */ + (void)sim_decode_quoted_string (match, match_buf, &match_size); ep->match = match_buf; ep->size = match_size; } diff --git a/scp.h b/scp.h index 381f48a..12e7b03 100644 --- a/scp.h +++ b/scp.h @@ -108,6 +108,8 @@ t_stat help_cmd (int32 flag, CONST char *ptr); t_stat screenshot_cmd (int32 flag, CONST char *ptr); t_stat spawn_cmd (int32 flag, CONST char *ptr); t_stat echo_cmd (int32 flag, CONST char *ptr); +t_stat echof_cmd (int32 flag, CONST char *ptr); +t_stat debug_cmd (int32 flag, CONST char *ptr); /* Allow compiler to help validate printf style format arguments */ #if !defined __GNUC__ @@ -273,6 +275,7 @@ uint32 sim_brk_test (t_addr bloc, uint32 btyp); void sim_brk_clrspc (uint32 spc, uint32 btyp); void sim_brk_npc (uint32 cnt); void sim_brk_setact (const char *action); +char *sim_brk_replace_act (char *new_action); const char *sim_brk_message(void); t_stat sim_send_input (SEND *snd, uint8 *data, size_t size, uint32 after, uint32 delay); t_stat sim_show_send_input (FILE *st, const SEND *snd); diff --git a/sim_console.c b/sim_console.c index 99ebf53..437b801 100644 --- a/sim_console.c +++ b/sim_console.c @@ -702,16 +702,21 @@ static t_stat x_sampleout_cmd (int32 flag, CONST char *cptr) return 4+SCPE_IERR; /* This routine should never be called */ } -static t_stat x_step_cmd (int32 flag, CONST char *cptr) +static t_stat x_execute_cmd (int32 flag, CONST char *cptr) { return 5+SCPE_IERR; /* This routine should never be called */ } -static t_stat x_run_cmd (int32 flag, CONST char *cptr) +static t_stat x_step_cmd (int32 flag, CONST char *cptr) { return 6+SCPE_IERR; /* This routine should never be called */ } +static t_stat x_run_cmd (int32 flag, CONST char *cptr) +{ +return 7+SCPE_IERR; /* This routine should never be called */ +} + static t_stat x_help_cmd (int32 flag, CONST char *cptr); static CTAB allowed_remote_cmds[] = { @@ -732,6 +737,7 @@ static CTAB allowed_remote_cmds[] = { { "DIR", &dir_cmd, 0 }, { "LS", &dir_cmd, 0 }, { "ECHO", &echo_cmd, 0 }, + { "ECHOF", &echof_cmd, 0 }, { "SET", &set_cmd, 0 }, { "SHOW", &show_cmd, 0 }, { "HELP", &x_help_cmd, 0 }, @@ -750,6 +756,7 @@ static CTAB allowed_master_remote_cmds[] = { { "REPEAT", &x_repeat_cmd, 0 }, { "COLLECT", &x_collect_cmd, 0 }, { "SAMPLEOUT",&x_sampleout_cmd, 0 }, + { "EXECUTE", &x_execute_cmd, 0 }, { "STEP", &x_step_cmd, 0 }, { "PWD", &pwd_cmd, 0 }, { "SAVE", &save_cmd, 0 }, @@ -757,6 +764,7 @@ static CTAB allowed_master_remote_cmds[] = { { "DIR", &dir_cmd, 0 }, { "LS", &dir_cmd, 0 }, { "ECHO", &echo_cmd, 0 }, + { "ECHOF", &echof_cmd, 0 }, { "SET", &set_cmd, 0 }, { "SHOW", &show_cmd, 0 }, { "HELP", &x_help_cmd, 0 }, @@ -769,6 +777,8 @@ static CTAB allowed_master_remote_cmds[] = { { "NOBREAK", &brk_cmd, SSH_CL }, { "EXPECT", &expect_cmd, 1 }, { "NOEXPECT", &expect_cmd, 0 }, + { "DEBUG", &debug_cmd, 1 }, + { "NODEBUG", &debug_cmd, 0 }, { "SEND", &send_cmd, 0 }, { NULL, NULL } }; @@ -781,10 +791,12 @@ static CTAB allowed_single_remote_cmds[] = { { "REPEAT", &x_repeat_cmd, 0 }, { "COLLECT", &x_collect_cmd, 0 }, { "SAMPLEOUT",&x_sampleout_cmd, 0 }, + { "EXECUTE", &x_execute_cmd, 0 }, { "PWD", &pwd_cmd, 0 }, { "DIR", &dir_cmd, 0 }, { "LS", &dir_cmd, 0 }, { "ECHO", &echo_cmd, 0 }, + { "ECHOF", &echof_cmd, 0 }, { "SHOW", &show_cmd, 0 }, { "HELP", &x_help_cmd, 0 }, { NULL, NULL } @@ -794,6 +806,7 @@ static CTAB remote_only_cmds[] = { { "REPEAT", &x_repeat_cmd, 0 }, { "COLLECT", &x_collect_cmd, 0 }, { "SAMPLEOUT",&x_sampleout_cmd, 0 }, + { "EXECUTE", &x_execute_cmd, 0 }, { NULL, NULL } }; @@ -939,15 +952,28 @@ while (sim_isspace (*rem->act)) /* skip spaces */ rem->act++; if (*rem->act == 0) /* now empty? */ return sim_rem_clract (line); -if ((ep = strchr (rem->act, ';'))) { /* cmd delimiter? */ +ep = strpbrk (rem->act, ";\"'"); /* search for a semicolon or single or double quote */ +if ((ep != NULL) && (*ep != ';')) { /* if a quoted string is present */ + char quote = *ep++; /* then save the opening quotation mark */ + + while (ep [0] != '\0' && ep [0] != quote) /* while characters remain within the quotes */ + if (ep [0] == '\\' && ep [1] == quote) /* if an escaped quote sequence follows */ + ep = ep + 2; /* then skip over the pair */ + else /* otherwise */ + ep = ep + 1; /* skip the non-quote character */ + ep = strchr (ep, ';'); /* the next semicolon is outside the quotes if it exists */ + } + +if (ep != NULL) { /* if a semicolon is present */ lnt = ep - rem->act; /* cmd length */ memcpy (buf, rem->act, lnt + 1); /* copy with ; */ buf[lnt] = 0; /* erase ; */ rem->act += lnt + 1; /* adv ptr */ } else { - strncpy (buf, rem->act, size); /* copy action */ + strlcpy (buf, rem->act, size); /* copy action */ rem->act += strlen (rem->act); /* adv ptr to end */ + sim_rem_clract (line); } return buf; } @@ -1443,7 +1469,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0); while (1) { if (stat == SCPE_EXIT) return stat|SCPE_NOMESSAGE; - if (!rem->single_mode) { + if ((!rem->single_mode) && (rem->act == NULL)) { read_start_time = sim_os_msec(); if (master_session) tmxr_linemsg (lp, "sim> "); @@ -1457,26 +1483,24 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0); if (!master_session) tmxr_linemsgf (lp, "%s%s\n", sim_prompt, rem->buf); else - tmxr_linemsgf (lp, "%s%s\n", sim_is_running ? "SIM> " : "sim> ", rem->buf); - rem->buf_ptr = strlen (rem->repeat_action); + tmxr_linemsgf (lp, "%s%s\n", "SIM> ", rem->buf); + rem->buf_ptr = strlen (rem->buf); got_command = TRUE; break; } - else { - if ((rem->repeat_pending) && /* New repeat pending */ - (rem->act == NULL) && /* AND no prior still active */ - (!tmxr_input_pending_ln (lp))) { /* AND no session input pending */ - rem->repeat_pending = FALSE; - sim_rem_setact (rem-sim_rem_consoles, rem->repeat_action); - sim_rem_getact (rem-sim_rem_consoles, rem->buf, rem->buf_size); - if (!master_session) - tmxr_linemsgf (lp, "%s%s\n", sim_prompt, rem->buf); - else - tmxr_linemsgf (lp, "%s%s\n", sim_is_running ? "SIM> " : "sim> ", rem->buf); - rem->buf_ptr = strlen (rem->repeat_action); - got_command = TRUE; - break; - } + if ((rem->repeat_pending) && /* New repeat pending */ + (rem->act == NULL) && /* AND no prior still active */ + (!tmxr_input_pending_ln (lp))) { /* AND no session input pending */ + rem->repeat_pending = FALSE; + sim_rem_setact (rem-sim_rem_consoles, rem->repeat_action); + sim_rem_getact (rem-sim_rem_consoles, rem->buf, rem->buf_size); + if (!master_session) + tmxr_linemsgf (lp, "%s%s\n", sim_prompt, rem->buf); + else + tmxr_linemsgf (lp, "%s%s\n", "SIM> ", rem->buf); + rem->buf_ptr = strlen (rem->buf); + got_command = TRUE; + break; } } if (!rem->single_mode) { @@ -1688,21 +1712,32 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0); stat = sim_rem_repeat_cmd_setup (i, &cptr); } else { - if (cmdp->action == &x_collect_cmd) { - sim_debug (DBG_CMD, &sim_remote_console, "sample_cmd executing\n"); - stat = sim_rem_collect_cmd_setup (i, &cptr); + if (cmdp->action == &x_execute_cmd) { + sim_debug (DBG_CMD, &sim_remote_console, "execute_cmd executing\n"); + if (rem->act) + stat = SCPE_IERR; + else { + sim_rem_setact (rem-sim_rem_consoles, cptr); + stat = SCPE_OK; + } } else { - if (sim_con_stable_registers && - sim_rem_master_mode) { /* can we process command now? */ - sim_debug (DBG_CMD, &sim_remote_console, "Processing Command directly\n"); - sim_oline = lp; /* specify output socket */ - sim_remote_process_command (); - stat = SCPE_OK; /* any message has already been emitted */ + if (cmdp->action == &x_collect_cmd) { + sim_debug (DBG_CMD, &sim_remote_console, "collect_cmd executing\n"); + stat = sim_rem_collect_cmd_setup (i, &cptr); } else { - sim_debug (DBG_CMD, &sim_remote_console, "Processing Command via SCPE_REMOTE\n"); - stat = SCPE_REMOTE; /* force processing outside of sim_instr() */ + if (sim_con_stable_registers && + sim_rem_master_mode) { /* can we process command now? */ + sim_debug (DBG_CMD, &sim_remote_console, "Processing Command directly\n"); + sim_oline = lp; /* specify output socket */ + sim_remote_process_command (); + stat = SCPE_OK; /* any message has already been emitted */ + } + else { + sim_debug (DBG_CMD, &sim_remote_console, "Processing Command via SCPE_REMOTE\n"); + stat = SCPE_REMOTE; /* force processing outside of sim_instr() */ + } } } } @@ -1779,7 +1814,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0); } if (sim_rem_master_was_connected && /* Master mode ever connected? */ !sim_rem_con_tmxr.ldsc[0].sock) /* Master Connection lost? */ - return SCPE_EXIT; /* simulator has been 'unplugged' */ + return sim_messagef (SCPE_EXIT, "Master Session Disconnect");/* simulator has been 'unplugged' */ if (sim_rem_cmd_active_line != -1) { if (steps) sim_activate(uptr, steps); /* check again after 'steps' instructions */ @@ -1983,6 +2018,8 @@ if (sim_rem_master_mode) { sim_rem_master_was_enabled = TRUE; sim_last_cmd_stat = SCPE_OK; while (sim_rem_master_mode) { + char *brk_action; + sim_rem_consoles[0].single_mode = FALSE; sim_cancel (rem_con_data_unit); sim_activate (rem_con_data_unit, -1); @@ -1991,9 +2028,14 @@ if (sim_rem_master_mode) { stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message supression flag */ stat = _sim_rem_message ("RUN", stat); } - sim_debug (DBG_MOD, &sim_remote_console, "Master Session Returned: Status - %d Active_Line: %d, Mode: %s, Active Cmd: %s\n", stat, sim_rem_cmd_active_line, sim_rem_consoles[0].single_mode ? "Single" : "^E Stopped", sim_rem_active_command ? sim_rem_active_command->name : ""); + brk_action = sim_brk_replace_act (NULL); + sim_debug (DBG_MOD, &sim_remote_console, "Master Session Returned: Status - %d Active_Line: %d, Mode: %s, Active Cmd: %s%s%s\n", stat, sim_rem_cmd_active_line, sim_rem_consoles[0].single_mode ? "Single" : "^E Stopped", sim_rem_active_command ? sim_rem_active_command->name : "", brk_action ? " Break Action: " : "", brk_action ? brk_action : ""); if (stat == SCPE_EXIT) sim_rem_master_mode = FALSE; + if (brk_action) { + free (sim_rem_consoles[0].act); + sim_rem_consoles[0].act = brk_action; + } sim_rem_cmd_active_line = 0; /* Make it look like */ sim_rem_consoles[0].single_mode = FALSE; if (stat != SCPE_STEP) @@ -2181,7 +2223,6 @@ char gbuf[CBUFSIZE]; t_stat r; time_t now; -sim_deb_switches = sim_switches; /* save debug switches */ if ((cptr == NULL) || (*cptr == 0)) /* need arg */ return SCPE_2FARG; cptr = get_glyph_nc (cptr, gbuf, 0); /* get file name */ @@ -2192,6 +2233,7 @@ r = sim_open_logfile (gbuf, FALSE, &sim_deb, &sim_deb_ref); if (r != SCPE_OK) return r; +sim_deb_switches = sim_switches; /* save debug switches */ if (sim_deb_switches & SWMASK ('R')) { clock_gettime(CLOCK_REALTIME, &sim_deb_basetime); if (!(sim_deb_switches & (SWMASK ('A') | SWMASK ('T'))))