|
|
| version 1.18, 2025/04/29 18:46:17 | version 1.31, 2025/05/20 18:07:41 |
|---|---|
| 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.31 2025/05/20 18:07:41 snw | |
| * Add completion to debugger | |
| * | |
| * Revision 1.30 2025/05/20 16:20:42 snw | |
| * Update ROUTINE SSVN after ZEDIT and ZSAVE | |
| * | |
| * Revision 1.29 2025/05/20 14:56:56 snw | |
| * Fix direct-mode interface to online help | |
| * | |
| * Revision 1.28 2025/05/20 14:36:06 snw | |
| * Documentation updates; raise ZCMMND instead of NOSTAND for restricted_mode restrictions | |
| * | |
| * Revision 1.27 2025/05/19 21:29:29 snw | |
| * Add basic tab completion to direct mode | |
| * | |
| * Revision 1.26 2025/05/19 02:03:31 snw | |
| * Reverse-engineer and document argumented ZPRINT (thanks to D. Wicksell) | |
| * | |
| * Revision 1.25 2025/05/18 18:15:38 snw | |
| * Add ZEDIT command for editing routines | |
| * | |
| * Revision 1.24 2025/05/14 12:22:04 snw | |
| * Further work on shared memory | |
| * | |
| * 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 | * Revision 1.18 2025/04/29 18:46:17 snw |
| * Begin work on interactive debugger | * Begin work on interactive debugger |
| * | * |
| Line 159 void rbuf_dump(void); | Line 198 void rbuf_dump(void); |
| short rbuf_slot_from_name(char *); | short rbuf_slot_from_name(char *); |
| short is_standard(void); | short is_standard(void); |
| #ifdef HAVE_LIBREADLINE | |
| char *m_commands[] = { | |
| "?", | |
| "@", | |
| "!<", | |
| "!>", | |
| "!!", | |
| "ablock", | |
| "astart", | |
| "astop", | |
| "aunblock", | |
| "break", | |
| "close", | |
| "do", | |
| "else", | |
| "events", | |
| "for", | |
| "goto", | |
| "halt", | |
| "hang", | |
| "history", | |
| "if", | |
| "job", | |
| "jobtab", | |
| "kill", | |
| "ksubscripts", | |
| "kvalue", | |
| "lock", | |
| "locktab", | |
| "merge", | |
| "new", | |
| "open", | |
| "quit", | |
| "rbuf", | |
| "rcl", | |
| "read", | |
| "set", | |
| "shmpages", | |
| "shmstat", | |
| "tcommit", | |
| "then", | |
| "trantab", | |
| "trollback", | |
| "tstart", | |
| "use", | |
| "view", | |
| "wh", | |
| "write", | |
| "xecute", | |
| "zassert", | |
| "zbreak", | |
| "zconst", | |
| "zedit", | |
| "zgoto", | |
| "zhalt", | |
| "zinsert", | |
| "zjob", | |
| "zload", | |
| "zmap", | |
| "znew", | |
| "zprint", | |
| "zquit", | |
| "zremove", | |
| "zsave", | |
| "zthrow", | |
| "ztrap", | |
| "zunmap", | |
| "zwatch", | |
| "zwith", | |
| "zwrite", | |
| "ABLOCK", | |
| "ASTART", | |
| "ASTOP", | |
| "AUNBLOCK", | |
| "BREAK", | |
| "CLOSE", | |
| "DO", | |
| "ELSE", | |
| "FOR", | |
| "GOTO", | |
| "HALT", | |
| "HANG", | |
| "IF", | |
| "JOB", | |
| "KILL", | |
| "KSUBSCRIPTS", | |
| "KVALUE", | |
| "LOCK", | |
| "MERGE", | |
| "NEW", | |
| "OPEN", | |
| "QUIT", | |
| "READ", | |
| "SET", | |
| "TCOMMIT", | |
| "THEN", | |
| "TROLLBACK", | |
| "TSTART", | |
| "USE", | |
| "VIEW", | |
| "WRITE", | |
| "XECUTE", | |
| "ZASSERT", | |
| "ZBREAK", | |
| "ZCONST", | |
| "ZEDIT", | |
| "ZGOTO", | |
| "ZHALT", | |
| "ZINSERT", | |
| "ZJOB", | |
| "ZLOAD", | |
| "ZMAP", | |
| "ZNEW", | |
| "ZPRINT", | |
| "ZQUIT", | |
| "ZREMOVE", | |
| "ZSAVE", | |
| "ZTHROW", | |
| "ZTRAP", | |
| "ZUNMAP", | |
| "ZWATCH", | |
| "ZWITH", | |
| "ZWRITE", | |
| NULL | |
| }; | |
| char **command_completion(const char *, int, int); | |
| char *command_generator(const char *, int); | |
| char **command_completion(const char *text, int start, int end) | |
| { | |
| if (start > 0) return NULL; | |
| rl_attempted_completion_over = 1; | |
| return rl_completion_matches (text, command_generator); | |
| } | |
| char *command_generator(const char *text, int state) | |
| { | |
| static int list_index, len; | |
| char *name; | |
| if (!state) { | |
| list_index = 0; | |
| len = strlen (text); | |
| } | |
| while ((name = m_commands[list_index++])) { | |
| if (strncmp (name, text, len) == 0) { | |
| return strdup (name); | |
| } | |
| } | |
| return NULL; | |
| } | |
| #endif | |
| /* | /* |
| * xecline(): | * xecline(): |
| * typ (where to go on function entry): 1 = restart | * typ (where to go on function entry): 1 = restart |
| Line 171 int xecline(int typ) | Line 366 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; |
| Line 194 int xecline(int typ) | Line 388 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 244 int xecline(int typ) | Line 439 int xecline(int typ) |
| next_line: /* entry point for next command line */ | next_line: /* entry point for next command line */ |
| if (debug_mode) { | if (debug_mode) { |
| debug_mode = debugger (); | debug_mode = debugger (DEBENTRY_LINE, entryref); |
| } | } |
| job_set_status (pid, JSTAT_INTERPRETER); | job_set_status (pid, JSTAT_INTERPRETER); |
| if (then_ctr > 0) { | if (then_ctr > 0) { |
| Line 294 next_line: /* entry point for n | Line 489 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 514 next0: | Line 714 next0: |
| if (ch == '!') { /* UNIXCALL */ | if (ch == '!') { /* UNIXCALL */ |
| if (restricted_mode) { | if (restricted_mode) { |
| merr_raise (NOSTAND); | merr_raise (CMMND); |
| goto err; | goto err; |
| } | } |
| Line 2616 quit0: | Line 2816 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 2642 quit0: | Line 2841 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 4518 use_socket: | Line 4717 use_socket: |
| if (k > MAXSEQ) goto open_socket; | if (k > MAXSEQ) goto open_socket; |
| if (restricted_mode) { | if (restricted_mode) { |
| merr_raise (NOSTAND); | merr_raise (CMMND); |
| goto err; | goto err; |
| } | } |
| Line 4950 open_socket: | Line 5149 open_socket: |
| if (merr () > OK) break; | if (merr () > OK) break; |
| } | } |
| else { | else { |
| halt:i = 0; | halt: |
| i = 0; | |
| } | } |
| cleanup (); | cleanup (); |
| Line 5269 open_socket: | Line 5469 open_socket: |
| break; | break; |
| /* Z-COMMANDS */ | /* Z-COMMANDS */ |
| case ZEDIT: | |
| merr_raise (cmd_zedit (&ra)); | |
| MRESCHECK(ra); | |
| break; | |
| case ZGO: | case ZGO: |
| /* ZGO with arguments: same as GOTO but with BREAK on */ | /* ZGO with arguments: same as GOTO but with BREAK on */ |
| Line 5408 zgo: | Line 5613 zgo: |
| merr_raise (NOPGM); | merr_raise (NOPGM); |
| break; | break; |
| } /*error */ | } /* error */ |
| stcpy (varnam, rou_name); | stcpy (varnam, rou_name); |
| } | } |
| Line 5426 zgo: | Line 5631 zgo: |
| } | } |
| zsave (varnam); | zsave (varnam); |
| ssvn_routine_update (); | |
| break; | break; |
| Line 5544 zgo: | Line 5750 zgo: |
| if (*codptr == EOL || *codptr == SP) { | if (*codptr == EOL || *codptr == SP) { |
| merr_raise (ARGLIST); | merr_raise (ARGLIST); |
| break; | break; |
| } /*error */ | } /* error */ |
| dosave[0] = EOL; | dosave[0] = EOL; |
| /* parse stringlit */ | /* parse strlit */ |
| expr (STRING); | expr (STRING); |
| if (merr () > OK) break; | if (merr () > OK) break; |
| Line 5657 zgo: | Line 5863 zgo: |
| } | } |
| if ((*(beg + 1)) == EOL) break; | if ((*(beg + 1)) == EOL) break; |
| write_m (beg + 1); | write_m (beg + 1); |
| if (merr () > OK) break; | if (merr () > OK) break; |
| } | } |
| Line 6744 syn_evt_loop_bottom: | Line 6950 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 6787 err: | Line 6992 err: |
| } | } |
| } | } |
| if (merr () > OK ) { | if (merr () > OK ) { |
| char er_buf[ERRLEN]; | char er_buf[ERRLEN]; |
| Line 6796 err: | Line 7002 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) |
| logprintf (FM_LOG_DEBUG, "xecline: interpreter error %d [%s]", ierr, er_buf); | logprintf (FM_LOG_DEBUG, "xecline: interpreter error %d [%s]", ierr, er_buf); |
| #endif | #endif |
| Line 7168 restart: | Line 7375 restart: |
| free (t_nsn); | free (t_nsn); |
| } | } |
| Line 7229 restore: | Line 7437 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 7260 direct_mode: | Line 7465 direct_mode: |
| int hist_idx; | int hist_idx; |
| HIST_ENTRY *hist_ent; | HIST_ENTRY *hist_ent; |
| rl_attempted_completion_function = command_completion; | |
| if (quiet_mode == FALSE) { | if (quiet_mode == FALSE) { |
| if (tp_level == 0) { | if (tp_level == 0) { |
| snprintf (fmrl_prompt, sizeof (fmrl_prompt) - 1, "\r\n%s.%s> ", shm_env, nsname); | snprintf (fmrl_prompt, sizeof (fmrl_prompt) - 1, "\r\n%s.%s> ", shm_env, nsname); |
| Line 7271 direct_mode: | Line 7478 direct_mode: |
| 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 7282 direct_mode: | Line 7493 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 7292 direct_mode: | Line 7504 direct_mode: |
| char kb[20]; | char kb[20]; |
| char db[STRLEN]; | char db[STRLEN]; |
| snprintf (kb, sizeof (kb) - 1, "%%SYS.HLP\201"); | snprintf (kb, sizeof (kb) - 1, "%%SYSHLP\201"); |
| snprintf (db, STRLEN - 1, "\201"); | snprintf (db, STRLEN - 1, "\201"); |
| symtab (kill_sym, kb, db); | symtab (kill_sym, kb, db); |