|
|
| version 1.13, 2025/04/10 01:24:39 | version 1.23, 2025/05/06 16:10:06 |
|---|---|
| Line 24 | Line 24 |
| * along with FreeM. If not, see <https://www.gnu.org/licenses/>. | * along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
| * | * |
| * $Log$ | * $Log$ |
| * Revision 1.23 2025/05/06 16:10:06 snw | |
| * Add extra blank before readline call on NetBSD | |
| * | |
| * Revision 1.22 2025/05/05 14:53:17 snw | |
| * Modify rpm spec to include documentation TODO | |
| * | |
| * Revision 1.21 2025/05/01 17:02:30 snw | |
| * Further debugging improvements | |
| * | |
| * Revision 1.20 2025/04/30 17:19:16 snw | |
| * Improve backtraces in debugger | |
| * | |
| * Revision 1.19 2025/04/30 14:41:03 snw | |
| * Further debugger work | |
| * | |
| * Revision 1.18 2025/04/29 18:46:17 snw | |
| * Begin work on interactive debugger | |
| * | |
| * Revision 1.17 2025/04/28 19:38:55 snw | |
| * Add trace mode | |
| * | |
| * Revision 1.16 2025/04/28 14:52:54 snw | |
| * Temporarily revert global handler refactor and fix reference regression in xecline | |
| * | |
| * Revision 1.15 2025/04/15 16:49:36 snw | |
| * Make use of logprintf throughout codebase | |
| * | |
| * Revision 1.14 2025/04/13 04:22:43 snw | |
| * Fix snprintf calls | |
| * | |
| * Revision 1.13 2025/04/10 01:24:39 snw | * Revision 1.13 2025/04/10 01:24:39 snw |
| * Remove C++ style comments | * Remove C++ style comments |
| * | * |
| Line 156 int xecline(int typ) | Line 186 int xecline(int typ) |
| short new_and_set = FALSE; | short new_and_set = FALSE; |
| short new_object = FALSE; | short new_object = FALSE; |
| short destructor_run = FALSE; | short destructor_run = FALSE; |
| short debug_mode = FALSE; | |
| short libcall = FALSE; | short libcall = FALSE; |
| char *namold; | char *namold; |
| long rouoldc; | long rouoldc; |
| unsigned long jobtime; | unsigned long jobtime; |
| char label[256], routine[256]; | char label[256], routine[256]; |
| char tracestr[512]; | |
| char *vn; | char *vn; |
| char *an; | char *an; |
| char *tmp; | char *tmp; |
| Line 177 int xecline(int typ) | Line 208 int xecline(int typ) |
| char *reeval_codptr; | char *reeval_codptr; |
| char reeval_code[512]; | char reeval_code[512]; |
| char entryref[256]; | |
| int i; | int i; |
| int j; | int j; |
| Line 226 int xecline(int typ) | Line 258 int xecline(int typ) |
| next_line: /* entry point for next command line */ | next_line: /* entry point for next command line */ |
| if (debug_mode) { | |
| debug_mode = debugger (DEBENTRY_LINE, entryref); | |
| } | |
| job_set_status (pid, JSTAT_INTERPRETER); | job_set_status (pid, JSTAT_INTERPRETER); |
| Line 274 next_line: /* entry point for n | Line 309 next_line: /* entry point for n |
| codptr = code; | codptr = code; |
| next_cmnd: /* continue line entry point */ | next_cmnd: /* continue line entry point */ |
| getraddress (entryref, nstx); | |
| if (debug_mode) { | |
| debug_mode = debugger (DEBENTRY_CMD, entryref); | |
| } | |
| if (sigint_in_for) goto for_quit; | if (sigint_in_for) goto for_quit; |
| if (forsw && (forpost[forx][0] != '\0')) { | if (forsw && (forpost[forx][0] != '\0')) { |
| Line 531 next0: | Line 571 next0: |
| else if (tmp2[0] == '<') { /* call write output to %-array */ | else if (tmp2[0] == '<') { /* call write output to %-array */ |
| FILE *pipdes; | FILE *pipdes; |
| char key[STRLEN + 1 /*was 256 */ ]; | char key[STRLEN]; |
| char data[STRLEN + 1 /*was 256 */ ]; | char data[STRLEN]; |
| char data_kill[256]; | char data_kill[256]; |
| data_kill[255] = EOL; | data_kill[255] = EOL; |
| for (i = 0; i < STRLEN + 1; i++) vn[i] = EOL; | for (i = 0; i < STRLEN - 1; i++) vn[i] = EOL; |
| snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid); | snprintf (key, STRLEN - 1, "^$JOB\202%d\202PIPE_GLVN\201", pid); |
| ssvn (get_sym, key, vn); | ssvn (get_sym, key, vn); |
| if (vn[0] == '^') { | if (vn[0] == '^') { |
| Line 556 next0: | Line 596 next0: |
| symtab (kill_sym, vn, data); | symtab (kill_sym, vn, data); |
| } | } |
| snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid); | snprintf (key, STRLEN - 1, "^$JOB\202%d\202PIPE_GLVN\201", pid); |
| ssvn (get_sym, key, vn); | ssvn (get_sym, key, vn); |
| data[0] = '0'; | data[0] = '0'; |
| Line 585 next0: | Line 625 next0: |
| int glvn_len = 0; | int glvn_len = 0; |
| while (fgets (data, STRLEN, pipdes)) { | while (fgets (data, STRLEN, pipdes)) { |
| snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid); | snprintf (key, STRLEN - 1, "^$JOB\202%d\202PIPE_GLVN\201", pid); |
| ssvn (get_sym, key, vn); | ssvn (get_sym, key, vn); |
| glvn_len = stlen (vn); | glvn_len = stlen (vn); |
| Line 646 next0: | Line 686 next0: |
| for (i = 0; i < STRLEN + 1; i++) vn[i] = EOL; | for (i = 0; i < STRLEN + 1; i++) vn[i] = EOL; |
| snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid); | snprintf (key, STRLEN - 1, "^$JOB\202%d\202PIPE_GLVN\201", pid); |
| ssvn (get_sym, key, vn); | ssvn (get_sym, key, vn); |
| if (vn[0] == '^') { | if (vn[0] == '^') { |
| Line 675 next0: | Line 715 next0: |
| int glvn_len = 0; | int glvn_len = 0; |
| for (i = 1; i <= k; i++) { | for (i = 1; i <= k; i++) { |
| snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid); | snprintf (key, STRLEN - 1, "^$JOB\202%d\202PIPE_GLVN\201", pid); |
| ssvn (get_sym, key, vn); | ssvn (get_sym, key, vn); |
| glvn_len = stlen (vn); | glvn_len = stlen (vn); |
| Line 845 again: | Line 885 again: |
| } | } |
| } | } |
| if (trace_mode) tracestr[0] = '\0'; | |
| switch (mcmnd) { | switch (mcmnd) { |
| case MAP: | case MAP: |
| Line 967 set0: | Line 1009 set0: |
| ch = *codptr; | ch = *codptr; |
| if (ch == '.') { | if (ch == '.') { |
| setref = TRUE; | if (!isdigit (*(codptr + 1))) { |
| codptr++; | setref = TRUE; |
| expr (NAME); | codptr++; |
| expr (NAME); | |
| } | |
| else { | |
| expr (STRING); | |
| } | |
| } | } |
| else { | else { |
| expr (STRING); | expr (STRING); |
| Line 2353 s_end: | Line 2400 s_end: |
| case QUIT: | case QUIT: |
| if (trace_mode) { | |
| fprintf (stderr, ">> TRACE: $STACK = %d QUIT CMD = %c\r\n", nstx, nestc[nstx]); | |
| } | |
| if (tp_level > 0) { | if (tp_level > 0) { |
| merr_raise (M42); | merr_raise (M42); |
| goto err; | goto err; |
| Line 2382 s_end: | Line 2433 s_end: |
| if (nestc[nstx] == '$') { /* extrinsic function/variable */ | if (nestc[nstx] == '$') { /* extrinsic function/variable */ |
| if (trace_mode) { | |
| fprintf (stderr, ">> TRACE: QUIT FROM EXTRINSIC\r\n"); | |
| } | |
| #ifdef DEBUG_NEWSTACK | #ifdef DEBUG_NEWSTACK |
| printf ("EXTRINSIC\r\n"); | printf ("EXTRINSIC\r\n"); |
| #endif | #endif |
| Line 2411 s_end: | Line 2466 s_end: |
| else { | else { |
| expr (STRING); | expr (STRING); |
| if (trace_mode) { | |
| fprintf (stderr, ">> TRACE: QUIT FROM SUBROUTINE\r\n"); | |
| } | |
| if (ierr != OK - CTRLB && merr () != OK && merr () != INRPT) { | if (ierr != OK - CTRLB && merr () != OK && merr () != INRPT) { |
| Line 2577 quit0: | Line 2636 quit0: |
| printf ("CHECK 03 (Stack PUSH)\r\n"); | printf ("CHECK 03 (Stack PUSH)\r\n"); |
| #endif | #endif |
| if (++nstx > NESTLEVLS) { | if (++nstx > NESTLEVLS) { |
| nstx--; | nstx--; |
| merr_raise (STKOV); | merr_raise (STKOV); |
| Line 2603 quit0: | Line 2661 quit0: |
| nestn[nstx] = 0; /* no overring of routine */ | nestn[nstx] = 0; /* no overring of routine */ |
| nestr[nstx] = roucur - rouptr; /* save roucur: only for $V(26) needed */ | nestr[nstx] = roucur - rouptr; /* save roucur: only for $V(26) needed */ |
| ztrap[nstx][0] = EOL; | ztrap[nstx][0] = EOL; |
| forsw = TRUE; | forsw = TRUE; |
| ftyp = 0; /* no args is FOREVER */ | ftyp = 0; /* no args is FOREVER */ |
| Line 3047 do_xecute: | Line 3105 do_xecute: |
| do_goto: | do_goto: |
| if (trace_mode) { | |
| char rn[256]; | |
| stcpy (rn, rou_name); | |
| stcnv_m2c (rn); | |
| switch (mcmnd) { | |
| case DO: | |
| snprintf (tracestr, sizeof (tracestr) - 1, "rtn = %s $stack = %d do ", rn, nstx); | |
| break; | |
| case GOTO: | |
| snprintf (tracestr, sizeof (tracestr) - 1, "rtn = %s $stack = %d goto ", rn, nstx); | |
| break; | |
| } | |
| } | |
| offset = 0; | offset = 0; |
| label[0] = routine[0] = EOL; | label[0] = routine[0] = EOL; |
| dofram0 = 0; | dofram0 = 0; |
| Line 3081 do_goto: | Line 3154 do_goto: |
| stcpy (label, varnam); | stcpy (label, varnam); |
| if (trace_mode) { | |
| char ttt[256]; | |
| stcpy (ttt, label); | |
| stcnv_m2c (ttt); | |
| strcat (tracestr, ttt); | |
| } | |
| ch = *++codptr; | ch = *++codptr; |
| } | } |
| Line 3096 do_goto: | Line 3177 do_goto: |
| /* unless argument is numeric, expr returns wrong codptr */ | /* unless argument is numeric, expr returns wrong codptr */ |
| if ((ch = *codptr) != SP && (ch != EOL) && (ch != ',') && (ch != '^')) ch = *++codptr; | if ((ch = *codptr) != SP && (ch != EOL) && (ch != ',') && (ch != '^')) ch = *++codptr; |
| if (trace_mode) { | |
| char ttt[256]; | |
| snprintf (ttt, 255, "+%d", offset); | |
| strcat (tracestr, ttt); | |
| } | |
| } | } |
| if (ch == '^') { /* parse routine */ | if (ch == '^') { /* parse routine */ |
| Line 3106 do_goto: | Line 3192 do_goto: |
| if (merr () > OK) goto err; | if (merr () > OK) goto err; |
| stcpy (routine, varnam); | stcpy (routine, varnam); |
| if (trace_mode) { | |
| char ttt[256]; | |
| char ttx[256]; | |
| stcpy (ttt, routine); | |
| stcnv_m2c (ttt); | |
| snprintf (ttx, 255, "^%s", ttt); | |
| strcat (tracestr, ttx); | |
| } | |
| dosave[0] = EOL; | dosave[0] = EOL; |
| ch = *++codptr; | ch = *++codptr; |
| loadsw = TRUE; | loadsw = TRUE; |
| } | } |
| if (trace_mode) { | |
| fprintf (stderr, ">> TRACE: %s\r\n", tracestr); | |
| } | |
| if (ch == '(' && mcmnd == DO) { /* parse parameter */ | if (ch == '(' && mcmnd == DO) { /* parse parameter */ |
| if (offset) { | if (offset) { |
| Line 3989 off3: | Line 4089 off3: |
| if (merr () > OK) goto err; | if (merr () > OK) goto err; |
| /* TODO: check this snprintf for proper sizing */ | |
| snprintf (&tmp3[1], 255, "%s\201", &constructor[1]); | snprintf (&tmp3[1], 255, "%s\201", &constructor[1]); |
| goto private; | goto private; |
| Line 4868 open_socket: | Line 4969 open_socket: |
| if (merr () > OK) break; | if (merr () > OK) break; |
| } | } |
| else { | else { |
| halt:i = 0; | halt: |
| i = 0; | |
| } | } |
| cleanup (); | cleanup (); |
| Line 5067 open_socket: | Line 5169 open_socket: |
| expr (STRING); | expr (STRING); |
| if (merr () > OK) break; | if (merr () > OK) break; |
| switch (intexpr (argptr)) { | { |
| char brkstr[256]; | |
| case 2: | |
| DSM2err = TRUE; | stcpy (brkstr, argptr); |
| break; /* enable DSM V 2 error processing */ | stcnv_m2c (brkstr); |
| case -2: | if (strcmp (brkstr, "DEBUG") == 0) { |
| DSM2err = FALSE; | debug_mode = TRUE; |
| break; /* enable normal error processing */ | } |
| else { | |
| case 0: | switch (intexpr (argptr)) { |
| breakon = FALSE; | |
| break; /* disable CTRL/C */ | case 2: |
| DSM2err = TRUE; | |
| default: | break; /* enable DSM V 2 error processing */ |
| breakon = TRUE; | |
| break; /* enable CTRL/C */ | case -2: |
| DSM2err = FALSE; | |
| break; /* enable normal error processing */ | |
| case 0: | |
| breakon = FALSE; | |
| break; /* disable CTRL/C */ | |
| default: | |
| breakon = TRUE; | |
| break; /* enable CTRL/C */ | |
| } | |
| } | |
| } | } |
| break; | break; |
| case VIEW: | case VIEW: |
| Line 6649 syn_evt_loop_bottom: | Line 6764 syn_evt_loop_bottom: |
| if (ch != ',' && merr () == OK) { | if (ch != ',' && merr () == OK) { |
| merr_raise (SPACER); | merr_raise (SPACER); |
| } | } |
| else if ((ierr <= OK) || (debug_mode == TRUE)) { | else if (ierr <= OK) { |
| if (debug_mode) goto direct_mode; | |
| if (*++codptr != SP && *codptr != EOL) goto again; | if (*++codptr != SP && *codptr != EOL) goto again; |
| merr_raise (ARGLIST); | merr_raise (ARGLIST); |
| Line 6692 err: | Line 6806 err: |
| } | } |
| } | } |
| if (merr () > OK ) { | if (merr () > OK ) { |
| char er_buf[ERRLEN]; | char er_buf[ERRLEN]; |
| Line 6701 err: | Line 6816 err: |
| stcpy (er_buf, errmes[merr ()]); | stcpy (er_buf, errmes[merr ()]); |
| stcnv_m2c (er_buf); | stcnv_m2c (er_buf); |
| #if !defined(MSDOS) | #if !defined(MSDOS) |
| m_log (LOG_ERR, er_buf); | logprintf (FM_LOG_DEBUG, "xecline: interpreter error %d [%s]", ierr, er_buf); |
| #endif | #endif |
| } | } |
| Line 7073 restart: | Line 7189 restart: |
| free (t_nsn); | free (t_nsn); |
| } | } |
| Line 7134 restore: | Line 7251 restore: |
| goto next_cmnd; | goto next_cmnd; |
| } | } |
| else { | |
| if (debug_mode) goto direct_mode; | |
| } | |
| if (libcall == TRUE) { /* library mode: don't go to direct mode, just return */ | if (libcall == TRUE) { /* library mode: don't go to direct mode, just return */ |
| return merr (); | return merr (); |
| Line 7167 direct_mode: | Line 7281 direct_mode: |
| if (quiet_mode == FALSE) { | if (quiet_mode == FALSE) { |
| if (tp_level == 0) { | if (tp_level == 0) { |
| snprintf (fmrl_prompt, 255, "\r\n%s.%s> ", shm_env, nsname); | snprintf (fmrl_prompt, sizeof (fmrl_prompt) - 1, "\r\n%s.%s> ", shm_env, nsname); |
| } | } |
| else { | else { |
| snprintf (fmrl_prompt, 255, "\r\nTL%d:%s.%s> ", tp_level, shm_env, nsname); | snprintf (fmrl_prompt, sizeof (fmrl_prompt) - 1 , "\r\nTL%d:%s.%s> ", tp_level, shm_env, nsname); |
| } | } |
| } | } |
| set_io (UNIX); | set_io (UNIX); |
| job_set_status (pid, JSTAT_DIRECTMODE); | job_set_status (pid, JSTAT_DIRECTMODE); |
| #if defined(__NetBSD__) | |
| printf ("\r\n"); | |
| #endif | |
| /* readline() does its own malloc() */ | /* readline() does its own malloc() */ |
| fmrl_buf = readline (fmrl_prompt); | fmrl_buf = readline (fmrl_prompt); |
| Line 7187 direct_mode: | Line 7305 direct_mode: |
| goto halt; | goto halt; |
| } | } |
| if (strlen (fmrl_buf) > 0) { | if (strlen (fmrl_buf) > 0) { |
| add_history (fmrl_buf); | add_history (fmrl_buf); |
| Line 7195 direct_mode: | Line 7314 direct_mode: |
| if (fmrl_buf[0] == '?') { | if (fmrl_buf[0] == '?') { |
| char kb[20]; | char kb[20]; |
| char db[255]; | char db[STRLEN]; |
| snprintf (kb, 19, "%%SYS.HLP\201"); | snprintf (kb, sizeof (kb) - 1, "%%SYS.HLP\201"); |
| snprintf (db, 19, "\201"); | snprintf (db, STRLEN - 1, "\201"); |
| symtab (kill_sym, kb, db); | symtab (kill_sym, kb, db); |
| Line 7208 direct_mode: | Line 7327 direct_mode: |
| stcpy (code, "DO ^%ZHELP\201"); | stcpy (code, "DO ^%ZHELP\201"); |
| if (strlen (fmrl_buf) > 1) { | if (strlen (fmrl_buf) > 1) { |
| snprintf (db, 254, "%s\201", &fmrl_buf[1]); | snprintf (db, STRLEN - 1, "%s\201", &fmrl_buf[1]); |
| symtab (set_sym, kb, db); | symtab (set_sym, kb, db); |
| } | } |
| } | } |
| else if (strcmp (fmrl_buf, "step") == 0) { | |
| debug_mode = TRUE; | |
| goto zgo; | |
| } | |
| else if ((strcmp (fmrl_buf, "cont") == 0) || (strcmp (fmrl_buf, "continue") == 0)) { | |
| debug_mode = FALSE; | |
| } | |
| else if (strcmp (fmrl_buf, "rbuf") == 0) { | else if (strcmp (fmrl_buf, "rbuf") == 0) { |
| rbuf_dump (); | rbuf_dump (); |
| } | } |
| Line 7277 direct_mode: | Line 7389 direct_mode: |
| } | } |
| else if (isdigit(fmrl_buf[0]) || (fmrl_buf[0] == '(') || (fmrl_buf[0] == '-') || (fmrl_buf[0] == '\'') || (fmrl_buf[0] == '+') || (fmrl_buf[0] == '$') || (fmrl_buf[0] == '^')) { | else if (isdigit(fmrl_buf[0]) || (fmrl_buf[0] == '(') || (fmrl_buf[0] == '-') || (fmrl_buf[0] == '\'') || (fmrl_buf[0] == '+') || (fmrl_buf[0] == '$') || (fmrl_buf[0] == '^')) { |
| snprintf (code, 255, "W %s", fmrl_buf); | snprintf (code, STRLEN - 1, "W %s", fmrl_buf); |
| stcnv_c2m (code); | stcnv_c2m (code); |
| set_io (MUMPS); | set_io (MUMPS); |
| Line 7359 direct_mode: | Line 7471 direct_mode: |
| char fmrl_prompt[256]; | char fmrl_prompt[256]; |
| if (tp_level == 0) { | if (tp_level == 0) { |
| snprintf (fmrl_prompt, 256, "\r\n%s> \201", nsname); | snprintf (fmrl_prompt, sizeof (fmrl_prompt) - 1, "\r\n%s> \201", nsname); |
| } | } |
| else { | else { |
| snprintf (fmrl_prompt, 256, "\r\nTL%d:%s> \201", tp_level, nsname); | snprintf (fmrl_prompt, sizeof (fmrl_prompt) - 1, "\r\nTL%d:%s> \201", tp_level, nsname); |
| } | } |
| write_m (fmrl_prompt); | write_m (fmrl_prompt); |