File:  [Coherent Logic Development] / freem / src / xecline.c
Revision 1.11: download - view: text, annotated - select for diffs
Wed Apr 2 03:02:42 2025 UTC (5 months, 3 weeks ago) by snw
Branches: MAIN
CVS tags: v0-63-1-rc1, v0-63-0-rc1, v0-63-0, HEAD
Stop requiring users to pass -e to fmadm when -u or -g are passed

    1: /*
    2:  *   $Id: xecline.c,v 1.11 2025/04/02 03:02:42 snw Exp $
    3:  *    freem interpreter proper
    4:  *
    5:  *  
    6:  *   Author: Serena Willis <snw@coherent-logic.com>
    7:  *    Copyright (C) 1998 MUG Deutschland
    8:  *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
    9:  *
   10:  *
   11:  *   This file is part of FreeM.
   12:  *
   13:  *   FreeM is free software: you can redistribute it and/or modify
   14:  *   it under the terms of the GNU Affero Public License as published by
   15:  *   the Free Software Foundation, either version 3 of the License, or
   16:  *   (at your option) any later version.
   17:  *
   18:  *   FreeM is distributed in the hope that it will be useful,
   19:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   20:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21:  *   GNU Affero Public License for more details.
   22:  *
   23:  *   You should have received a copy of the GNU Affero Public License
   24:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
   25:  *
   26:  *   $Log: xecline.c,v $
   27:  *   Revision 1.11  2025/04/02 03:02:42  snw
   28:  *   Stop requiring users to pass -e to fmadm when -u or -g are passed
   29:  *
   30:  *   Revision 1.10  2025/03/27 03:27:35  snw
   31:  *   Install init scripts to share/freem/examples/init and fix regression in method dispatch
   32:  *
   33:  *   Revision 1.9  2025/03/24 04:13:12  snw
   34:  *   Replace action macro dat with fra_dat to avoid symbol conflict on OS/2
   35:  *
   36:  *   Revision 1.8  2025/03/24 04:05:36  snw
   37:  *   Replace crlf with frm_crlf to avoid symbol conflict with readline on OS/2
   38:  *
   39:  *   Revision 1.7  2025/03/22 22:52:24  snw
   40:  *   Add STRLEN_GBL macro to manage global string length
   41:  *
   42:  *   Revision 1.6  2025/03/22 21:44:32  snw
   43:  *   Make the startup messages fewer and add environment name to direct-mode prompt
   44:  *
   45:  *   Revision 1.5  2025/03/09 19:50:47  snw
   46:  *   Second phase of REUSE compliance and header reformat
   47:  *
   48:  *
   49:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
   50:  * SPDX-License-Identifier: AGPL-3.0-or-later
   51:  **/
   52: 
   53: #include <stdlib.h>
   54: 
   55: #include "mpsdef.h"
   56: #include "namespace.h"
   57: #include "transact.h"
   58: #include "merge.h"
   59: #include "sighnd.h"
   60: #include "init.h"
   61: #include "events.h"
   62: #include "mdebug.h"
   63: #include "freem.h"
   64: #include "mref.h"
   65: #include "log.h"
   66: #include "consttbl.h"
   67: #include "shmmgr.h"
   68: #include "locktab.h"
   69: #include "jobtab.h"
   70: #include "config.h"
   71: #include "datatypes.h"
   72: #include "objects.h"
   73: #include "mcommand.h"
   74: 
   75: #if defined(__linux__)
   76: # include <sched.h>
   77: #endif
   78: 
   79: #if !defined(MSDOS)
   80: # include "io_socket.h"
   81: #endif
   82: 
   83: #include "merr.h"
   84: 
   85: #include <errno.h>
   86: #include <unistd.h>
   87: #include <string.h>
   88: 
   89: #if !defined(MSDOS)
   90: # include <syslog.h>
   91: #endif
   92: 
   93: #include <stdio.h>
   94: #include <ctype.h>
   95: 
   96: #include <time.h>
   97: #include <sys/types.h>
   98: #include <pwd.h>
   99: #if !defined(__OpenBSD__) && !defined(__FreeBSD__)
  100: # include <sys/timeb.h>
  101: #endif
  102: #include <sys/wait.h>
  103: #include <sys/time.h>
  104: #include <time.h>
  105: 
  106: #ifdef HAVE_LIBREADLINE
  107: #  if defined(HAVE_READLINE_READLINE_H)
  108: #    include <readline/readline.h>
  109: #  elif defined(HAVE_READLINE_H)
  110: #    include <readline.h>
  111: #  else /* !defined(HAVE_READLINE_H) */
  112: extern char *readline ();
  113: #  endif /* !defined(HAVE_READLINE_H) */
  114: /*char *cmdline = NULL;*/
  115: #else /* !defined(HAVE_READLINE_READLINE_H) */
  116:   /* no readline */
  117: #endif /* HAVE_LIBREADLINE */
  118: 
  119: #ifdef HAVE_READLINE_HISTORY
  120: #  if defined(HAVE_READLINE_HISTORY_H)
  121: #    include <readline/history.h>
  122: #  elif defined(HAVE_HISTORY_H)
  123: #    include <history.h>
  124: #  else /* !defined(HAVE_HISTORY_H) */
  125: extern void add_history ();
  126: extern int write_history ();
  127: extern int read_history ();
  128: #  endif /* defined(HAVE_READLINE_HISTORY_H) */
  129:   /* no history */
  130: #endif /* HAVE_READLINE_HISTORY */
  131: 
  132: #include "mwapi_window.h"
  133: #include "mwapi_event.h"
  134: 
  135: 
  136: void on_frame_entry(void);
  137: void rbuf_dump(void);
  138: short rbuf_slot_from_name(char *);
  139: short is_standard(void);
  140: 
  141: /*
  142:  * xecline():
  143:  *   typ (where to go on function entry):   1 = restart
  144:  *                                          2 = error
  145:  *
  146:  */
  147: int xecline(int typ)
  148: {
  149:     MACTION ra;
  150:     short new_and_set = FALSE;
  151:     short new_object = FALSE;
  152:     short destructor_run = FALSE;
  153:     short debug_mode = FALSE;
  154:     short libcall = FALSE;
  155:     char *namold;
  156:     long rouoldc;
  157:     unsigned long jobtime;
  158:     char label[256], routine[256];
  159: 
  160:     char *vn;
  161:     char *an;
  162:     char *tmp;
  163:     char *tmp2;
  164:     char *tmp3;
  165:     
  166:     
  167:     char *deferrable_codptr;
  168:     char deferrable_code[512];
  169: 
  170:     char *ev_handlers;
  171:     
  172:     char *reeval_codptr;
  173:     char reeval_code[512];
  174:     
  175:     int i;
  176:     int j;
  177:     register int ch;
  178: 
  179:     int then_ctr = 0;
  180: 
  181: #if defined(HAVE_MWAPI_MOTIF)    
  182:     int syn_event_entry_nstx = 0;
  183:     int in_syn_event_loop = FALSE;
  184: #endif
  185:     
  186: #   ifdef DEBUG_NEWSTACK
  187:     int loop;
  188: #   endif
  189: 
  190:     vn = (char *) malloc ((STRLEN + 1) * sizeof (char));
  191:     an = (char *) malloc ((STRLEN + 1) * sizeof (char));
  192:     tmp = (char *) malloc ((STRLEN + 1) * sizeof (char));
  193:     tmp2 = (char *) malloc ((STRLEN + 1) * sizeof (char));
  194:     tmp3 = (char *) malloc ((STRLEN + 1) * sizeof (char));
  195: 
  196:     NULLPTRCHK(vn,"xecline");
  197:     NULLPTRCHK(an,"xecline");
  198:     NULLPTRCHK(tmp,"xecline");
  199:     NULLPTRCHK(tmp2,"xecline");
  200:     NULLPTRCHK(tmp3,"xecline");
  201: 
  202:     deferrable_codptr = deferrable_code;
  203: 
  204:     switch (typ) {
  205: 
  206:         case 0:
  207:             goto next_line;
  208:         
  209:         case 1:
  210:             goto restart;
  211: 
  212:         case 2:
  213:             goto err;
  214: 
  215:         case 3:
  216:             libcall = TRUE;
  217:             goto restart;
  218: 
  219:     }
  220: 
  221: next_line:          /* entry point for next command line */
  222: 
  223:     
  224:     job_set_status (pid, JSTAT_INTERPRETER);
  225:     
  226:     if (then_ctr > 0) {
  227:         test = nestlt[nstx];
  228:         level--;
  229:         then_ctr--;
  230:     }
  231:     
  232:     while ((roucur < rouend) && (ch = (*roucur++)) != TAB && ch != SP); /* skip label */
  233: 
  234:     if (roucur >= rouend) goto quit0;         /* end of routine implies QUIT */
  235: 
  236:     while ((ch = *roucur) == TAB || ch == SP) roucur++;
  237: 
  238:     i = 0;
  239:     if (ch == '.') {               /* get level count */
  240:         
  241:         do {
  242:             i++;
  243:             while ((ch = (*++roucur)) == SP || ch == TAB);
  244:         }
  245:         while (ch == '.');
  246:         
  247:     }
  248: 
  249:     if (i != level) {
  250: 
  251:         if (mcmnd == GOTO) {
  252:             merr_raise (M45);
  253:             goto err;
  254:         }
  255: 
  256:         if (i < level) {
  257:             goto quit0;
  258:         }
  259:         else {
  260:             roucur += stlen (roucur) + 2;
  261:             goto next_line;
  262:         }
  263:     }
  264: 
  265:     i = stcpy (code, roucur) + 1;    
  266:     code[i] = EOL;
  267:     roucur += i + 1;
  268:     codptr = code;
  269: 
  270: next_cmnd:          /* continue line entry point */
  271:     if (sigint_in_for) goto for_quit;
  272:     
  273:     if (forsw && (forpost[forx][0] != '\0')) {
  274: 
  275:         stcpy (reeval_code, code);
  276:         reeval_codptr = codptr;
  277: 
  278:         strcpy (code, forpost[forx]);
  279:         stcnv_c2m (code);
  280:         codptr = code;
  281: 
  282:         expr (STRING);
  283:         
  284:         if (merr () > OK) {
  285:             stcpy (code, reeval_code);
  286:             codptr = reeval_codptr;
  287: 
  288:             goto err;
  289:         }
  290: 
  291:         if (tvexpr (argptr) == FALSE) {
  292:             stcpy (code, reeval_code);
  293:             codptr = reeval_codptr;
  294:             
  295:             goto for_quit;
  296:         }
  297: 
  298:         stcpy (code, reeval_code);
  299:         codptr = reeval_codptr;
  300:         
  301:     }
  302:         
  303:     job_set_status (pid, JSTAT_INTERPRETER);
  304: 
  305:     if (evt_async_enabled == TRUE) {
  306: 
  307:         switch (pending_signal_type) {
  308: 
  309:             case SIGWINCH:
  310:                 evt_enqueue ("SIGWINCH", EVT_CLS_INTERRUPT, 1);
  311:                 break;
  312: 
  313:             case SIGINT:
  314:                 evt_enqueue ("SIGINT", EVT_CLS_INTERRUPT, 0);
  315:                 break;
  316: 
  317:             case SIGFPE:
  318:                 evt_enqueue ("SIGFPE", EVT_CLS_INTERRUPT, 0);
  319:                 break;
  320: 
  321:             case SIGQUIT:
  322:                 evt_enqueue ("SIGQUIT", EVT_CLS_INTERRUPT, 0);
  323:                 break;
  324: 
  325:         }
  326: 
  327:         pending_signal_type = -1;
  328:         
  329:         /* process async events */
  330:         ev_handlers = (char *) malloc (STRLEN * sizeof (char));
  331: 	NULLPTRCHK(ev_handlers,"xecline");
  332: 
  333: 
  334:         /* get a comma-delimited list of applicable handlers (e.g. ^HNDL1,^HNDL2,^HNDL3) */
  335:         ev_handlers[0] = NUL;
  336:         evt_depth = evt_get_handlers (ev_handlers);
  337: 
  338:         stcnv_c2m (ev_handlers);
  339:         stcpy (tmp3, ev_handlers);
  340:         free (ev_handlers);
  341: 
  342:         /* only execute event handlers if we have at least one such handler registered in ^$JOB($JOB,"EVENTS") */
  343:         if (evt_depth) {
  344:     
  345:             /* per X11-1998/28, async events are to be disabled during the execution of event handlers */
  346: 
  347:             /* TODO: this should be done by incrementing the event block counter
  348:                for all event types, or whatever the event extension says to do.
  349: 
  350:                In any event (rimshot here for the obvious pun), turning off all
  351:                event handlers this way is decidedly non-standard. Or non-what-might-
  352:                become the standard. Whatever. */
  353:             
  354:             evt_async_enabled = FALSE;
  355:             evt_async_initial = TRUE;
  356:             evt_async_restore = TRUE;
  357: 
  358:             goto evthandler;
  359:     
  360:         }
  361: 
  362:     }
  363: 
  364: 
  365:     if (merr () > OK) goto err;
  366: 
  367: next0:
  368: 
  369:     do {
  370:         if ((ch = *codptr) == EOL) {
  371:             if (forsw) goto for_end;
  372: 
  373:             goto next_line;
  374:         }
  375: 
  376:         codptr++;
  377:     }
  378:     while (ch == SP);
  379: 
  380:     /* decode command word */
  381: 
  382:     if (ch < 'A') {  /* Handle non-alpha first chars */
  383:         
  384:         if (ch == ';') {           /* COMMENT */
  385: 
  386:             ch = *(codptr++);
  387: 
  388:             if(ch == '%') {         /* DIRECTIVE */
  389: 
  390:                 int dir_pos = 0;
  391:                 int dir_wc = 0;
  392:                 char dir_words[20][255];
  393: 
  394:                 while((ch = *(codptr++)) != EOL) {
  395: 
  396:                     switch (ch) {
  397: 
  398: 
  399:                         case SP:
  400:                             
  401:                             dir_words[dir_wc][dir_pos] = NUL;
  402: 
  403:                             dir_wc++;
  404:                             dir_pos = 0;
  405: 
  406:                             break;
  407: 
  408: 
  409:                         default:
  410: 
  411:                             dir_words[dir_wc][dir_pos++] = ch;
  412: 
  413:                     }
  414: 
  415:                 }
  416: 
  417:                 dir_words[dir_wc][dir_pos] = NUL;
  418: 
  419:                 if (strcmp (dir_words[0], "DIALECT") == 0) {
  420:                     short rb_slot;
  421: 
  422:                     rb_slot = rbuf_slot_from_name (rou_name);
  423:                     
  424:                     if ((strcmp (dir_words[1], "STANDARD") == 0) ||
  425:                         (strcmp (dir_words[1], "MDS") == 0)) {
  426:                         rbuf_flags[rb_slot].standard = TRUE;
  427:                         rbuf_flags[rb_slot].dialect = D_MDS;
  428:                     }
  429:                     else if (strcmp (dir_words[1], "M77") == 0) {
  430:                         rbuf_flags[rb_slot].standard = TRUE;
  431:                         rbuf_flags[rb_slot].dialect = D_M77;
  432:                     }
  433:                     else if (strcmp (dir_words[1], "M84") == 0) {
  434:                         rbuf_flags[rb_slot].standard = TRUE;
  435:                         rbuf_flags[rb_slot].dialect = D_M84;
  436:                     }
  437:                     else if (strcmp (dir_words[1], "M90") == 0) {
  438:                         rbuf_flags[rb_slot].standard = TRUE;
  439:                         rbuf_flags[rb_slot].dialect = D_M90;
  440:                     }
  441:                     else if (strcmp (dir_words[1], "M95") == 0) {
  442:                         rbuf_flags[rb_slot].standard = TRUE;
  443:                         rbuf_flags[rb_slot].dialect = D_M95;
  444:                     }
  445:                     else if (strcmp (dir_words[1], "M5") == 0) {
  446:                         rbuf_flags[rb_slot].standard = TRUE;
  447:                         rbuf_flags[rb_slot].dialect = D_M5;
  448:                     }
  449:                     else if ((strcmp (dir_words[1], "FREEM") == 0) ||
  450:                              (strcmp (dir_words[1], "EXTENDED") == 0)) {
  451:                         rbuf_flags[rb_slot].standard = FALSE;
  452:                         rbuf_flags[rb_slot].dialect = D_FREEM;
  453:                     }
  454:                     else {
  455:                         merr_raise (CMMND);
  456:                         goto err;
  457:                     }
  458:                     goto skip_line;
  459:                 }
  460:                 else {
  461:                     goto skip_line;
  462:                 }
  463: 
  464:             }
  465: 
  466:             goto skip_line;
  467:         }
  468: 
  469:         if ((!is_standard ()) && (ch == '#')) {
  470:             goto skip_line;
  471:         }
  472: 
  473:         if ((is_standard ()) && (ch == '#')) {
  474:             merr_raise (NOSTAND);
  475:             goto err;
  476:         }
  477: 
  478:         if (ch == '@') {
  479:             if (!is_standard ()) {
  480:                 goto do_xecute;
  481:             }
  482:             else {
  483:                 merr_raise (NOSTAND);
  484:                 goto err;
  485:             }
  486:         }
  487:         
  488:         if (ch == '!') {           /* UNIXCALL */
  489: 
  490:             if (restricted_mode) {
  491:                 merr_raise (NOSTAND);
  492:                 goto err;
  493:             }
  494:             
  495:             /* don't catch child dies signal */
  496:             sig_attach (SIGUSR1, SIG_IGN);
  497: 
  498:             tmp2[stcpy (tmp2, codptr)] = NUL;
  499: 
  500:             if (demomode) fputc (d1char, stdout);
  501: 
  502:             if (tmp2[0] == '!') {
  503:                 
  504: 		uid_t suid;
  505: 		struct passwd *spw;
  506: 
  507: 		suid = geteuid ();
  508: 		spw = getpwuid (suid);
  509: 		
  510: 		set_io (UNIX);
  511: 
  512: 		fprintf (stderr, "Type Ctrl-D to exit from the shell\n");
  513: 
  514:                 if (strlen (spw->pw_shell)) {
  515: 		    zsystem = system (spw->pw_shell);
  516: 		}
  517: 		else {
  518: 		    zsystem = system ("/bin/sh");
  519: 		}
  520: 		
  521: 		set_io (MUMPS);
  522: 		sig_attach (SIGUSR1, &oncld);   /* restore handler */
  523: 		
  524:             }
  525:             else if (tmp2[0] == '<') {           /* call write output to %-array */
  526:                 
  527:                 FILE *pipdes;
  528:                 char key[STRLEN + 1 /*was 256 */ ];
  529:                 char data[STRLEN + 1 /*was 256 */ ];
  530:                 char data_kill[256];
  531:                 data_kill[255] = EOL;
  532:                 
  533:                 for (i = 0; i < STRLEN + 1; i++) vn[i] = EOL;
  534:                 
  535:                 snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid);
  536:                 ssvn (get_sym, key, vn);
  537: 
  538:                 if (vn[0] == '^') {
  539: 
  540:                     if (vn[1] == '$') {
  541:                         merr_raise (INVREF);
  542:                         goto err;
  543:                     }
  544:                     else {
  545:                         global (kill_sym, vn, data_kill);
  546:                     }
  547: 
  548:                 }
  549:                 else {
  550:                     symtab (kill_sym, vn, data);
  551:                 }
  552: 
  553:                 snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid);
  554:                 ssvn (get_sym, key, vn);
  555: 
  556:                 data[0] = '0';
  557:                 data[1] = EOL;
  558: 
  559:                 if (vn[0] == '^') {
  560: 
  561:                     if (vn[1] == '$') {
  562:                         merr_raise (INVREF);
  563:                         goto err;
  564:                     }
  565:                     else {
  566:                         global (set_sym, vn, data);
  567:                     }
  568: 
  569:                 }
  570:                 else {
  571:                     symtab (set_sym, vn, data);
  572:                 }
  573: 
  574: 		set_io (UNIX);
  575:                 if ((pipdes = popen (&tmp2[1], "r")) == NULL) {
  576:                     zsystem = 1;
  577:                 }
  578:                 else {
  579:                     int glvn_len = 0;
  580:                     
  581:                     while (fgets (data, STRLEN, pipdes)) {
  582:                         snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid);
  583:                         ssvn (get_sym, key, vn);
  584: 
  585:                         glvn_len = stlen (vn);                        
  586:                         stcpy (key, vn);
  587: 
  588:                         key[glvn_len] = DELIM;
  589: 
  590:                         if (vn[0] == '^') {
  591:                             
  592:                             if (vn[1] == '$') {
  593:                                 merr_raise (INVREF);
  594:                                 goto err;
  595:                             }
  596:                             else {
  597:                                 global (getinc, vn, &key[glvn_len + 1]);
  598:                             }
  599:                             
  600:                         }
  601:                         else {
  602:                             symtab (getinc, vn, &key[glvn_len + 1]);
  603:                         }
  604:                         
  605:                         i = strlen (data);
  606:                         
  607:                         data[i] = EOL;
  608: 
  609:                         if (i > 1 && data[i - 1] == LF) data[i - 1] = EOL;
  610: 
  611:                         if (vn[0] == '^') {
  612:                             
  613:                             if (vn[1] == '$') {
  614:                                 merr_raise (INVREF);
  615:                                 goto err;
  616:                             }
  617:                             else {
  618:                                 global (set_sym, key, data);
  619:                             }
  620:                             
  621:                         }
  622:                         else {
  623:                             symtab (set_sym, key, data);
  624:                         }
  625:                         
  626:                         if (merr () == STORE) break;
  627:                     }
  628: 
  629:                     pclose (pipdes);
  630:                     
  631:                     zsystem = 0;
  632:                 }
  633: 		set_io (MUMPS);
  634:             }      
  635:             else if (tmp2[0] == '>') {           /* call read input from %-array */
  636:                 FILE *pipdes;
  637:                 char key[STRLEN + 1 /*was 256 */ ];
  638:                 char data[STRLEN + 1 /*was 256 */ ];
  639:                 int i, k, l;
  640:                 
  641:                 for (i = 0; i < STRLEN + 1; i++) vn[i] = EOL;
  642:                 
  643:                 snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid);
  644:                 ssvn (get_sym, key, vn);
  645: 
  646:                 if (vn[0] == '^') {
  647: 
  648:                     if (vn[1] == '$') {
  649:                         merr_raise (INVREF);
  650:                         goto err;
  651:                     }
  652:                     else {
  653:                         global (get_sym, vn, data);
  654:                     }
  655: 
  656:                 }
  657:                 else {
  658:                     symtab (get_sym, vn, data);
  659:                 }
  660: 
  661:                 merr_clear ();
  662:                 k = intexpr (data);
  663: 
  664: 		set_io (UNIX);
  665:                 if (k < 1 || (pipdes = popen (&tmp2[1], "w")) == NULL) {
  666:                     zsystem = 1;
  667:                 }
  668:                 else {
  669:                     int glvn_len = 0;
  670:                     
  671:                     for (i = 1; i <= k; i++) {
  672:                         snprintf (key, 255, "^$JOB\202%d\202PIPE_GLVN\201", pid);
  673:                         ssvn (get_sym, key, vn);
  674: 
  675:                         glvn_len = stlen (vn);                        
  676:                         stcpy (key, vn);
  677: 
  678:                         key[glvn_len] = DELIM;
  679:                         
  680:                         intstr (&key[glvn_len + 1], i);
  681: 
  682:                         if (vn[0] == '^') {
  683: 
  684:                             if (vn[1] == '$') {
  685:                                 merr_raise (INVREF);
  686:                                 goto err;
  687:                             }
  688:                             else {
  689:                                 global (get_sym, key, data);
  690:                             }
  691:                             
  692:                         }
  693:                         else {                        
  694:                             symtab (get_sym, key, data);
  695:                         }
  696: 
  697:                         l = stlen (data);
  698:                         
  699:                         data[l++] = LF;
  700:                         data[l] = NUL;
  701: 
  702:                         fputs (data, pipdes);
  703:                     }
  704:                     
  705:                     pclose (pipdes);
  706: 
  707:                     zsystem = 0;
  708:                     merr_clear ();
  709:                 }
  710: 		set_io (MUMPS);
  711: 		
  712:             }     
  713:             else {
  714: 		set_io (UNIX);
  715:                 zsystem = system (tmp2);
  716: 		set_io (MUMPS);
  717:             }
  718: 
  719:             if (demomode) fputc (d1char, stdout);
  720: 
  721:             sig_attach (SIGUSR1, &oncld);   /* restore handler */
  722: 	    
  723: 
  724:             if (merr () == STORE) {
  725:                 zsystem = 1;
  726:                 goto err;
  727:             }
  728: 
  729:             goto skip_line;
  730:         }
  731: 
  732:         merr_raise (CMMND);
  733:         goto err;
  734:     } /* END handling of non-alpha first chars */
  735: 
  736: 
  737:     mcmnd = ch | 0140;      /* uppercase to lower case */
  738: 
  739:     i = 1;
  740: 
  741:     while ((ch = (*codptr)) != SP && ch != ':' && ch != EOL) {
  742:         tmp3[++i] = ch | 0140;
  743:         codptr++;
  744:     }
  745: 
  746:     j = i;
  747: 
  748:     if (j > 1) {
  749:         merr_raise (mcmd_tokenize (&ra, tmp3, deferrable_codptr, deferrable_code, &j));
  750:         MRESCHECK(ra);
  751:     }
  752: 
  753: 
  754:     if (*codptr == ':') {               
  755:         /* handle postconditional */
  756:         
  757:         if (mcmnd == FOR) {
  758:             char *savcp = codptr;
  759: 
  760:             codptr++;
  761:             i = 0;
  762:             while ((forpost[forx + 1][i++] = *(codptr++)) != SP);
  763: 
  764:             forpost[forx + 1][i - 1] = '\0';
  765:         
  766:             codptr = savcp;
  767:         }
  768:         
  769: 
  770:         /* postcond after FOR,IF,ELSE not allowed in dialects other than D_FREEM  */ 
  771: 
  772:         
  773:         if ((rtn_dialect () != D_FREEM) && (mcmnd == FOR || mcmnd == IF || mcmnd == ELSE)) {
  774:             merr_raise (NOSTAND);
  775:             goto err;
  776:         }       
  777: 
  778:         codptr++;
  779: 
  780:         expr (STRING);
  781: 
  782:         if (merr () > OK) goto err;
  783: 
  784:         ch = *codptr;
  785: 
  786:         if (ch != SP && ch != EOL) {
  787:             merr_raise (SPACER);
  788:             goto err;
  789:         }
  790: 
  791:         if (tvexpr (argptr) == FALSE) {           /* skip arguments */
  792: 
  793:             if ((mcmnd == IF) || (mcmnd == THEN) || (mcmnd == ELSE) || (mcmnd == FOR)) {
  794:                 mcmnd = 0;
  795:                 goto skip_line;
  796:             }
  797:             
  798:             mcmnd = 0;      /* avoid false LEVEL error */            
  799:             
  800:             for (;;) {
  801:                 if (ch == EOL) goto skip_line;               
  802:                 if ((ch = *++codptr) == SP) goto next_cmnd;
  803:                 if (ch != '"') continue;
  804: 
  805:                 while (*codptr++ != EOL) {
  806:                     if (*codptr != ch) continue;
  807:                     if (*++codptr != ch) break;
  808:                 }
  809: 
  810:                 if (--codptr == code) goto err;
  811:             }
  812:         }
  813: 
  814:     }
  815: 
  816:     if (*codptr != EOL) {               /* beware argumentless cmnds at end of line */
  817:         codptr++;           /* entry for next argument in list */
  818: 
  819: again:
  820:         while (*codptr == '@') {           /* handle indirection */
  821:             
  822:             stcpy (tmp, codptr++);  /* save code to restore on nameind */
  823:             expr (ARGIND);
  824: 
  825:             if (merr () > OK) goto err;
  826: 
  827:             if (((ch = (*codptr)) != SP && ch != EOL && ch != ',' && ch != ':' && ch != '=') || (ch == '@' && *(codptr + 1) == '(')) {
  828:                 stcpy (code, tmp);  /* restore code on nameind */
  829:                 codptr = code;
  830: 
  831:                 break;
  832:             }
  833:             else {
  834:                 stcpy (argptr + stlen (argptr), codptr);
  835:                 stcpy (code, argptr);
  836:                 
  837:                 codptr = code;
  838:             }
  839:         }
  840:     }
  841: 
  842:     switch (mcmnd) {
  843: 
  844:         case MAP:
  845:             merr_raise (cmd_map (&ra));
  846:             MRESCHECK(ra);
  847:             break;
  848:             
  849:         case UNMAP:
  850:             merr_raise (cmd_unmap (&ra));
  851:             MRESCHECK(ra);
  852:             break;
  853:         
  854:         case THEN:
  855:             merr_raise (cmd_then (&ra, &then_ctr));
  856:             MRESCHECK(ra);
  857:             break;
  858:             
  859:         case THROW:
  860:             merr_raise (cmd_throw (&ra));
  861:             MRESCHECK(ra);
  862:             break;
  863:             
  864: 	case CONST:            
  865:             merr_raise (cmd_const (&ra));
  866:             MRESCHECK(ra);
  867: 	    break;
  868: 	    
  869:         case KVALUE:
  870:             merr_raise (cmd_kvalue (&ra));
  871:             MRESCHECK(ra);
  872:             break;
  873: 
  874:         case KSUBSC:
  875:             merr_raise (cmd_ksubscripts (&ra));
  876:             MRESCHECK(ra);
  877:             break;
  878: 
  879:         case TSTART:
  880:             merr_raise (cmd_tstart (&ra));
  881:             MRESCHECK(ra);
  882:             break;
  883:             
  884:         case TCOMMIT:
  885:             merr_raise (cmd_tcommit (&ra));
  886:             MRESCHECK(ra);
  887:             break;
  888:             
  889:         case TROLLBACK:
  890:             merr_raise (cmd_trollback (&ra));
  891:             MRESCHECK(ra);
  892:             break;
  893:             
  894:         case SET:
  895: 
  896: set0:
  897:             if ((ch = (*codptr)) >= 'A') {           /* no set$piece nor multiset */
  898:                 short setref = FALSE;
  899:                 short stclass = SC_UNCHANGED;
  900:                 
  901:                 expr (NAME);
  902:                 if (merr () > OK) break;               
  903:                 stcpy (vn, varnam);
  904: 
  905:                 if (isalpha (vn[0]) && *(codptr + 1) == ':') {
  906:                     char sc_string[255];
  907:                     register int sci;
  908:                     
  909:                     codptr += 2;
  910:                     expr (NAME);
  911: 
  912:                     stcpy (sc_string, varnam);
  913:                     for (i = 0; i < stlen (sc_string); i++) {
  914:                         sc_string[i] = toupper (sc_string[i]);
  915:                     }
  916: 
  917:                     stcnv_m2c (sc_string);
  918:                     if (strcmp (sc_string, "PRIVATE") == 0) {
  919:                         stclass = SC_PRIVATE;
  920:                     }
  921:                     else if (strcmp (sc_string, "PUBLIC") == 0) {
  922:                         stclass = SC_PUBLIC;
  923:                     }
  924:                     else {
  925:                         merr_raise (OBJACINVALID);
  926:                         break;
  927:                     }
  928:                 }
  929: 
  930:                 if ((*++codptr != '=') || (*(codptr + 1) == '=')) {
  931:                     ch = *codptr;
  932:                     
  933:                     /* double char symbol ** (power) is encoded by ' ' */
  934:                     if (ch == '*' && *(codptr + 1) == ch) {
  935:                         codptr++;
  936:                         ch = ' ';
  937:                     }
  938: 
  939:                     /* negated boolean operator */
  940:                     else if ((ch == '\'') && (*(codptr + 2) == '=')) ch = SETBIT (*++codptr);
  941: 
  942:                     if (*++codptr != '=') {
  943: 
  944: /* SET A++ or SET A-- equivalent to SET A+=1 SET A-=1 currently disabled */
  945: //#ifdef NEVER
  946:                         if ((ch == '+' || ch == '-') && ch == *codptr) {
  947:                             codptr++;
  948:                             setop = ch;
  949:                             argptr[0] = '1';
  950:                             argptr[1] = EOL;
  951:                             
  952:                             goto set2;
  953:                         }
  954: //#endif /* NEVER */
  955: 
  956:                         merr_raise (ASSIGNER);
  957:                         break;
  958:                     }
  959: 
  960:                     setop = ch;
  961:                 }
  962: 
  963:                 codptr++;
  964: 
  965:                 ch = *codptr;               
  966: 
  967:                 if (ch == '.') {                    
  968:                     setref = TRUE;
  969:                     codptr++;
  970:                     expr (NAME);
  971:                 }
  972:                 else {                
  973:                     expr (STRING);
  974:                 }
  975: 
  976:                 
  977:                 if (merr () > OK) break;
  978: 
  979: 
  980: set2:
  981: 
  982:                 if (vn[0] == '^') {
  983: 
  984:                     stcpy (an, argptr);
  985:                     
  986:                     if (setref == TRUE) {
  987:                         merr_raise (INVREF);
  988:                         goto err;
  989:                     }
  990:                     
  991:                     if (vn[1] == '$') {
  992:                         ssvn (set_sym, vn, an);
  993:                     }
  994:                     else {
  995:                         global (set_sym, vn, an);
  996:                     }
  997: 
  998:                 }
  999:                 else {
 1000:                     stcpy (an, argptr);
 1001:                     
 1002:                     if (setref == TRUE) {
 1003:                         symtab (new_sym, vn, "");
 1004:                         symtab (m_alias, vn, varnam);
 1005:                         codptr++;
 1006:                     }
 1007:                     else {
 1008:                         if (new_object == FALSE) {
 1009:                             symtab (set_sym, vn, an);
 1010:                             switch (stclass) {
 1011:                                 
 1012:                                 case SC_PUBLIC:
 1013:                                     obj_set_field_public (vn);
 1014:                                     break;
 1015: 
 1016:                                 case SC_PRIVATE:
 1017:                                     obj_set_field_private (vn);
 1018:                                     break;
 1019: 
 1020:                             }
 1021:                         }
 1022:                     }
 1023:                 }
 1024:                 
 1025:                 if (merr () > OK) {
 1026:                     stcpy (varerr, vn);
 1027:                     break;
 1028:                 }
 1029: 
 1030:                 if (((new_and_set == TRUE) || (new_object == TRUE)) && (*codptr != SP) && (*codptr != EOL)) {
 1031:                     new_and_set = FALSE;
 1032:                     new_object = FALSE;
 1033:                     
 1034:                     merr_raise (INEWMUL);
 1035:                     goto err;
 1036:                 }
 1037: 
 1038:                 if (new_and_set == TRUE) new_and_set = FALSE;
 1039:                 if (new_object == TRUE) new_object = FALSE;
 1040: set1:
 1041:                 if (*codptr != ',') break;
 1042: 
 1043:                 if (*++codptr == '@') goto again;
 1044: 
 1045:                 goto set0;
 1046:             }
 1047: 
 1048:             /****** special SET syntax: multiple SET, set$piece, special variables */
 1049:             {
 1050:                 char multiset, vnset[256];  /* multiset variables */
 1051:                 long arg3, arg4;    /* 3rd,4th arg in set$piece */
 1052: 
 1053:                 if ((multiset = (ch == '('))) {
 1054:                     vnset[0] = EOL;
 1055:                     codptr++;
 1056:                 }
 1057: 
 1058: set:
 1059:                 if (*codptr == '$' && (*(codptr + 1) | 0140) == 'p') {           /* set$piece */
 1060: 
 1061:                     if (multiset) {
 1062:                         merr_raise (INVREF);
 1063:                         goto err;
 1064:                     }
 1065:         
 1066:                     setpiece = 'p';
 1067: 
 1068:                     while (*++codptr != '(') {
 1069:                         
 1070:                         if (*codptr == EOL) {
 1071:                             merr_raise (INVREF);
 1072:                             goto err;
 1073:                         }
 1074:                     
 1075:                     }
 1076:                     
 1077:                     codptr++;
 1078:                     
 1079:                     expr (NAME);
 1080: 
 1081:                     if (merr () > OK) goto err;
 1082: 
 1083:                     stcpy (vn, varnam);
 1084:                     
 1085:                     codptr++;
 1086: 
 1087:                     if (*codptr++ != ',') {
 1088:                         merr_raise (COMMAER);
 1089:                         goto err;
 1090:                     }
 1091: 
 1092:                     expr (STRING);                    
 1093:                     
 1094:                     if (merr () > OK) goto err;
 1095: 
 1096:                     stcpy (tmp2, argptr);
 1097: 
 1098:                     if (*codptr != ')') {
 1099:                     
 1100:                         codptr++;
 1101: 
 1102:                         expr (STRING);
 1103: 
 1104:                         if (merr () > OK) goto err;
 1105: 
 1106:                         arg3 = intexpr (argptr);
 1107: 
 1108:                         if (merr () == MXNUM) {
 1109:                             arg3 = 256;
 1110:                             merr_clear ();
 1111:                         }
 1112:                     
 1113:                     }
 1114:                     else {
 1115:                         arg3 = 1;
 1116:                     }
 1117: 
 1118:                     if (*codptr != ')') {
 1119:                     
 1120:                         codptr++;
 1121: 
 1122:                         expr (STRING);
 1123: 
 1124:                         if (merr () > OK) goto err;
 1125: 
 1126:                         if (*codptr != ')') {
 1127:                             merr_raise (BRAER);
 1128:                             goto err;
 1129:                         }
 1130: 
 1131:                         arg4 = intexpr (argptr);
 1132: 
 1133:                         if (merr () == MXNUM) {
 1134:                             arg4 = 256;
 1135:                             merr_clear ();
 1136:                         }
 1137:                     
 1138:                     }
 1139:                     else {
 1140:                         arg4 = arg3;
 1141:                     }
 1142:                 } /* set$piece */
 1143:                 else if (*codptr == '$' && (*(codptr + 1) | 0140) == 'q' && (*(codptr + 2) | 0140) == 's') { /* TODO: verify this works (jpw) was (*codptr == '$q'...*/
 1144:                     /*SET $QSUBSCRIPT */
 1145: 
 1146:                     if (multiset) {
 1147:                         merr_raise (INVREF);
 1148:                         goto err;
 1149:                     }
 1150: 
 1151:                     setpiece = 'q';
 1152: 
 1153:                     while (*++codptr != '(') {
 1154:                         
 1155:                         if (*codptr == EOL) {
 1156:                             merr_raise (INVREF);
 1157:                             goto err;
 1158:                         }
 1159: 
 1160:                     }
 1161:                     
 1162:                     codptr++;
 1163: 
 1164:                     expr (NAME);
 1165: 
 1166:                     if (merr () > OK) goto err;
 1167: 
 1168:                     stcpy (vn, varnam);
 1169: 
 1170:                     if (*++codptr == ',') {
 1171:                         codptr++;
 1172: 
 1173:                         expr (STRING);
 1174:                         
 1175:                         if (merr () > OK) goto err;
 1176: 
 1177:                         stcpy (tmp2, argptr);
 1178:                     }
 1179: 
 1180:                     if (*codptr != ')') {
 1181:                         merr_raise (BRAER);
 1182:                         goto err;
 1183:                     }
 1184:                 
 1185:                 }
 1186:                 else if (*codptr == '$' &&
 1187:                          (*(codptr + 1) | 0140) == 'd' &&
 1188:                          (*(codptr + 2) | 0140) == 'i') {
 1189: 
 1190:                     short rb_slot;
 1191: 
 1192:                     rb_slot = rbuf_slot_from_name (rou_name);
 1193:                     
 1194:                     while ((*(++codptr)) != '=');
 1195: 
 1196:                     codptr++;
 1197: 
 1198:                     expr (STRING);
 1199: 
 1200:                     stcnv_m2c (argptr);
 1201:                     
 1202:                     if ((strcmp (argptr, "STANDARD") == 0) ||
 1203:                         (strcmp (argptr, "MDS") == 0)) {
 1204:                         rbuf_flags[rb_slot].standard = TRUE;
 1205:                         rbuf_flags[rb_slot].dialect = D_MDS;
 1206:                     }
 1207:                     else if (strcmp (argptr, "M77") == 0) {
 1208:                         rbuf_flags[rb_slot].standard = TRUE;
 1209:                         rbuf_flags[rb_slot].dialect = D_M77;
 1210:                     } 
 1211:                     else if (strcmp (argptr, "M84") == 0) {
 1212:                         rbuf_flags[rb_slot].standard = TRUE;
 1213:                         rbuf_flags[rb_slot].dialect = D_M84;
 1214:                     } 
 1215:                     else if (strcmp (argptr, "M90") == 0) {
 1216:                         rbuf_flags[rb_slot].standard = TRUE;
 1217:                         rbuf_flags[rb_slot].dialect = D_M90;
 1218:                     } 
 1219:                     else if (strcmp (argptr, "M95") == 0) {
 1220:                         rbuf_flags[rb_slot].standard = TRUE;
 1221:                         rbuf_flags[rb_slot].dialect = D_M95;
 1222:                     } 
 1223:                     else if (strcmp (argptr, "M5") == 0) {
 1224:                         rbuf_flags[rb_slot].standard = TRUE;
 1225:                         rbuf_flags[rb_slot].dialect = D_M5;
 1226:                     }
 1227:                     else if ((strcmp (argptr, "FREEM") == 0) ||
 1228:                              (strcmp (argptr, "EXTENDED") == 0)) {
 1229:                         rbuf_flags[rb_slot].standard = TRUE;
 1230:                         rbuf_flags[rb_slot].dialect = D_FREEM;
 1231:                     }
 1232:                     else {
 1233:                         merr_raise (CMMND);
 1234:                         goto err;
 1235:                     }
 1236: 
 1237:                     goto s_end;
 1238: 
 1239:                 }
 1240:                 else if (*codptr == '$' && (*(codptr + 1) | 0140) == 'e' && (*(codptr + 2) | 0140) != 't' && (*(codptr + 2) | 0140) != 'c') {
 1241: 
 1242:                     /* set $extract */
 1243:                     if (multiset) {
 1244:                         merr_raise (INVREF);
 1245:                         goto err;
 1246:                     }
 1247: 
 1248:                     setpiece = 'e';
 1249:                     
 1250:                     while (*++codptr != '(') {
 1251:                         
 1252:                         if (*codptr == EOL) {
 1253:                             merr_raise (INVREF);
 1254:                             goto err;
 1255:                         }
 1256: 
 1257:                     }
 1258: 
 1259:                     codptr++;
 1260: 
 1261:                     expr (NAME);
 1262: 
 1263:                     if (merr () > OK) goto err;
 1264: 
 1265:                     stcpy (vn, varnam);
 1266: 
 1267:                     codptr++;
 1268: 
 1269:                     if (*codptr != ')') {
 1270:                         codptr++;
 1271: 
 1272:                         expr (STRING);
 1273:                         
 1274:                         if (merr () > OK) goto err;
 1275: 
 1276:                         arg3 = intexpr (argptr);
 1277:                         
 1278:                         if (merr () == MXNUM) {
 1279:                             arg3 = 256;
 1280:                             merr_clear ();
 1281:                         }
 1282:                     }
 1283:                     else {
 1284:                         arg3 = 1;
 1285:                     }
 1286: 
 1287:                     if (*codptr != ')') {
 1288:                         codptr++;
 1289: 
 1290:                         expr (STRING);
 1291:                         
 1292:                         if (merr () > OK) goto err;
 1293: 
 1294:                         if (*codptr != ')') {
 1295:                             merr_raise (BRAER);
 1296:                             goto err;
 1297:                         }
 1298: 
 1299:                         arg4 = intexpr (argptr);
 1300: 
 1301:                         if (merr () == MXNUM) {
 1302:                             arg4 = 256;
 1303:                             merr_clear ();
 1304:                         }
 1305: 
 1306:                     }
 1307:                     else {
 1308:                         arg4 = arg3;
 1309:                     }
 1310: 
 1311:                 }
 1312:                 else if (*codptr == '$' && (*(codptr + 1) | 0140) == 'e' && (*(codptr + 2) | 0140) == 'c') {
 1313:                     /* set $ecode */
 1314: 
 1315:                     if (multiset) {
 1316:                         merr_raise (INVREF);
 1317:                         goto err;
 1318:                     }
 1319: 
 1320:                     while ((*(++codptr)) != '=');
 1321: 
 1322:                     codptr++;
 1323: 
 1324:                     expr (STRING);
 1325:                     
 1326:                     if (merr () > OK) goto err;
 1327: 
 1328:                     switch (argptr[0]) {
 1329:                         
 1330:                         case ',':
 1331:                             
 1332:                             switch (argptr[1]) {
 1333: 
 1334:                                 case ',':
 1335:                                     merr_raise (M101);
 1336:                                     goto err;                                 
 1337:                                 
 1338:                             }
 1339:                             
 1340:                             break;
 1341: 
 1342:                     }
 1343:                     
 1344:                     merr_raise (merr_set_ecode (argptr));
 1345: 
 1346: #if 0
 1347:                     set_io (UNIX);
 1348:                     stcnv_m2c (ecode);
 1349:                     stcnv_m2c (etrap);
 1350:                     printf ("\n\n*** IN SET $ECODE: ecode = '%s' etrap = '%s'\n", ecode, etrap);
 1351:                     stcnv_c2m (etrap);
 1352:                     stcnv_c2m (ecode);
 1353:                     set_io (MUMPS);
 1354: #endif
 1355: 
 1356:                     if (merr () > OK) goto err;
 1357: 
 1358:                     goto s_end;
 1359: 
 1360:                 }
 1361:                 else if (*codptr == '$' && (*(codptr + 1) | 0140) == 'e' && (*(codptr + 2) | 0140) == 't') {
 1362:                     /* set $etrap */
 1363: 
 1364:                     if (multiset) {
 1365:                         merr_raise (INVREF);
 1366:                         goto err;
 1367:                     }
 1368: 
 1369:                     while ((*(++codptr)) != '=');
 1370: 
 1371:                     codptr++;
 1372: 
 1373:                     expr (STRING);
 1374: 
 1375:                     if (merr () > OK) goto err;
 1376: 
 1377:                     stcpy (etrap, argptr);
 1378: 
 1379: #if 0
 1380:                     set_io (UNIX);
 1381:                     stcnv_m2c (ecode);
 1382:                     stcnv_m2c (etrap);
 1383:                     printf ("\n\n***IN SET $ETRAP: ecode = '%s' etrap = '%s'\n", ecode, etrap);
 1384:                     stcnv_c2m (etrap);
 1385:                     stcnv_c2m (ecode);
 1386:                     set_io (MUMPS);
 1387: #endif
 1388: 
 1389:                     goto s_end;
 1390: 
 1391:                 }
 1392:                 else if (*codptr == '$' && (*(codptr + 1) | 0140) == 'g' && cset) {           /* set$get */
 1393:                     
 1394:                     if (multiset) {
 1395:                         merr_raise (INVREF);
 1396:                         goto err;
 1397:                     }
 1398: 
 1399:                     setpiece = 'g';
 1400: 
 1401:                     while (*++codptr != '(') {
 1402:                         
 1403:                         if (*codptr == EOL) {
 1404:                             merr_raise (INVREF);
 1405:                             goto err;
 1406:                         }
 1407:                     }
 1408: 
 1409:                     codptr++;
 1410: 
 1411:                     expr (NAME);
 1412: 
 1413:                     if (merr () > OK) goto err;
 1414: 
 1415:                     stcpy (vn, varnam);
 1416: 
 1417:                     if (*++codptr == ',') {
 1418:                         codptr++;
 1419: 
 1420:                         expr (STRING);
 1421: 
 1422:                         if (merr () > OK) goto err;
 1423: 
 1424:                         stcpy (tmp2, argptr);
 1425:                     }
 1426:                     else {
 1427:                         tmp2[0] = EOL;
 1428:                     }
 1429: 
 1430:                     if (*codptr != ')') {
 1431:                         merr_raise (BRAER);
 1432:                         goto err;
 1433:                     }
 1434:                 }
 1435:                 else {
 1436:                     if (*codptr == '$') {
 1437:                         codptr++;
 1438: 
 1439:                         expr (NAME);
 1440: 
 1441:                         if (merr () > OK) goto err;
 1442: 
 1443:                         stcpy (tmp, varnam);
 1444: 
 1445:                         varnam[0] = '$';
 1446: 
 1447:                         stcpy (&varnam[1], tmp);
 1448:                         
 1449:                         i = 0;
 1450:                         while ((ch = varnam[++i]) != EOL) { 
 1451:                             if (ch >= 'A' && ch <= 'Z') {
 1452:                                 varnam[i] |= 0140;  /*to lowercase */
 1453:                             }
 1454:                         }
 1455:                     }
 1456:                     else {
 1457:                         expr (NAME);
 1458: 
 1459:                         if (merr () > OK) goto err;
 1460:                     }
 1461: 
 1462:                     stcpy (vn, varnam);
 1463:                 }
 1464: 
 1465:                 if (multiset) {
 1466:                     vnset[i = stlen (vnset)] = SOH;
 1467:                     
 1468:                     stcpy (&vnset[++i], vn);
 1469: 
 1470:                     if (*++codptr == ',') {
 1471:                         codptr++;
 1472:                         goto set;
 1473:                     }
 1474: 
 1475:                     if (*codptr != ')') {
 1476:                         merr_raise (COMMAER);
 1477:                         goto err;
 1478:                     }
 1479:                 }
 1480: 
 1481:                 if (*++codptr != '=') {
 1482:                     ch = *codptr;
 1483: 
 1484:                     if (!cset || *++codptr != '=' || multiset || setpiece || varnam[0] == '$') {
 1485:                         merr_raise (ASSIGNER);
 1486:                         break;
 1487:                     }
 1488: 
 1489:                     setop = ch;
 1490:                 }
 1491: 
 1492:                 codptr++;
 1493: 
 1494:                 expr (STRING);
 1495: 
 1496:                 if (merr () > OK) goto err;
 1497: 
 1498:                 if (multiset)
 1499: multi:
 1500:                 {
 1501:                     i = 0;
 1502:                     while (vnset[i] == SOH) i++;
 1503: 
 1504:                     j = 0;
 1505:                     while ((vn[j] = vnset[i]) != SOH && vnset[i] != EOL) {
 1506:                         vnset[i++] = SOH;
 1507:                         j++;
 1508:                     }
 1509: 
 1510:                     vn[j] = EOL;
 1511: 
 1512:                     if (j == 0) goto s_end;
 1513:                 }
 1514: 
 1515:                 if (setpiece == 'p') {
 1516:                     long m, n;
 1517: 
 1518:                     if (arg4 < arg3 || arg4 < 1) {
 1519:                         setpiece = FALSE;
 1520:                         break;
 1521:                     }
 1522: 
 1523:                     if (arg3 <= 0) arg3 = 1;
 1524:                     
 1525:                     if (vn[0] == '^') {
 1526:                         if (vn[1] == '$') {
 1527:                             ssvn (get_sym, vn, tmp3);
 1528:                         }
 1529:                         else {
 1530:                             global (get_sym, vn, tmp3);
 1531:                         }
 1532:                     }
 1533:                     else {
 1534:                         symtab (get_sym, vn, tmp3);
 1535:                     }
 1536: 
 1537: 
 1538:                     if (merr () == UNDEF || merr () == M6 || merr () == M7) {
 1539:                         tmp3[0] = EOL;
 1540:                         merr_clear ();
 1541:                     }
 1542:                     else if (merr () != OK) {
 1543:                         stcpy (varerr, vn);
 1544:                     }
 1545: 
 1546:                     ch = 0;
 1547:                     m = 0;
 1548:                     n = 0;
 1549: 
 1550:                     j = stlen (tmp2);
 1551: 
 1552:                     while (n < arg3 - 1) {
 1553:                         
 1554:                         if ((ch = find (&tmp3[m], tmp2)) <= 0) {
 1555: 
 1556:                             while (++n < arg3) {
 1557:                                 if (stcat (tmp3, tmp2) == 0) {
 1558:                                     merr_raise (M75);
 1559:                                     goto err;
 1560:                                 }
 1561:                             }
 1562: 
 1563:                             arg3 = arg4 = stlen (tmp3);
 1564: 
 1565:                             goto set10;
 1566:                         }
 1567: 
 1568:                         n++;
 1569:                         m += j + ch - 1;
 1570:                     }
 1571: 
 1572:                     if (arg3 > 1) {
 1573:                         arg3 = m;
 1574:                     }
 1575:                     else {
 1576:                         arg3 = 0;
 1577:                     }
 1578: 
 1579:                     while (n++ < arg4) {
 1580:                         
 1581:                         if ((ch = find (&tmp3[m], tmp2)) <= 0) {
 1582:                             arg4 = stlen (tmp3);
 1583: 
 1584:                             goto set10;
 1585:                         }
 1586: 
 1587:                         m += j + ch - 1;
 1588:                     }
 1589: 
 1590:                     arg4 = m - j;
 1591: 
 1592: set10:
 1593: 
 1594:                     stcpy0 (tmp2, tmp3, (long) arg3);
 1595:                     
 1596:                     tmp2[arg3] = EOL;
 1597: 
 1598:                     if (stcat (tmp2, argptr) == 0) {
 1599:                         merr_raise (M75);
 1600:                         goto err;
 1601:                     }
 1602: 
 1603:                     if (stcat (tmp2, &tmp3[arg4]) == 0) {
 1604:                         merr_raise (M56); //JPW
 1605:                         goto err;
 1606:                     }
 1607: 
 1608:                     stcpy (argptr, tmp2);
 1609:                     
 1610:                     setpiece = FALSE;
 1611:                 }
 1612:                 else if (setpiece == 'q') {           /* SET$QSUBSCRIPT */
 1613:                     
 1614:                     setpiece = FALSE;
 1615:                     
 1616:                     if (vn[0] == '^') {
 1617:                         if (vn[1] == '$') {
 1618:                             ssvn (get_sym, vn, tmp3);
 1619:                         }
 1620:                         else {
 1621:                             global (get_sym, vn, tmp3);
 1622:                         }                        
 1623:                     }
 1624:                     else {
 1625:                         symtab (get_sym, vn, tmp3);
 1626:                     }
 1627: 
 1628:                     if (merr () == UNDEF || merr () == M6 || merr () == M7) {
 1629:                         tmp3[0] = EOL;
 1630:                         merr_clear ();
 1631:                     }
 1632:                     else if (merr () != OK) {
 1633:                         stcpy (varerr, vn);
 1634:                     }
 1635: 
 1636:                     if (merr () == OK) {
 1637:                         /* 2nd $QS argument */
 1638:                         if ((arg4 = intexpr (tmp2)) < -1) merr_raise (ARGER);
 1639:                         if (merr () != OK) break;
 1640: 
 1641:                         /* special if source is empty */
 1642:                         if (tmp3[0] != EOL || (arg4 != 0)) {
 1643:                             /* special: Set env to empty: no |""| */
 1644:                             if ((arg4 == -1) && (*argptr == EOL)) {
 1645:                                 tmp2[0] = EOL;
 1646:                             }                        
 1647:                             else if ((arg4 != 0) && !znamenumeric (argptr)) {
 1648:                                 /* put replacement string in tmp2 with     */
 1649:                                 /* quotes around env or subscript, unless numeric */
 1650:                                 i = 0;
 1651:                                 j = -1;
 1652:                                 tmp2[0] = '"';
 1653: 
 1654:                                 while ((tmp2[++i] = argptr[++j]) != EOL) {
 1655:                                     if (tmp2[i] == '"') tmp2[++i] = '"';
 1656: 
 1657:                                     if (i >= (STRLEN - 2)) {
 1658:                                         merr_raise (M75);
 1659:                                         break;
 1660:                                     }
 1661:                                 }
 1662: 
 1663:                                 tmp2[i] = '"';
 1664:                                 tmp2[++i] = EOL;
 1665:                             }
 1666:                             else {
 1667:                                 stcpy (tmp2, argptr);
 1668:                             }
 1669: 
 1670:                             /* source is tmp3, dest is argptr, replacement is tmp2 */
 1671:                             {
 1672:                                 int ch, cpflag, quote, piececounter;
 1673:                                 
 1674:                                 piececounter = 0;
 1675:                                 i = 0;
 1676:                                 j = 0;
 1677:                                 quote = FALSE;
 1678:                                 cpflag = FALSE;
 1679:                                 
 1680:                                 /* if source has no env, process right now */
 1681:                                 if ((arg4 == -1) && (tmp3[tmp3[0] == '^'] != '|') && tmp2[0] != EOL) {
 1682:                                     
 1683:                                     if (tmp3[0] == '^') {
 1684:                                         argptr[j++] = '^';
 1685:                                         i = 1;
 1686:                                     }
 1687:                                     
 1688:                                     argptr[j++] = '|';
 1689:                                     ch = 0;
 1690:                                     
 1691:                                     while ((argptr[j] = tmp2[ch++]) != EOL) j++;
 1692: 
 1693:                                     argptr[j++] = '|';
 1694: 
 1695:                                 }
 1696:                                 else if (arg4 == 0) {   /* '^'+name may be separated by env */                                
 1697:                                     if (tmp2[0] == '^') argptr[j++] = '^';
 1698:                                     if (tmp3[0] == '^') i++;
 1699:                                 }
 1700: 
 1701:                                 while ((ch = tmp3[i++]) != EOL) {
 1702:                                     if (ch == '"') quote = !quote;
 1703:                                     
 1704:                                     if (!quote) {
 1705:                                         
 1706:                                         if (ch == ',') {
 1707:                                             piececounter++;
 1708:                                             argptr[j++] = ch;
 1709:                                             
 1710:                                             continue;
 1711:                                         }
 1712:                                         
 1713:                                         if ((ch == '(' && piececounter == 0)) {
 1714:                                             if (!cpflag && (arg4 == 0)) {
 1715:                                                 i--;
 1716:                                             }
 1717:                                             else {
 1718:                                                 piececounter = 1;
 1719:                                                 argptr[j++] = ch;
 1720: 
 1721:                                                 continue;
 1722:                                             }
 1723:                                         }
 1724: 
 1725:                                         if (ch == '|') {
 1726:                                             if (piececounter == 0) {
 1727:                                                 piececounter = (-1);
 1728:                                             }
 1729:                                             else if (piececounter == (-1)) {
 1730:                                                 piececounter = 0;
 1731:                                             }
 1732: 
 1733:                                             if (tmp2[0] != EOL || piececounter > 0) argptr[j++] = ch;
 1734: 
 1735:                                             continue;
 1736:                                         }
 1737:                                     }
 1738:                                     
 1739:                                     if (piececounter == arg4) {
 1740:                                         if (cpflag) continue;
 1741: 
 1742:                                         cpflag = TRUE;
 1743:                                         ch = 0;
 1744:                                         
 1745:                                         if (arg4 == 0 && tmp2[0] == '^') ch = 1;
 1746: 
 1747:                                         while ((argptr[j] = tmp2[ch++]) != EOL) j++;
 1748:                                     }
 1749:                                     else {
 1750:                                         argptr[j++] = ch;
 1751:                                     }
 1752: 
 1753:                                     if (j >= (STRLEN - 1)) {
 1754:                                         merr_raise (M75);
 1755:                                         break;
 1756:                                     }
 1757:                                 } /* while ((ch = tmp3[i++]) != EOL) ... */
 1758: 
 1759:                                 if (piececounter && (piececounter == arg4)) argptr[j++] = ')';
 1760: 
 1761:                                 if (piececounter < arg4) {
 1762:                                     
 1763:                                     if (piececounter == 0) {
 1764:                                         argptr[j++] = '(';
 1765:                                     }
 1766:                                     else {
 1767:                                         argptr[j - 1] = ',';
 1768:                                     }
 1769: 
 1770:                                     while (++piececounter < arg4) {
 1771:                                         argptr[j++] = '"';
 1772:                                         argptr[j++] = '"';
 1773:                                         argptr[j++] = ',';
 1774: 
 1775:                                         if (j >= STRLEN) {
 1776:                                             merr_raise (M75);
 1777:                                             break;
 1778:                                         }
 1779: 
 1780:                                     }
 1781:                                 }
 1782:                                 
 1783:                                 ch = 0;
 1784: 
 1785:                                 if (argptr[j - 1] != ')') {
 1786:                                     while ((argptr[j++] = tmp2[ch++]) != EOL);
 1787:                                     argptr[j - 1] = ')';
 1788:                                 }
 1789:                             }
 1790: 
 1791:                             argptr[j] = EOL;
 1792: 
 1793:                             if (j >= STRLEN) {
 1794:                                 merr_raise (M75);
 1795:                                 break;
 1796:                             }
 1797:                         
 1798:                         }
 1799:                     }
 1800:                     else {
 1801:                         break;
 1802:                     }
 1803:                 } /* set$qsubscript */
 1804:                 else if (setpiece == 'e') {           /* SETtable $EXTRACT *//* parameters ok?? */
 1805: 
 1806:                     if (arg3 > arg4 || arg4 < 1) {
 1807:                         setpiece = FALSE;
 1808:                         break;
 1809:                     }
 1810: 
 1811:                     if (arg3 <= 0) arg3 = 1;
 1812: 
 1813:                     if (arg3 > STRLEN) {
 1814:                         merr_raise (M75);
 1815:                         goto err;
 1816:                     }
 1817: 
 1818:                     /* get value of glvn */
 1819:                     if (vn[0] == '^') { 
 1820:                         if (vn[1] == '$') {
 1821:                             ssvn (get_sym, vn, tmp3);
 1822:                         }
 1823:                         else {
 1824:                             global (get_sym, vn, tmp3);
 1825:                         }
 1826:                     }
 1827:                     else {
 1828:                         symtab (get_sym, vn, tmp3);
 1829:                     }
 1830: 
 1831: 
 1832:                     /* if UNDEF assume null string */
 1833:                     if (merr () == UNDEF || merr () == M6 || merr () == M7) {
 1834:                         tmp3[0] = EOL;
 1835:                         merr_clear ();
 1836:                     }
 1837:                     else if (merr () != OK) {
 1838:                         stcpy (varerr, vn);
 1839:                     }
 1840: 
 1841:                     j = stlen (tmp3);
 1842: 
 1843:                     /* pad with SPaces if source string is too short */
 1844:                     while (j < arg3) tmp3[j++] = SP;
 1845: 
 1846:                     tmp3[j] = EOL;
 1847:                     
 1848:                     if (stlen (tmp3) > arg4) {
 1849:                         stcpy (tmp2, &tmp3[arg4]);
 1850:                     }
 1851:                     else {
 1852:                         tmp2[0] = EOL;
 1853:                     }
 1854: 
 1855:                     tmp3[arg3 - 1] = EOL;
 1856: 
 1857:                     /* compose new value of glvn */
 1858:                     if (stcat (tmp3, argptr) == 0) {
 1859:                         merr_raise (M75);
 1860:                         goto err;
 1861:                     }
 1862: 
 1863:                     if (stcat (tmp3, tmp2) == 0) {
 1864:                         merr_raise (M75);
 1865:                         goto err;
 1866:                     }
 1867: 
 1868:                     stcpy (argptr, tmp3);
 1869:                     setpiece = FALSE;
 1870:                 }
 1871:                 else if (setpiece == 'g') {           /* SETtable $GET */
 1872:                     setpiece = FALSE;
 1873:                     ch = (stcmp (tmp2, argptr) == 0) ? killone : set_sym;
 1874: 
 1875:                     if (vn[0] == '^') {
 1876:                         stcpy (an, argptr);
 1877:                         if (vn[1] == '$') {                            
 1878:                             ssvn (ch, vn, an);
 1879:                         }
 1880:                         else {
 1881:                             global (ch, vn, an);
 1882:                         }
 1883:                     }
 1884:                     else {
 1885:                         stcpy (an, argptr);
 1886:                         symtab (ch, vn, an);
 1887:                     }
 1888: 
 1889:                     if (merr () != OK) stcpy (varerr, vn);
 1890:                     break;
 1891:                 }
 1892: 
 1893:                 if (vn[0] == '^') {           /* global variables and SSVNs */
 1894:                     stcpy (an, argptr);
 1895:                     
 1896:                     if (vn[1] == '$') {
 1897:                         ssvn (set_sym, vn, an);
 1898:                     }
 1899:                     else {
 1900:                         global (set_sym, vn, an);
 1901:                     }
 1902: 
 1903: 
 1904:                     if (merr () > OK) {
 1905:                         stcpy (varerr, vn);
 1906:                         goto err;
 1907:                     }
 1908:                 }
 1909:                 else if (vn[0] != '$') {           /* local variables */
 1910:                     stcpy (an, argptr);
 1911:                     symtab (set_sym, vn, an);
 1912: 
 1913:                     if (merr () > OK) {
 1914:                         stcpy (varerr, vn);
 1915:                         goto err;
 1916:                     }
 1917:                 }
 1918:                 else {           /* $-variables */
 1919: 
 1920:                     if (vn[1] == 'x') {           /* set $X */
 1921:                         j = intexpr (argptr);
 1922: 
 1923:                         if (merr () == MXNUM) {
 1924:                             j = 256;
 1925:                             merr_clear ();
 1926:                         }
 1927: 
 1928:                         if (j < 0) {
 1929:                             merr_raise (M43);
 1930:                             goto err;
 1931:                         }
 1932: 
 1933:                         if (io == HOME) {
 1934:                             argptr[0] = ESC;
 1935:                             argptr[1] = '[';
 1936:                             argptr[2] = EOL;
 1937: 
 1938:                             if (ypos[HOME] > 1) {
 1939:                                 intstr (tmp3, ypos[HOME] + 1);
 1940:                                 stcat (argptr, tmp3);
 1941:                             }
 1942: 
 1943:                             if (j > 0) {
 1944:                                 stcat (argptr, ";\201");
 1945:                                 intstr (tmp3, j + 1);
 1946:                                 stcat (argptr, tmp3);
 1947:                             }
 1948: 
 1949:                             stcat (argptr, "H\201");
 1950:                             write_m (argptr);
 1951:                         }
 1952: 
 1953:                         xpos[io] = j;
 1954:                         goto s_end;
 1955:                     }
 1956:                     else if (vn[1] == 'y') {           /* set $Y */
 1957:                         
 1958:                         j = intexpr (argptr);
 1959:                         
 1960:                         if (merr () == MXNUM)  {
 1961:                             j = 256;
 1962:                             merr_clear ();
 1963:                         }
 1964: 
 1965:                         if (j < 0) {
 1966:                             merr_raise (M43);
 1967:                             goto err;
 1968:                         }
 1969: 
 1970:                         if (io == HOME) {
 1971: 
 1972:                             argptr[0] = ESC;
 1973:                             argptr[1] = '[';
 1974:                             argptr[2] = EOL;
 1975: 
 1976:                             if (j > 0) {
 1977:                                 intstr (tmp3, j + 1);
 1978:                                 stcat (argptr, tmp3);
 1979:                             }
 1980: 
 1981:                             if (xpos[HOME] > 0) {
 1982:                                 stcat (argptr, ";\201");
 1983:                                 intstr (tmp3, xpos[HOME] + 1);
 1984:                                 stcat (argptr, tmp3);
 1985:                             }
 1986: 
 1987:                             stcat (argptr, "H\201");
 1988:                             write_m (argptr);
 1989:                         }
 1990:                         
 1991:                         ypos[io] = j;
 1992:                         goto s_end;
 1993:                     }
 1994:                     else if (vn[1] == 't') {           /* set $t */
 1995:                         test = tvexpr (argptr);
 1996:                         goto s_end;
 1997:                     }
 1998:                     else if (vn[1] == 'j') {           /* set $job */
 1999:                         pid = intexpr (argptr);
 2000:                         lock (" \201", -1, 's');
 2001:                         goto s_end;
 2002:                     }
 2003: #if !defined(_SCO_DS)
 2004:                     else if (vn[1] == 'h') {           /* set $horolog */
 2005:                         long int day;
 2006: 		        long int sec;
 2007:                         struct timespec sh_ts;
 2008: 
 2009:                         if (!is_horolog (argptr)) {
 2010:                             merr_raise (ZINVHORO);
 2011:                             goto err;
 2012:                         }
 2013:                         
 2014:                         sec = 0L;
 2015:                         
 2016:                         for (i = 0; argptr[i] != EOL; i++) {
 2017: 
 2018:                             if (argptr[i] == ',') {
 2019:                                 sec = intexpr (&argptr[i + 1]);
 2020:                                 break;
 2021:                             }
 2022: 
 2023:                         }
 2024: 
 2025:                         if (sec < 0 || sec >= 86400L) {
 2026:                             merr_raise (ARGER);
 2027:                             goto err;
 2028:                         }
 2029:                         
 2030:                         day = intexpr (argptr) - 47117L;
 2031: 
 2032:                         if (day < 0 || day > 49710L) {
 2033:                             merr_raise (ARGER);
 2034:                             goto err;
 2035:                         }
 2036:                         
 2037:                         sec += day * 86400 + FreeM_timezone;
 2038:                         day = FreeM_timezone;
 2039: 
 2040:                         sh_ts.tv_sec = sec;
 2041: 
 2042: #if defined(__linux__)
 2043:                         if (clock_settime (CLOCK_REALTIME, &sh_ts) != 0) {
 2044:                             merr_raise (PROTECT);
 2045:                             goto err;
 2046:                         }
 2047: #endif
 2048:                         
 2049: #ifndef LINUX
 2050: /* daylight savings time status may have changed */
 2051:                         {
 2052:                             struct tm *ctdata;
 2053:                             long clock;
 2054: 
 2055:                             clock = time (0L);
 2056:                             ctdata = localtime (&clock);
 2057:                             
 2058:                             if (day -= (FreeM_timezone = ctdata->tm_tzadj)) {
 2059:                                 sec -= day;
 2060:                                 tzoffset += day;
 2061:                                 stime (&sec);
 2062:                             }
 2063:                         }
 2064: #endif /* LINUX */
 2065:                         goto s_end;
 2066: 
 2067: 
 2068:                     }
 2069: #endif /* _SCO_DS */
 2070:                     else if ((vn[1] == 'r') || ((vn[1] == 'z') && (vn[2] == 'r') && vn[3] == EOL)) { /* set $reference */
 2071:                         
 2072:                         if (argptr[0] == EOL) {
 2073:                             zref[0] = EOL;
 2074:                             break;
 2075:                         }
 2076:                         
 2077:                         stcpy (tmp4, codptr);
 2078:                         stcpy (code, argptr);
 2079:                         
 2080:                         codptr = code;
 2081:                         
 2082:                         expr (NAME);
 2083:                         stcpy (code, tmp4);
 2084:                         
 2085:                         codptr = code;
 2086: 
 2087:                         if (argptr[0] != '^') merr_raise (INVREF);
 2088:                         if (ierr <= OK) nakoffs = stcpy (zref, argptr); /* save reference */ /* SMW - TODO */
 2089: 
 2090:                         goto s_end;
 2091:                     }
 2092:                     else if (vn[1] == 'z') {           /* $Z.. variables *//* if not intrinsic: make it user defined */
 2093:                         
 2094:                         i = stcpy (&tmp[1], &vn[1]) + 1;
 2095:                         
 2096:                         if (vn[3] == DELIM) i = 3;  /* set $zf() function keys */
 2097: 
 2098:                         tmp[0] = SP;
 2099:                         tmp[i] = SP;
 2100:                         tmp[++i] = EOL;
 2101:                         
 2102:                         if (find (zsvn, tmp) == FALSE) {
 2103:                             
 2104:                             i = 2;
 2105:                             while (vn[i] != EOL) {
 2106:                                 
 2107:                                 if (vn[i++] == DELIM) {
 2108:                                     merr_raise (INVREF);
 2109:                                     goto err;
 2110:                                 }
 2111: 
 2112:                             }
 2113: 
 2114:                             udfsvn (set_sym, &vn[2], argptr);
 2115:                             break;
 2116:                         }
 2117:                         
 2118:                         if ((!stcmp (&vn[2], "l\201")) || (!stcmp (&vn[2], "local\201"))) { /* set $zlocal */
 2119:                             
 2120:                             if (argptr[0] == EOL) {
 2121:                                 zloc[0] = EOL;
 2122:                                 break;
 2123:                             }
 2124:                             
 2125:                             stcpy (tmp4, codptr);
 2126:                             stcpy (code, argptr);
 2127:                             
 2128:                             codptr = code;
 2129:                             
 2130:                             expr (NAME);
 2131:                             stcpy (code, tmp4);
 2132:                             
 2133:                             codptr = code;
 2134:                             
 2135:                             if (argptr[0] == '^') merr_raise (INVREF);
 2136:                             if (ierr <= OK) stcpy (zloc, argptr);   /* save reference */
 2137: 
 2138:                             break;
 2139:                         }
 2140:                         if ((!stcmp (&vn[2], "t\201")) || (!stcmp (&vn[2], "tr\201")) || (!stcmp (&vn[2], "trap\201"))) {       /* set $ztrap */
 2141:                             
 2142:                             if (stlen (argptr) > ZTLEN) {
 2143:                                 merr_raise (M75);
 2144:                                 goto err;
 2145:                             }
 2146:                             
 2147:                             /* DSM V.2 error trapping */
 2148: #ifdef DEBUG_NEWSTACK
 2149:                             printf ("Setting Ztrap, DSM2err [%d]\r\n", DSM2err);
 2150: #endif
 2151: 
 2152: 
 2153:                             if (DSM2err) {
 2154:                                 stcpy (ztrap[NESTLEVLS + 1], argptr);
 2155:                             }
 2156:                             else {
 2157:                                 stcpy (ztrap[nstx], argptr);
 2158:                             }
 2159: 
 2160:                         }
 2161:                         else if (!stcmp (&vn[2], "p\201") || !stcmp (&vn[2], "precision\201")) { /* set $zprecision */
 2162: 
 2163:                             short tmp_zprecise;
 2164:                             
 2165:                             if ((tmp_zprecise = intexpr (argptr)) < 0) {
 2166:                                 merr_raise (MXNUM);
 2167:                                 goto err;
 2168:                             }
 2169: 
 2170:                             if (!fp_mode) {
 2171:                                 
 2172:                                 if (merr () == MXNUM) goto err;
 2173: 
 2174:                                 if (tmp_zprecise > 20000) {
 2175:                                     merr_raise (MXNUM);
 2176:                                     goto err;
 2177:                                 }
 2178:                                 
 2179:                             }
 2180: #if !defined(_AIX)			    
 2181:                             else {
 2182:                                 
 2183:                                 if (tmp_zprecise > DBL_DIG) {
 2184:                                     merr_raise (MXNUM);
 2185:                                     goto err;
 2186:                                 }
 2187: 
 2188:                                 sprintf (fp_conversion, "%%.%df\201", tmp_zprecise);
 2189:                                 
 2190:                             }
 2191: #endif			    
 2192: 
 2193:                             zprecise = tmp_zprecise;
 2194:                             
 2195: 
 2196:                         }
 2197:                         else if (vn[2] == 'f' && vn[3] == DELIM) {       /* set $zf() function keys */
 2198:                             
 2199:                             i = intexpr (&vn[4]) - 1;
 2200:                             
 2201:                             if (i < 0 || i > 43) {
 2202:                                 merr_raise (FUNARG);
 2203:                                 goto err;
 2204:                             }
 2205: 
 2206:                             if (stlen (argptr) > FUNLEN) {
 2207:                                 merr_raise (M75);
 2208:                                 goto err;
 2209:                             }
 2210: 
 2211:                             stcpy (zfunkey[i], argptr);
 2212: 
 2213:                         }                    
 2214:                         else if (vn[2] == 'm' && vn[4] == EOL && (vn[3] == 'c' || vn[3] == 'n' || vn[3] == 'p' || vn[3] == 'l' || vn[3] == 'u')) { /* set $zm_ loadable match; sort match code */
 2215:                             
 2216:                             short k;
 2217: 
 2218:                             i = 0;
 2219: 
 2220:                             for (ch = 0; ch <= 255; ch++) {
 2221:                                 j = argptr - partition;
 2222: 
 2223:                                 while ((k = partition[j++]) != EOL) {
 2224:                                     
 2225:                                     if (UNSIGN (k) == ch) {
 2226:                                         tmp[i++] = k;
 2227:                                         break;
 2228:                                     }
 2229: 
 2230:                                 }
 2231: 
 2232:                             }
 2233: 
 2234:                             tmp[i] = EOL;
 2235:                             
 2236:                             switch (vn[3]) {
 2237:                             
 2238:                                 case 'c':
 2239:                                     stcpy (zmc, tmp);
 2240:                                     break;
 2241:                             
 2242:                                 case 'n':
 2243:                                     stcpy (zmn, tmp);
 2244:                                     break;
 2245: 
 2246:                                 case 'p':
 2247:                                     stcpy (zmp, tmp);
 2248:                                     break;
 2249:                                     /*   'a': always union of zml+zmu */
 2250: 
 2251:                                 case 'l':
 2252:                                     stcpy (zml, tmp);
 2253:                                     break;
 2254:                             
 2255:                                 case 'u':
 2256:                                     stcpy (zmu, tmp);
 2257:                                     break;
 2258:                                     /*   'e': always 'everything'     */
 2259:                             }
 2260: 
 2261:                         }
 2262:                         else {
 2263:                             merr_raise (INVREF);
 2264:                             break;
 2265:                         }
 2266:                     } 
 2267:                     else {
 2268:                         merr_raise (INVREF);
 2269:                         goto err;
 2270:                     } /* end of processing for $Z.. intrinsic special variables */
 2271:                 }           /* svns=$vars */
 2272: 
 2273:                 if (multiset) goto multi;
 2274:             } /* end of scope for special SET syntaxes */
 2275: 
 2276: s_end:
 2277:             if (*codptr != ',') break;
 2278:             if (*++codptr == '@') goto again;
 2279: 
 2280:             goto set0;
 2281: 
 2282:         case IF:
 2283:             merr_raise (cmd_if (&ra));
 2284:             MRESCHECK(ra);
 2285:             break;
 2286: 
 2287: 
 2288:         case OO_USING:
 2289:             merr_raise (cmd_using (&ra));
 2290:             MRESCHECK(ra);
 2291: 	    break;
 2292: 	    
 2293: 	case OO_WITH:
 2294:             merr_raise (cmd_with (&ra));
 2295:             MRESCHECK(ra);
 2296:             break;
 2297:             
 2298:         case WRITE:
 2299:             merr_raise (cmd_write(&ra, &i));
 2300:             MRESCHECK(ra);
 2301:             break;
 2302: 
 2303:         case READ:
 2304:             merr_raise (cmd_read (&ra));
 2305:             MRESCHECK(ra);
 2306:             break;
 2307: 
 2308:         case ELSE:
 2309:             merr_raise (cmd_else (&ra));
 2310:             MRESCHECK(ra);
 2311:             break;
 2312: 
 2313:         case ZQUIT:
 2314: 
 2315:         {
 2316:             int zq_lvlct;
 2317: 
 2318:             if (rtn_dialect () != D_FREEM) {
 2319:                 merr_raise (NOSTAND);
 2320:                 goto err;
 2321:             }
 2322:             
 2323:             if (*codptr == EOL) {
 2324:                 zq_lvlct = nstx;
 2325:             }
 2326:             else {             
 2327:                 expr (STRING);
 2328: 
 2329:                 zq_lvlct = intexpr (argptr);
 2330: 
 2331:                 if (merr () > OK) goto err;
 2332: 
 2333:                 if (zq_lvlct < 0 || zq_lvlct > nstx) {
 2334:                     merr_raise (LVLERR);
 2335:                     goto err;
 2336:                 }
 2337:                 else if (zq_lvlct != nstx) {
 2338:                     repQUIT = nstx - zq_lvlct;
 2339:                 }
 2340:                 else {
 2341:                     merr_raise (LVLERR);
 2342:                     goto err;
 2343:                 }
 2344:             }
 2345:                 
 2346:             break;
 2347:         }
 2348:             
 2349:         case QUIT:
 2350: 
 2351:             if (tp_level > 0) {
 2352:                 merr_raise (M42);
 2353:                 goto err;
 2354:             }
 2355:             
 2356: #ifdef DEBUG_NEWSTACK
 2357:             printf ("At QUIT command, checking stack...\r\n");
 2358: #endif
 2359: 
 2360: 
 2361: 
 2362: #ifdef DEBUG_NEWSTACK
 2363:             printf ("nestc[nstx] is (%d)\r\n", nestc[nstx]);
 2364: #endif
 2365: 
 2366:             if (*codptr != EOL && *codptr != SP && nestc[nstx] != '$') {
 2367: #ifdef DEBUG_NEWSTACK
 2368:                 printf ("IERR\r\n");
 2369: #endif
 2370: 
 2371:                 merr_raise (ARGER);
 2372:                 break;
 2373:             }
 2374: 
 2375: 
 2376: 
 2377:             if (nestc[nstx] == '$') {           /* extrinsic function/variable */
 2378: 
 2379: 
 2380: #ifdef DEBUG_NEWSTACK
 2381:                 printf ("EXTRINSIC\r\n");
 2382: #endif
 2383:                 //printf (" extr_types[%d] = '%d'\r\n", nstx, extr_types[nstx]);
 2384:                 if (*codptr == EOL || *codptr == SP) {
 2385: 
 2386: #ifdef DEBUG_NEWSTACK
 2387:                     printf ("CODPTR is [%d]\r\n", *codptr);
 2388: #endif
 2389: 
 2390:                     if (exfdefault[0] == EOL) {
 2391:                         *argptr = EOL;
 2392:                         merr_raise (NOVAL);
 2393:                     }
 2394:                     else { /* there is a default expression... */
 2395:                         stcpy (&code[1], exfdefault);
 2396:                         expr (STRING);
 2397: 
 2398:                         if (ierr != OK - CTRLB && merr () != OK && merr () != INRPT) {
 2399: 
 2400: #ifdef DEBUG_NEWSTACK
 2401:                             printf ("Break at 1st IERR\r\n");
 2402: #endif
 2403:                             break;
 2404:                         }
 2405:                     }
 2406:                 }
 2407:                 else {                    
 2408:                     
 2409:                     expr (STRING);
 2410:                     
 2411:                     if (ierr != OK - CTRLB && merr () != OK && merr () != INRPT) {
 2412: 
 2413: #ifdef DEBUG_NEWSTACK
 2414:                         printf ("Break at 2nd IERR\r\n");
 2415: #endif
 2416: 
 2417:                         break;
 2418:                     }
 2419: 
 2420:                     if (dt_check (extr_types[nstx], argptr, 0) == FALSE) {
 2421:                         extr_types[nstx] = DT_STRING;
 2422:                         merr_raise (TYPMISMATCH);
 2423:                         break;
 2424:                     }
 2425: 
 2426:                     
 2427:                 }
 2428: 
 2429: #ifdef DEBUG_NEWSTACK
 2430:                 printf ("CHECK 01 (Stack POP)\r\n");
 2431: #endif
 2432: 
 2433: 
 2434: 
 2435:                 if (nestn[nstx]) {           /* reload routine */
 2436:                     namptr = nestn[nstx];
 2437: 
 2438:                     stcpy (rou_name, namptr);
 2439:                     zload (rou_name);
 2440:                     
 2441:                     ssvn_job_update ();
 2442: 
 2443:                     dosave[0] = 0;
 2444:                     
 2445:                     namptr--;
 2446:                 }
 2447: 
 2448:                 if (nestnew[nstx]) unnew ();       /* un-NEW variables */
 2449:                 
 2450:                 /* restore old pointers */
 2451:                 level = nestlt[nstx];   /* pop level */
 2452:                 roucur = nestr[nstx] + rouptr;
 2453: 
 2454:                 extr_types[nstx] = DT_STRING;
 2455:                 
 2456:                 stcpy (codptr = code, cmdptr = nestp[nstx--]);
 2457:                 estack--;
 2458:                 
 2459:                 forsw = (nestc[nstx] == FOR);
 2460:                 loadsw = TRUE;
 2461:                 
 2462:                 return 0;
 2463: 
 2464: 
 2465:             }
 2466: 
 2467: 
 2468:             if (nestc[nstx] == BREAK) {
 2469:                 merr_clear ();
 2470:                 merr_set_break ();
 2471:                 goto zgo;
 2472:             }           /*cont. single step */
 2473: 
 2474: 
 2475: quit0:
 2476: 
 2477: #ifdef DEBUG_NEWSTACK
 2478:             printf ("CHECK 02 (Stack POP)\r\n");
 2479: #endif
 2480: 
 2481:             if (evt_depth) {
 2482:                     
 2483:                 evt_depth--;
 2484:                     
 2485:                 if (evt_depth == 0 && evt_async_restore == TRUE) {
 2486:                     evt_async_enabled = TRUE;
 2487:                     evt_async_restore = FALSE;
 2488:                 }
 2489: 
 2490:             }
 2491: 
 2492:             if (etrap_lvl) etrap_lvl--;
 2493: 
 2494:             if (nstx == 0) goto restore;       /* nothing to quit */
 2495: 
 2496:             if (nestc[nstx] == FOR) {
 2497:                 
 2498:                 stcpy (code, cmdptr = nestp[nstx--]);
 2499: 
 2500:                 estack--;
 2501:             
 2502:                 codptr = code;
 2503:             
 2504:                 ftyp = fortyp[--forx];
 2505:                 fvar = forvar[forx];
 2506:                 finc = forinc[forx];
 2507:                 fpost = forpost[forx];
 2508:                 flim = forlim[forx];
 2509:                 fi = fori[forx];
 2510: 
 2511:                 if ((forsw = (nestc[nstx] == FOR))) goto for_end;
 2512:             
 2513:                 goto next_line;
 2514:             }
 2515: 
 2516:             if (nestn[nstx]) {           /* reload routine */
 2517:                 namptr = nestn[nstx];
 2518: 
 2519:                 if ((nestc[nstx] != XECUTE) || loadsw) {
 2520:                     
 2521:                     stcpy (rou_name, namptr);
 2522:                     zload (rou_name);
 2523:                 
 2524:                     ssvn_job_update ();
 2525: 
 2526:                     dosave[0] = 0;
 2527:                 }
 2528: 
 2529:                 namptr--;
 2530:             }
 2531: 
 2532:             if (nestnew[nstx]) unnew ();       /* un-NEW variables */
 2533: 
 2534:             /* restore old pointers */
 2535:             if ((mcmnd = nestc[nstx]) == BREAK) goto restore;       /* cont. single step */
 2536: 
 2537:             if (mcmnd == DO_BLOCK) {
 2538:                 test = nestlt[nstx];
 2539:                 level--;
 2540:             }
 2541:             else { /* pop $TEST */
 2542:                 level = nestlt[nstx];   /* pop level */
 2543:             }
 2544: 
 2545:             if (nstx) {
 2546:                 roucur = nestr[nstx] + rouptr;
 2547:             }
 2548:             else {
 2549:                 roucur = buff + (NO_OF_RBUF * PSIZE0 + 1);
 2550:             }
 2551: 
 2552:             stcpy (codptr = code, cmdptr = nestp[nstx--]);
 2553:             estack--;
 2554:             forsw = (nestc[nstx] == FOR);
 2555:             
 2556:             loadsw = TRUE;
 2557: 
 2558:             if (deferred_ierr > OK) { /* smw - TODO: how to handle deferred_ierr now */
 2559:                 merr_raise (deferred_ierr);
 2560:             }
 2561: 
 2562: #if defined(HAVE_MWAPI_MOTIF)            
 2563:             if ((in_syn_event_loop == TRUE) && (nstx == syn_event_entry_nstx)) goto syn_evt_loop_bottom;
 2564: #endif            
 2565:             
 2566:             break;
 2567: 
 2568:         case FOR:
 2569: 
 2570:             if ((ch = *codptr) == EOL) goto skip_line;     /* ignore empty line */
 2571: 
 2572: #ifdef DEBUG_NEWSTACK
 2573:             printf ("CHECK 03 (Stack PUSH)\r\n");
 2574: #endif
 2575: 
 2576:             
 2577:             if (++nstx > NESTLEVLS) {
 2578:                 nstx--;                
 2579:                 merr_raise (STKOV);
 2580:             
 2581:                 break;
 2582:             }
 2583:             else {
 2584:                 estack++;
 2585:             }
 2586: 
 2587:             fvar = forvar[++forx];
 2588:             finc = forinc[forx];
 2589:             fpost = forpost[forx];
 2590:             flim = forlim[forx];
 2591:             fi = fori[forx];
 2592:             nestc[nstx] = FOR;  /* stack set-up */
 2593: 
 2594: #ifdef DEBUG_NEWSTACK
 2595:             if (!cmdptr) printf ("CMDPTR is ZERO!\r\n");
 2596: #endif
 2597: 
 2598:             nestp[nstx] = cmdptr;
 2599:             nestn[nstx] = 0;        /* no overring of routine */
 2600:             nestr[nstx] = roucur - rouptr;  /* save roucur: only for $V(26) needed */
 2601:             ztrap[nstx][0] = EOL;
 2602: 
 2603: 
 2604:             forsw = TRUE;
 2605:             ftyp = 0;           /* no args is FOREVER */
 2606: 
 2607:             if (ch == SP) {
 2608:                 goto for_go;
 2609:             }
 2610:             else {           /* find local variable */
 2611:                 
 2612:                 if (ch == '^') {
 2613:                     merr_raise (GLOBER);
 2614:                     break;
 2615:                 }
 2616:                 
 2617:                 if (ch == '$') {
 2618:                     merr_raise (INVREF);
 2619:                     break;
 2620:                 }
 2621: 
 2622:                 if (*(codptr + 1) == '=') {           /* single char local variable */
 2623: 
 2624:                     if ((ch < 'A' && ch != '%') || (ch > 'Z' && ch < 'a') || ch > 'z') {
 2625:                         merr_raise (INVREF);
 2626:                         break;
 2627:                     }
 2628: 
 2629:                     fvar[0] = ch;
 2630:                     fvar[1] = EOL;
 2631:                     
 2632:                     codptr += 2;
 2633:                 }
 2634:                 else {
 2635:                     expr (NAME);
 2636: 
 2637:                     if (*++codptr != '=') merr_raise (ASSIGNER);
 2638:                     if (merr () != OK) break;
 2639: 
 2640:                     stcpy (fvar, varnam);
 2641: 
 2642:                     codptr++;
 2643:                 }
 2644: 
 2645:                 ftyp++;
 2646:             }
 2647: 
 2648: for_nxt_arg:
 2649: 
 2650:             expr (STRING);
 2651:             
 2652:             if (merr () != OK) break;
 2653: 
 2654:             stcpy (tmp, argptr);
 2655: 
 2656:             if ((ch = *codptr) != ':') {
 2657:                 
 2658:                 if (ch == ',' || ch == SP || ch == EOL) {
 2659:                     ftyp = 1;
 2660:                     goto for_init;
 2661:                 }
 2662:             
 2663:                 merr_raise (ARGLIST);
 2664:                 break;
 2665:             }
 2666: 
 2667:             numlit (tmp);       /* numeric interpretation */
 2668: 
 2669:             codptr++;
 2670:             expr (STRING);
 2671:             
 2672:             if (merr () != OK) break;
 2673:             
 2674:             numlit (argptr);
 2675:             stcpy (finc, argptr);   /* increment */
 2676:             
 2677:             if ((ch = *codptr) != ':') {
 2678:                 
 2679:                 if (ch == ',' || ch == EOL || ch == SP) {
 2680:                     ftyp = 2;
 2681:                     goto for_init;
 2682:                 }
 2683: 
 2684:                 merr_raise (ARGLIST);
 2685:                 break;
 2686: 
 2687:             }
 2688: 
 2689:             codptr++;
 2690: 
 2691:             expr (STRING);
 2692:             if (merr () != OK) break;
 2693: 
 2694:             numlit (argptr);
 2695:             stcpy (flim, argptr);   /* limit */
 2696: 
 2697:             ftyp = 3;
 2698: 
 2699:             if ((ch = *codptr) != ',' && ch != SP && ch != EOL) {
 2700:                 merr_raise (ARGLIST);
 2701:                 break;
 2702:             }
 2703: 
 2704:             if ((*finc != '-' && comp (flim, tmp)) || (*finc == '-' && comp (tmp, flim))) {
 2705:             
 2706:                 symtab (set_sym, fvar, tmp);
 2707:             
 2708:                 if (merr () > OK) {
 2709:                     stcpy (varerr, vn);
 2710:                     break;
 2711:                 }
 2712:             
 2713:                 goto for_quit;
 2714:             }
 2715: 
 2716: for_init:
 2717: 
 2718:             symtab (set_sym, fvar, tmp);
 2719: 
 2720:             if (merr () > OK) {
 2721:                 stcpy (varerr, fvar);
 2722:                 break;
 2723:             }
 2724: 
 2725:             /* optimize frequent special case: */
 2726:             /* increment by one and no additional FOR arguments */
 2727:             /* if limit value it must be a positive integer */
 2728:             if (ftyp > 1 && finc[0] == '1' && finc[1] == EOL) {
 2729:                 j = TRUE;
 2730:                 
 2731:                 if (ftyp == 3) {
 2732:                     i = 0;
 2733: 
 2734:                     while ((ch = flim[i]) != EOL) {
 2735:                         
 2736:                         if (ch < '0' || ch > '9') j = FALSE;
 2737:                     
 2738:                         i++;
 2739:                     }
 2740: 
 2741:                     fi = i;
 2742:                     fori[forx] = i;
 2743:                 }
 2744: 
 2745:                 if (j && ((ch = *codptr) == SP || ch == EOL)) {
 2746:                     ftyp += 2;                
 2747:                     if (ch == SP) codptr++;
 2748:                 }
 2749:             }
 2750: 
 2751: for_go:
 2752: 
 2753:             fortyp[forx] = ftyp;
 2754: 
 2755: 
 2756: #ifdef DEBUG_NEWSTACK
 2757:             if (!cmdptr) printf ("CMDPTR is ZERO!\r\n");
 2758: #endif
 2759: 
 2760:             nestp[nstx] = cmdptr;
 2761: 
 2762:             cmdptr += stcpy (cmdptr, codptr) + 1;
 2763: 
 2764:             if (ftyp > 3) goto next_cmnd;
 2765: 
 2766:             /* skip following for arguments if there are any */
 2767: 
 2768: for10:
 2769: 
 2770:             if (*codptr == SP) goto next_cmnd;
 2771: 
 2772:             i = 0;
 2773: 
 2774:             while ((((ch = *codptr) != SP) || i) && ch != EOL) {                
 2775:                 if (ch == '"') i = !i;                
 2776: 
 2777:                 codptr++;
 2778:             }           /* skip rest of FOR list */
 2779: 
 2780:             goto next_cmnd;
 2781: 
 2782: for_end:            /* end of line return */
 2783: 
 2784: #ifdef DEBUG_NEWSTACK
 2785:             printf ("For_end: nstx: %d, Nestp: (%d)\r\n", nstx, nestp[nstx]);
 2786: #endif
 2787: 
 2788:             stcpy (codptr = code, nestp[nstx]); /* restore old pointers */
 2789: 
 2790: 
 2791: 
 2792:             switch (ftyp) {
 2793:                 
 2794:                 case 5:     /* frequent special case: increment 1 */
 2795:                     symtab (getinc, fvar, tmp);
 2796: 
 2797:                     /*  compare fvar-value to flim-value */
 2798:                     /* fi: i=0; while (flim[i]>='0') i++; */
 2799:                     /* Note: EOL<'-'<'.'<'0' tmp has at least one character */
 2800:                     ch = '0';
 2801:                     j = 1;
 2802: 
 2803:                     while (tmp[j] >= ch) j++;
 2804:                     
 2805:                     if (j < fi) goto next_cmnd;
 2806:                     
 2807:                     if (j == fi) {
 2808:                         j = 0;
 2809:                     
 2810:                         while (tmp[j] == flim[j]) {
 2811:                             if (tmp[j] == EOL) goto next_cmnd;
 2812:                             j++;
 2813:                         }
 2814:                         
 2815:                         if (tmp[j] <= flim[j]) goto next_cmnd;
 2816:                     }
 2817:                     
 2818:                     if (flim[0] != '-' && tmp[0] == '-') goto next_cmnd;
 2819: 
 2820:                     stcpy (tmp2, "-1\201"); /* correct last inc */
 2821:                     add (tmp, tmp2);
 2822:                     symtab (set_sym, fvar, tmp);
 2823: 
 2824:                     goto for_quit;
 2825:                 
 2826:                 case 4:     /* frequent special case: increment 1 without limit */
 2827:                     symtab (getinc, fvar, tmp);
 2828:                     
 2829:                     
 2830:                 case 0:     /* argumentless FOR */
 2831: 
 2832:                     if(argless_forsw_quit == TRUE) {
 2833:                         /* if we have a positive QUIT condition, bail from the FOR loop */
 2834:                         argless_forsw_quit = FALSE;
 2835:                         goto for_quit;
 2836:                     }
 2837:                     else {
 2838: 
 2839:                         /* otherwise, just keep on truckin' */
 2840:                         goto next_cmnd;
 2841:                     }
 2842: 
 2843:                 case 3:     /* FOR with increment and limit test */
 2844:                     symtab (get_sym, fvar, tmp);
 2845:                     numlit (tmp);
 2846:                     stcpy (tmp2, finc); /* add may change forinc */
 2847:                     add (tmp, tmp2);
 2848: 
 2849:                     if (*finc != '-') {
 2850:                         if (comp (flim, tmp)) goto for_quit;
 2851:                     }
 2852:                     else {
 2853:                         if (comp (tmp, flim)) goto for_quit;
 2854:                     }
 2855: 
 2856:                     symtab (set_sym, fvar, tmp);
 2857: 
 2858:                     goto for10;
 2859: 
 2860:                 case 2:     /* FOR with increment without limit test */
 2861:                     symtab (get_sym, fvar, tmp);
 2862:                     numlit (tmp);
 2863:                     stcpy (tmp2, finc); /* add may change forinc */
 2864:                     add (tmp, tmp2);
 2865: 
 2866:                     symtab (set_sym, fvar, tmp);
 2867:                     goto for10;
 2868:             }           /* end switch */
 2869: 
 2870: for_quit:
 2871: 
 2872:             cmdptr = nestp[nstx];
 2873: 
 2874: 
 2875:             if (*codptr++ == ',') goto for_nxt_arg;
 2876: 
 2877:             forpost[forx][0] = '\0';
 2878: 
 2879:             nstx--;
 2880:             estack--;
 2881: 
 2882:             forx--;
 2883:             ftyp = fortyp[forx];
 2884:             fvar = forvar[forx];
 2885:             finc = forinc[forx];
 2886:             flim = forlim[forx];
 2887:             fi = fori[forx];
 2888: 
 2889: 
 2890:             if ((forsw = (nestc[nstx] == FOR))) goto for_end;
 2891: 
 2892:             if (sigint_in_for) {
 2893:                 merr_raise (INRPT);
 2894:                 sigint_in_for = FALSE;
 2895:             }
 2896:             
 2897:             if (merr () > OK) goto err;
 2898:             goto next_line;
 2899: 
 2900:         case MERGE:
 2901: 
 2902:             {
 2903:                 char lhs[256];
 2904:                 char rhs[256];
 2905: 
 2906:                 char k_buf[STRLEN];
 2907: 
 2908:                 if ((rtn_dialect () != D_M95) &&
 2909:                     (rtn_dialect () != D_MDS) &&
 2910:                     (rtn_dialect () != D_M5) &&
 2911:                     (rtn_dialect () != D_FREEM)) {
 2912:                     merr_raise (NOSTAND);
 2913:                     goto err;
 2914:                 }
 2915:                 
 2916:                 expr (NAME);
 2917:                 if (merr () > OK) break;
 2918: 
 2919:                 key_to_name (lhs, varnam, 255);
 2920:                 stcnv_c2m (lhs);
 2921: 
 2922:                 if (*++codptr != '=') {
 2923:                     merr_raise (ASSIGNER);
 2924:                     break;
 2925:                 }
 2926: 
 2927:                 codptr++;
 2928: 
 2929:                 expr (NAME);
 2930:                 if (merr () > OK) break;
 2931: 
 2932:                 codptr++;
 2933: 
 2934:                 key_to_name (rhs, varnam, 255);
 2935:                 stcnv_c2m (rhs);
 2936: 
 2937:                 stcpy (k_buf, "%INTMERGELHS\201\201");
 2938:                 symtab (set_sym, k_buf, lhs);
 2939: 
 2940:                 stcpy (k_buf, "%INTMERGERHS\201\201");
 2941:                 symtab (set_sym, k_buf, rhs);
 2942:                 
 2943:                 stcpy (&tmp3[1], "SYSWMERGE \201");
 2944:                 goto private;
 2945: 
 2946:                 break;
 2947: 
 2948:             }
 2949: 
 2950:         
 2951:         case RLOAD:
 2952:             if ((rtn_dialect () != D_MDS) &&
 2953:                 (rtn_dialect () != D_FREEM)) {
 2954:                 merr_raise (NOSTAND);
 2955:                 goto err;
 2956:             }
 2957:             stcpy (&tmp3[1], "zrload \201");
 2958:             goto private;
 2959: 
 2960: 
 2961:         case RSAVE:
 2962:             if ((rtn_dialect () != D_MDS) &&
 2963:                 (rtn_dialect () != D_FREEM)) {
 2964:                 merr_raise (NOSTAND);
 2965:                 goto err;
 2966:             }
 2967: 
 2968:             stcpy (&tmp3[1], "zrsave \201");
 2969:             goto private;
 2970: 
 2971: 
 2972:         case XECUTE:
 2973:             
 2974: 
 2975: do_xecute:            
 2976:             expr (STRING);
 2977: 
 2978:             if (merr () > OK) break;
 2979:             
 2980:             stcpy (tmp, argptr);
 2981: 
 2982:             if (*codptr == ':') {           /* argument postcond */                
 2983:                 codptr++;
 2984:                 expr (STRING);
 2985:                 
 2986:                 if (merr () > OK) break;
 2987:                 if (tvexpr (argptr) == FALSE) break;
 2988:             }
 2989:             
 2990:             if (++nstx > NESTLEVLS) {
 2991:                 nstx--;
 2992:                 merr_raise (STKOV);
 2993:             
 2994:                 break;
 2995:             }
 2996:             else {
 2997:                 estack++;
 2998:             }
 2999: 
 3000: 
 3001: #ifdef DEBUG_NEWSTACK
 3002:             if (!cmdptr) printf ("CMDPTR is ZERO!\r\n");
 3003: #endif
 3004: 
 3005:             nestc[nstx] = XECUTE;            
 3006:             nestp[nstx] = cmdptr;   /* command stack address */
 3007:             nestr[nstx] = roucur - rouptr;  /* save roucur */
 3008:             nestlt[nstx] = level;
 3009:             
 3010:             level = 0;      /* save level */
 3011:             nestnew[nstx] = 0;
 3012:             ztrap[nstx][0] = EOL;
 3013: 
 3014:             while ((*(namptr++)) != EOL);
 3015: 
 3016:             stcpy ((nestn[nstx] = namptr), rou_name);   /* save routine name */
 3017: 
 3018:             forsw = FALSE;
 3019:             loadsw = FALSE;
 3020:             cmdptr += stcpy (cmdptr, codptr) + 1;
 3021: 
 3022:             stcpy (code, tmp);
 3023: 
 3024:             roucur = buff + (NO_OF_RBUF * PSIZE0 + 1);
 3025:             codptr = code;
 3026: 
 3027:             goto next_cmnd;
 3028: 
 3029:         
 3030:         case DO:
 3031: 
 3032:             if (evt_async_initial == TRUE) {
 3033:                 evt_async_initial = FALSE;
 3034:             }
 3035:             else {
 3036:                 evt_depth++;
 3037:             }
 3038: 
 3039:             rouoldc = roucur - rouptr;
 3040:             namold = 0;
 3041: 
 3042:         case GOTO:
 3043: 
 3044: do_goto:
 3045: 
 3046:             offset = 0;
 3047:             label[0] = routine[0] = EOL;
 3048:             dofram0 = 0;
 3049: 
 3050:             if (((ch = *codptr) != '+') && (ch != '^')) {           /* parse label */  
 3051:                           
 3052:                 if (ch == SP || ch == EOL) {           /* no args: blockstructured DO */
 3053: 
 3054:                     if (mcmnd != DO) {
 3055:                         merr_raise (ARGLIST);
 3056:                         break;                    
 3057:                     }
 3058: 
 3059:                     /* direct mode: DO +1 */
 3060: 
 3061: 
 3062:                     if (nstx == 0 && roucur >= rouend) {
 3063:                         roucu0 = rouptr;
 3064:                         goto off1;
 3065:                     }
 3066: 
 3067:                     mcmnd = DO_BLOCK;
 3068:                     roucu0 = roucur;    /* continue with next line */
 3069:                     forsw = FALSE;
 3070:                 
 3071:                     goto off2;
 3072:                 }
 3073: 
 3074:                 expr (LABEL);
 3075:                 
 3076:                 if (merr () > OK) goto err;
 3077: 
 3078:                 stcpy (label, varnam);
 3079: 
 3080:                 ch = *++codptr;
 3081:             }
 3082: 
 3083:             if (ch == '+') {           /* parse offset */
 3084:                 
 3085:                 codptr++;
 3086:                 expr (OFFSET);
 3087: 
 3088:                 if (merr () > OK) goto err;
 3089:                 
 3090:                 offset = intexpr (argptr);
 3091:                 dosave[0] = EOL;
 3092:                 
 3093:                 /* unless argument is numeric, expr returns wrong codptr */
 3094:                 if ((ch = *codptr) != SP && (ch != EOL) && (ch != ',') && (ch != '^')) ch = *++codptr;
 3095:             
 3096:             }
 3097: 
 3098:             if (ch == '^') {           /* parse routine */
 3099:                 codptr++;
 3100:                 expr (LABEL);
 3101: 
 3102:                 if (merr () > OK) goto err;
 3103:                 
 3104:                 stcpy (routine, varnam);
 3105:                 
 3106:                 dosave[0] = EOL;
 3107:                 ch = *++codptr;
 3108:                 loadsw = TRUE;
 3109:             }
 3110: 
 3111:             if (ch == '(' && mcmnd == DO) {           /* parse parameter */
 3112: 
 3113:                 if (offset) {
 3114:                     merr_raise (ARGLIST);
 3115:                     goto err;
 3116:                 }
 3117: 
 3118:                 if (*++codptr == ')') {
 3119:                     ch = *++codptr;
 3120:                 }
 3121:                 else {
 3122:                     dofram0 = dofrmptr;
 3123:                     i = 0;
 3124:                     
 3125:                     for (;;) {
 3126:                         setpiece = TRUE;    /* to avoid error on closing bracket */
 3127:                     
 3128:                         if (*codptr == '.' && (*(codptr + 1) < '0' || *(codptr + 1) > '9')) {
 3129:                             codptr++;
 3130:                             
 3131:                             expr (NAME);
 3132:                             codptr++;
 3133:                             
 3134:                             *dofrmptr++ = DELIM;    /* to indicate call by name */
 3135:                             dofrmptr += stcpy (dofrmptr, varnam) + 1;
 3136:                         }
 3137:                         else {
 3138:                             expr (STRING);
 3139:                             dofrmptr += stcpy (dofrmptr, argptr) + 1;
 3140:                         }
 3141:                     
 3142:                         setpiece = FALSE;
 3143:                         i++;
 3144:                         
 3145:                         if (merr () > OK) {
 3146:                             dofrmptr = dofram0;
 3147:                             goto err;
 3148:                         }
 3149:                     
 3150:                         ch = *codptr++;
 3151:                         if (ch == ',') continue;
 3152:                     
 3153:                         if (ch != ')') {
 3154:                             merr_raise (COMMAER);
 3155:                             dofrmptr = dofram0;
 3156:                     
 3157:                             goto err;
 3158:                         }
 3159:                     
 3160:                         ch = *codptr;
 3161:                         break;
 3162:                     }
 3163:                 }
 3164:             }
 3165: 
 3166:             if (ch == ':') {           /* parse postcond */
 3167:                 
 3168:                 codptr++;
 3169:                 expr (STRING);
 3170:                 
 3171:                 if (merr () > OK) {
 3172:                     if (dofram0) dofrmptr = dofram0; /* reset frame pointer */
 3173:                     goto err;
 3174:                 }
 3175: 
 3176:                 if (tvexpr (argptr) == FALSE) {
 3177:                     if (*codptr != ',') mcmnd = 0;  /* avoid false LEVEL Error */
 3178:                     if (dofram0) dofrmptr = dofram0; /* reset frame pointer */
 3179:                 
 3180:                     break;
 3181:                 }
 3182:             }
 3183: 
 3184:             if (mcmnd == GOTO) {           /* GOTO: clear FORs from stack */
 3185:                 
 3186: #ifdef DEBUG_NEWSTACK
 3187:                 printf ("CHECK 05 Multi-POP on FOR\r\n");
 3188: #endif
 3189: 
 3190: 
 3191: 
 3192:                 while (nestc[nstx] == FOR) {
 3193:                 
 3194: #ifdef DEBUG_NEWSTACK
 3195:                     printf ("POP");
 3196: #endif
 3197: 
 3198:                     cmdptr = nestp[nstx--];
 3199:                     estack--;
 3200: 
 3201:                     forx--;
 3202:                     ftyp = fortyp[forx];
 3203:                     fvar = forvar[forx];
 3204:                     finc = forinc[forx];
 3205:                     flim = forlim[forx];
 3206:                     fi = fori[forx];
 3207:                 }
 3208: 
 3209: #ifdef DEBUG_NEWSTACK
 3210:                 printf ("\r\n");
 3211: #endif
 3212: 
 3213: 
 3214:                 loadsw = TRUE;
 3215:             }
 3216: 
 3217: job_entry:     /* entry called from successful JOB */
 3218: 
 3219:             if (routine[0] != EOL) {
 3220: 
 3221: #ifdef DEBUG_NEWSTACK
 3222:                 printf ("CHECK 06\r\n");
 3223: #endif
 3224: 
 3225:                 if (mcmnd == DO) {
 3226: 
 3227:                     while ((*(namptr++)) != EOL);
 3228:                     
 3229:                     namold = namptr;
 3230:                     stcpy (namptr, rou_name);
 3231: 
 3232:                     ssvn_job_update ();
 3233: 
 3234:                 }
 3235: 
 3236:                     /* if (GOTO label^rou) under a (DO label)   */
 3237:                     /* save away old routine to restore on quit */
 3238: 
 3239: 
 3240:                 
 3241:                 else if (nstx > 0) {
 3242: 
 3243: #ifdef DEBUG_NEWSTACK
 3244:                     printf ("CHECK 06, stack is greater than 0\r\n");
 3245: #endif
 3246: 
 3247:                     while (nestc[nstx] == FOR) {
 3248: #ifdef DEBUG_NEWSTACK
 3249:                         printf ("POP");
 3250: #endif
 3251: 
 3252:                         nstx--;
 3253:                         estack--;
 3254:                         forx--;
 3255:                         ftyp = fortyp[forx];
 3256:                         fvar = forvar[forx];
 3257:                         finc = forinc[forx];
 3258:                         flim = forlim[forx];
 3259:                         fi = fori[forx];
 3260:                     }
 3261: 
 3262:                     if (nestn[nstx] == 0) {                        
 3263:                         while ((*(namptr++)) != EOL);
 3264: 
 3265:                         stcpy ((nestn[nstx] = namptr), rou_name);
 3266:                     }
 3267:                 }
 3268: 
 3269:                 zload (routine);                
 3270:                 if (merr () > OK) goto err;       /* load file */
 3271: 
 3272:                 ssvn_job_update ();
 3273:             
 3274:             } /* if (routine[0] != EOL) */
 3275:             {
 3276:                 char *reg, *reg1;
 3277: 
 3278:                 reg1 = rouptr;
 3279:                 reg = reg1;
 3280: 
 3281:                 if (label[0] != EOL) {
 3282:                 
 3283:                     if (forsw && mcmnd == DO && stcmp (label, dosave) == 0) {
 3284:                         roucu0 = xdosave;
 3285:                         goto off1;
 3286:                     }
 3287: 
 3288:                     while (reg < rouend) {
 3289:                         reg++;
 3290:                         j = 0;
 3291:                     
 3292:                         while (*reg == label[j]) {
 3293:                             reg++;
 3294:                             j++;
 3295:                         }
 3296: 
 3297:                         if (label[j] == EOL) {
 3298:                             
 3299:                             if (*reg == TAB || *reg == SP) goto off;
 3300:                             
 3301:                             /* call of procedure without specifying a parameter list */
 3302:                             if (*reg == '(') {                                
 3303:                                 if (dofram0 == 0) dofram0 = dofrmptr;                            
 3304:                                 goto off;
 3305:                             }
 3306: 
 3307:                         }
 3308: 
 3309:                         reg = (reg1 = reg1 + UNSIGN (*reg1) + 2);
 3310:                     }
 3311:                     {
 3312:                         merr_raise (M13);
 3313:                         stcpy (varerr, label);  /* to be included in error message */
 3314:                         
 3315:                         if (dofram0) dofrmptr = dofram0; /* reset frame pointer */
 3316:                         
 3317:                         zload (rou_name);
 3318:                         ssvn_job_update ();                        
 3319:                         goto err;
 3320:                     }
 3321:                 }
 3322: off:
 3323:                 if (label[0] == EOL && offset > 0) offset--;
 3324:                 while (offset-- > 0) reg1 = reg1 + (UNSIGN (*reg1) + 2);
 3325:                 
 3326:                 if (forsw) {
 3327:                     xdosave = reg1;
 3328:                     stcpy (dosave, label);
 3329:                 }
 3330: 
 3331:                 roucu0 = reg1;
 3332:             }
 3333: 
 3334:             if (roucu0 >= rouend) {
 3335:                 merr_raise (M13);
 3336:                 stcpy (varerr, label);  /* to be included in error message */
 3337: 
 3338:                 if (dofram0) dofrmptr = dofram0; /* reset frame pointer */
 3339:                 
 3340:                 zload (rou_name);
 3341:                 ssvn_job_update ();
 3342:                 goto err;
 3343:             }
 3344: 
 3345: off1:
 3346:             if (routine[0] != EOL) stcpy (rou_name, routine);
 3347: 
 3348:             ssvn_job_update ();            
 3349: 
 3350:             roucu0++;
 3351:             forsw = FALSE;
 3352: 
 3353:             if (mcmnd != DO) {           /* i.e. GOTO or JOB */
 3354:                 roucur = roucu0;
 3355:                 goto off3;
 3356:             }
 3357: 
 3358: off2:
 3359: 
 3360: #ifdef DEBUG_NEWSTACK
 3361:             printf ("CHECK 07 (Stack PUSH)\r\n");
 3362: #endif
 3363: 
 3364: 
 3365: 
 3366:             if (++nstx > NESTLEVLS) {
 3367:                 nstx--;
 3368:                 merr_raise (STKOV);
 3369:             
 3370:                 goto err;
 3371:             }
 3372:             else {
 3373:                 on_frame_entry ();
 3374:                 estack++;
 3375:             }
 3376: 
 3377:             nestc[nstx] = mcmnd;
 3378: 
 3379: #ifdef DEBUG_NEWSTACK
 3380:             if (!cmdptr) printf ("CMDPTR is ZERO!\r\n");
 3381: #endif
 3382: 
 3383:             nestp[nstx] = cmdptr;
 3384:             nestn[nstx] = namold;
 3385:             nestr[nstx] = rouoldc;
 3386:             nestnew[nstx] = 0;
 3387: 
 3388:             if (mcmnd != DO_BLOCK) {
 3389:                 nestlt[nstx] = level;
 3390:                 level = 0;
 3391:             }
 3392:             else { /* push level ; clr level */
 3393:                 nestlt[nstx] = test;
 3394:                 level++;
 3395:             }           /* push $TEST ; inc level */
 3396: 
 3397:             ztrap[nstx][0] = EOL;
 3398: 
 3399: 
 3400:             cmdptr += stcpy (cmdptr, codptr) + 1;
 3401:             roucur = roucu0;
 3402: 
 3403:             /* processing for private Z-Command: */
 3404:             if (privflag) {
 3405: 
 3406: 
 3407: 
 3408: #ifdef DEBUG_NEWPTR
 3409:                 printf ("Xecline 01 (using NEWPTR): ");
 3410:                 printf ("[nstx] is [%d], [nestnew] is [%d]", nstx, nestnew[nstx]);
 3411:                 printf ("- Initialized to newptr\r\n");
 3412: #endif /* Debug */
 3413: 
 3414:                 nestnew[nstx] = newptr;
 3415: 
 3416: 
 3417:                 stcpy (vn, zargdefname);
 3418: 
 3419:                 /*was:      vn[0] = '%';   vn[1] = EOL; */
 3420: 
 3421:                 symtab (new_sym, vn, "");
 3422:                 /*djw change 'input variable for Z command' to get value of $V(202) */
 3423:                 /*was:      vn[0] = '%';   vn[1] = EOL; */
 3424: 
 3425:                 stcpy (vn, zargdefname);
 3426:                 symtab (set_sym, vn, tmp2);
 3427: 
 3428:                 privflag = FALSE;
 3429:             }
 3430: 
 3431: off3:
 3432: 
 3433:             if (dofram0) {
 3434:                 char *reg, *reg1;
 3435: 
 3436:                 reg = roucu0;
 3437:                 reg1 = dofram0;
 3438:             
 3439:                 while ((ch = (*reg++)) != '(') {
 3440:                     if (ch == SP || ch == TAB || ch == EOL) break;
 3441:                 }
 3442: 
 3443:                 if (ch != '(') {
 3444:                     merr_raise (TOOPARA);
 3445:                     dofrmptr = dofram0;
 3446:             
 3447:                     goto err;
 3448:                 }
 3449:             
 3450:                 j = 0;
 3451: 
 3452:                 while ((ch = (*reg++)) != EOL) {
 3453:             
 3454:                     if ((ch == ',' && j) || ch == ')') {
 3455:                         varnam[j] = EOL;
 3456: 
 3457: 
 3458: 
 3459: #ifdef DEBUG_NEWPTR
 3460:                         printf ("Xecline 02: ");
 3461:                         printf ("[nstx] is [%d], [nestnew] is [%d]\r\n", nstx, nestnew[nstx]);
 3462: #endif
 3463: 
 3464:                         if (nestnew[nstx] == 0) nestnew[nstx] = newptr;
 3465:             
 3466: 
 3467: 
 3468:                         if (reg1 < dofrmptr) {
 3469: 
 3470:                             if (*reg1 == DELIM) {   /* call by reference */
 3471:                             
 3472:                                 if (stcmp (reg1 + 1, varnam)) {   /* are they different?? */
 3473:                                     symtab (new_sym, varnam, "");
 3474:                                     symtab (m_alias, varnam, reg1 + 1);
 3475:                                 }
 3476: 
 3477:                             }
 3478:                             else {
 3479:                                 symtab (new_sym, varnam, "");   /* call by value */
 3480:                                 symtab (set_sym, varnam, reg1);
 3481:                             }
 3482: 
 3483:                             reg1 += stlen (reg1) + 1;
 3484:                         }
 3485:                         else {
 3486:                             symtab (new_sym, varnam, "");
 3487:                         }
 3488: 
 3489:                         if (ch == ')') break;
 3490:                 
 3491:                         j = 0;
 3492:                         continue;
 3493:                     }
 3494: 
 3495:                     if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9' && j) || (ch == '%' && j == 0)) {
 3496:                         varnam[j++] = ch;
 3497:                         continue;
 3498:                     }
 3499: 
 3500:                     merr_raise (ARGLIST);
 3501:                     dofrmptr = dofram0; /* reset frame pointer */
 3502:                     
 3503:                     goto err;
 3504:                 }
 3505: 
 3506:                 if (reg1 < dofrmptr) {
 3507:                     merr_raise (TOOPARA);
 3508:                     dofrmptr = dofram0;
 3509: 
 3510:                     goto err;
 3511:                 }
 3512: 
 3513:                 dofrmptr = dofram0;
 3514:             }
 3515: 
 3516:             goto next_line;
 3517: 
 3518:         /* ZJOB *//* same as JOB, but without timeout */
 3519:         /* not recommended; just for backward compatibility */
 3520:         case ZJOB:
 3521:             if (is_standard ()) {
 3522:                 merr_raise (NOSTAND);
 3523:                 goto err;
 3524:             }
 3525: 
 3526:         case JOB:
 3527: 
 3528:             if (rtn_dialect () == D_M77) {
 3529:                 merr_raise (NOSTAND);
 3530:                 goto err;
 3531:             }
 3532:             
 3533:             if (*codptr == SP || *codptr == EOL) {
 3534:                 merr_raise (M13);
 3535:                 varerr[0] = EOL;    /* to be included in error message */
 3536: 
 3537:                 break;
 3538:             }
 3539: 
 3540:             loadsw = TRUE;
 3541:             offset = 0;
 3542:             frm_timeout = (-1L);
 3543:             label[0] = routine[0] = EOL;
 3544: 
 3545:             if (((ch = *codptr) != '+') && (ch != '^')) {           /* parse label */
 3546:                 expr (LABEL);
 3547:                 if (merr () > OK) goto err;
 3548: 
 3549:                 stcpy (label, varnam);
 3550: 
 3551:                 ch = *++codptr;
 3552:             }
 3553: 
 3554:             if (ch == '+') {           /* parse offset */
 3555:                 codptr++;
 3556: 
 3557:                 expr (OFFSET);
 3558:                 if (merr () > OK) goto err;
 3559: 
 3560:                 offset = intexpr (argptr);
 3561:                 
 3562:                 /* unless argument is numeric, expr returns wrong codptr */
 3563:                 if ((ch = *codptr) != SP && (ch != EOL) && (ch != ',') && (ch != '^')) ch = *++codptr;
 3564:             
 3565:             }
 3566: 
 3567:             if (ch == '^') {           /* parse routine */
 3568:                 codptr++;
 3569:                 
 3570:                 expr (LABEL);
 3571:                 if (merr () > OK) goto err;
 3572: 
 3573:                 stcpy (routine, varnam);
 3574: 
 3575:                 dosave[0] = EOL;
 3576:                 ch = *++codptr;
 3577:             }
 3578: 
 3579:             dofram0 = NULL;
 3580:             if (ch == '(') {           /* parse parameter */
 3581:                 
 3582:                 if (offset) {
 3583:                     merr_raise (ARGLIST);
 3584:                     goto err;
 3585:                 }
 3586:                 
 3587:                 codptr++;
 3588:                 dofram0 = dofrmptr;
 3589:                 
 3590:                 i = 0;
 3591:                 for (;;) {
 3592:                     setpiece = TRUE;    /* to avoid error on closing bracket */
 3593:                     
 3594:                     if (*codptr == '.' && (*(codptr + 1) < '0' || *(codptr + 1) > '9')) {
 3595:                         codptr++;
 3596:                         
 3597:                         expr (NAME);
 3598:                         
 3599:                         codptr++;
 3600:                         
 3601:                         *dofrmptr++ = DELIM;    /* to indicate call by name */
 3602:                         dofrmptr += stcpy (dofrmptr, varnam) + 1;
 3603:                     }
 3604:                     else {
 3605:                         expr (STRING);
 3606:                         dofrmptr += stcpy (dofrmptr, argptr) + 1;
 3607:                     }
 3608: 
 3609:                     setpiece = FALSE;
 3610:                     i++;
 3611:                     
 3612:                     if (merr () > OK) {
 3613:                         dofrmptr = dofram0;
 3614:                         goto err;
 3615:                     }
 3616: 
 3617:                     ch = *codptr++;
 3618:                     if (ch == ',') continue;
 3619: 
 3620:                     if (ch != ')') {
 3621:                         merr_raise (COMMAER);
 3622:                         dofrmptr = dofram0;
 3623: 
 3624:                         goto err;
 3625:                     }
 3626: 
 3627:                     ch = *codptr;
 3628:                     break;
 3629:                 }
 3630:             }
 3631: 
 3632:             if (ch == ':' && *(codptr + 1) == ch) {
 3633:                 codptr++;       /* timeout,no jobparams */                
 3634:             }
 3635:             else if (ch == ':' && *(codptr + 1) == '(') { /* parse any 'job parameters', but ignore them otherwise */
 3636:                 codptr++;
 3637:                 setpiece = TRUE;    /* to avoid bracket error at end of jobparameters */
 3638: 
 3639:                 for (;;) {
 3640:                     if (*++codptr != ':') expr (STRING);
 3641:                     if (*codptr == ':') continue;
 3642:                     if (*codptr++ != ')') merr_raise (ARGER);
 3643: 
 3644:                     break;
 3645:                 }
 3646: 
 3647:                 setpiece = FALSE;
 3648:                 ch = (*codptr);
 3649:             }
 3650: 
 3651:             if (ch == ':') {           /* timeout */
 3652:                 codptr++;
 3653:                 expr (STRING);
 3654: 
 3655:                 if ((frm_timeout = intexpr (argptr)) < 0L) frm_timeout = 0L;
 3656:                 if (merr () > OK) goto err;
 3657: 
 3658:                 test = TRUE;
 3659:             }
 3660: 
 3661:             if (mcmnd == ZJOB) frm_timeout = 0L;       /* ZJOB-command has timeout 0 */
 3662: 
 3663:             close_all_globals ();   /* close all globals */
 3664:             j = getpid ();      /* job number of father process */
 3665: 
 3666:             if (lonelyflag) {           /* single user */
 3667:                 if (frm_timeout < 0L) {
 3668:                     merr_raise (PROTECT); /* error without timeout */
 3669:                 }
 3670:                 else {
 3671:                     test = FALSE;   /* timeout always fails */
 3672:                 }
 3673:                 
 3674:                 break;
 3675:             }
 3676: 
 3677:             while ((i = fork ()) == -1) {
 3678:             
 3679:                 if (frm_timeout == 0L) {
 3680:                     test = FALSE;
 3681:                     break;
 3682:                 }
 3683:                 
 3684:                 if (frm_timeout > 0L) frm_timeout--;
 3685:                 
 3686:                 sleep (1);
 3687: 
 3688:             }
 3689: 
 3690:             if (mcmnd == ZJOB && zjobflag) {
 3691:                 
 3692:                 if (i == 0) {           /* we are in child process */
 3693:                     intstr (zb, j); /* $JOB of father job */
 3694:                     
 3695:                     father = j;
 3696:                     pid = getpid ();    /* this is our new job number */
 3697: 
 3698:                     jobtime = time (0L);;
 3699: 
 3700: 
 3701:                     nstx = 0;       /* clear stack */
 3702:                     estack = 0;
 3703: 
 3704:                     forx = 0;
 3705:                     forsw = FALSE;
 3706:                     level = 0;
 3707:                     cmdptr = cmdstack;  /*  -  command stack pointer */
 3708:                     namptr = namstck;   /*  -  routine name stack pointer */
 3709:                     usermode = 0;   /* application mode */
 3710:                     merr_clear ();
 3711: 
 3712:                     lock (" \201", -1, 'j');    /* tell lock about JOB */
 3713:                     goto job_entry;
 3714:                 }
 3715: 
 3716:                 /* ignore signal while here */
 3717:                 sig_attach (SIGUSR1, SIG_IGN);
 3718: 
 3719:                 while (wait (&zsystem) != i);
 3720: 
 3721:                 sig_attach (SIGUSR1, &oncld);   /* restore handler */
 3722: 
 3723:                 merr_clear ();      /* there might be a INRPT from other job */
 3724:     
 3725:                 set_io (MUMPS);
 3726:                 break;
 3727:             }
 3728: 
 3729:             if (i == 0) {           /* we are in child process */
 3730:                 
 3731:                 intstr (zb, j); /* $JOB of father job */
 3732:                 father = j;
 3733: 
 3734:                 pid = getpid ();    /* $J = process ID */
 3735:                 usermode = 0;       /* no programmer mode */
 3736:                 DSW |= BIT0;        /* disable echo */
 3737:                 zbreakon = DISABLE; /* disable CTRL/B */
 3738:                 breakon = DISABLE;  /* disable CTRL/C */
 3739:                 hardcopy = DISABLE; /* disable hardcopy function */
 3740:                 
 3741:                 fclose (stdin); /* close normal input */
 3742:                 
 3743:                 jour_flag = 0;  /* no protocol */
 3744:                 
 3745: 
 3746:                 nstx = 0;       /* clear stack */
 3747:                 estack = 0;
 3748: 
 3749:                 forx = 0;
 3750:                 forsw = FALSE;
 3751:                 level = 0;
 3752:                 
 3753:                 cmdptr = cmdstack;  /*  -  command stack pointer */
 3754:                 namptr = namstck;   /*  -  routine name stack pointer */
 3755:                 
 3756:                 /* init random number */
 3757:                 if ((nrandom = time (0L) * getpid ()) < 0) nrandom = (-nrandom);
 3758:                 
 3759:                 merr_clear ();
 3760:                 lock (" \201", -1, 'j');    /* tell lock about JOB */
 3761: 
 3762:                 goto job_entry;
 3763:             }
 3764: 
 3765:             intstr (zb, i);     /* $JOB of the process just started */
 3766:             break;
 3767: 
 3768:         case KILL:
 3769:             
 3770:             /* argumentless: KILL all local variables */
 3771:             if (((ch = *codptr) == SP) || ch == EOL) {
 3772:                 symtab (kill_all, "", "");
 3773:                 break;
 3774:             }
 3775: 
 3776:             if (ch != '(') {
 3777:                 char destc[255];
 3778:                 register int cd;
 3779: 
 3780:                 destc[0] = '\0';
 3781:                 
 3782:                 expr (NAME);
 3783:             
 3784:                 /* aviod a disaster if someone types KILL ^PATDAT[TEST] ! */
 3785:                 if (((ch = *++codptr) != SP) && ch != EOL && ch != ',') merr_raise (INVREF);
 3786:                 if (merr () > OK) goto err;
 3787:             
 3788:                 if (varnam[0] == '^') {
 3789:                     if (varnam[1] != '$') {
 3790:                         global (kill_sym, varnam, tmp);
 3791:                     }
 3792:                     else {
 3793:                         ssvn (kill_sym, varnam, tmp);
 3794:                     }
 3795:                     break;
 3796:                 }
 3797: 
 3798:                 symtab (kill_sym, varnam, tmp);
 3799:                
 3800:                 if (destructor_ct) {
 3801: 
 3802:                     for (cd = 0; cd < destructor_ct; cd++) {
 3803:                         if (strlen (destructors[cd]) > 0) {
 3804:                             strcat (destc, destructors[cd]);
 3805:                             strcat (destc, ",");
 3806:                         }
 3807:                     }
 3808: 
 3809:                     destructor_ct = 0;                    
 3810:                     destc[strlen(destc) - 1] = '\201';
 3811: 
 3812:                     stcpy (&tmp3[1], destc);
 3813:                     destructor_run = TRUE;
 3814:                     
 3815:                     goto private;
 3816:                 }
 3817:                 
 3818:                 
 3819:                 break;
 3820:             }
 3821: 
 3822:             /* exclusive kill */
 3823:             tmp[0] = SP;
 3824:             tmp[1] = EOL;
 3825: 
 3826:             for (;;) {
 3827: 
 3828:                 codptr++;
 3829:                 expr (NAME);
 3830:                 
 3831:                 if (merr () > OK) goto err;
 3832:                 
 3833:                 if (varnam[0] == '^') {
 3834:                     merr_raise (GLOBER);
 3835:                     goto err;
 3836:                 }
 3837:                 
 3838:                 i = 0;
 3839:                 while (varnam[i] != EOL) {
 3840: 
 3841:                     if (varnam[i] == DELIM) {
 3842:                         merr_raise (SBSCR);
 3843:                         goto err;
 3844:                     }
 3845: 
 3846:                     i++;
 3847:                 }
 3848: 
 3849:                 if (stcat (tmp, varnam) == 0) {
 3850:                     merr_raise (M75);
 3851:                     goto err;
 3852:                 }
 3853: 
 3854:                 if (stcat (tmp, " \201") == 0) {
 3855:                     merr_raise (M75);
 3856:                     goto err;
 3857:                 }
 3858: 
 3859:                 if ((ch = *++codptr) == ')') {
 3860:                     codptr++;
 3861:                     break;
 3862:                 }
 3863: 
 3864:                 if (ch != ',') {
 3865:                     merr_raise (COMMAER);
 3866:                     goto err;
 3867:                 }
 3868:             }
 3869: 
 3870:             symtab (killexcl, tmp, "");
 3871:             break;
 3872: 
 3873:         case NEWCMD:
 3874:             if ((rtn_dialect () == D_M77) ||
 3875:                 (rtn_dialect () == D_M84)) {
 3876:                 merr_raise (NOSTAND);
 3877:                 goto err;
 3878:             }
 3879:         /*case ZNEW:*/            
 3880:             
 3881:             /* argumentless: NEW all local variables */
 3882:             if (((ch = *codptr) == SP) || ch == EOL) {
 3883:                 ch = nstx;
 3884: 
 3885:                 while (nestc[ch] == FOR) ch--;       /* FOR does not define a NEW level */
 3886:                 
 3887: #ifdef DEBUG_NEWPTR
 3888:                 printf ("Xecline 03: (TODO - NEW ALL) ");
 3889:                 printf ("[ch] is %d, [nestnew] is %d\r\n", ch, nestnew[ch]);
 3890: #endif
 3891: 
 3892:                 if (nestnew[ch] == 0) nestnew[ch] = newptr;
 3893:                 
 3894:                 symtab (new_all, "", "");
 3895:                 break;
 3896:             }
 3897: 
 3898:             if (ch != '(') {
 3899:                 expr (NAME);
 3900:                 
 3901:                 if (merr () > OK) goto err;
 3902: 
 3903:                 codptr++;
 3904:                 
 3905:                 if (varnam[0] == '^') {
 3906:                     merr_raise (GLOBER);
 3907:                     goto err;
 3908:                 }
 3909: 
 3910:                 if (varnam[0] == '$') {
 3911:                     i = 0;
 3912:                 
 3913:                     while ((ch = varnam[++i]) != EOL) if (ch >= 'A' && ch <= 'Z') varnam[i] = ch + 32;
 3914: 
 3915:                     /* set $reference */    
 3916:                     if ((stcmp (&varnam[1], "r\201")) && (stcmp (&varnam[1], "reference\201")) && (stcmp (&varnam[1], "zr\201")) && (stcmp (&varnam[1], "zreference\201")) &&
 3917:                         (stcmp (&varnam[1], "t\201")) && (stcmp (&varnam[1], "test\201")) && (stcmp (&varnam[1], "j\201")) && (stcmp (&varnam[1], "job\201")) &&
 3918:                         (stcmp (&varnam[1], "zi\201")) && (stcmp (&varnam[1], "zinrpt\201")) && (stcmp (&varnam[1], "et\201")) && (stcmp (&varnam[1], "etrap\201")) &&
 3919:                         (stcmp (&varnam[1], "es\201")) && (stcmp (&varnam[1], "estack\201"))) {
 3920:                             merr_raise (INVREF);
 3921:                             goto err;
 3922:                     }
 3923:                 }
 3924: 
 3925:                 /* new and set, new object */
 3926:                 if (*codptr == '=') {
 3927: 
 3928:                     if ((rtn_dialect () != D_FREEM)) {
 3929:                         merr_raise (NOSTAND);
 3930:                         goto err;
 3931:                     }
 3932:                     
 3933:                     codptr++;
 3934:                     stcpy (vn, varnam);
 3935: 
 3936:                     if (*codptr != '$') {
 3937:                         /* this is a new-and-set */
 3938:                         expr (STRING);
 3939:                         new_and_set = TRUE;
 3940:                     }
 3941:                     else {
 3942:                         if ((*codptr == '$') &&
 3943:                             (*(codptr + 1) == '#') &&
 3944:                             (*(codptr + 2) == '^')) {
 3945: 
 3946:                             char class[255];
 3947:                             char constructor[255];
 3948:                             char objvar[255];
 3949:                             char datres[5];
 3950:                             int dat_res;
 3951:                             
 3952:                             stcpy (objvar, vn);
 3953: 
 3954:                             symtab (fra_dat, objvar, datres);
 3955:                             dat_res = atoi (datres);
 3956: 
 3957:                             if (dat_res > 0) {
 3958:                                 merr_raise (OBJCONFLICT);
 3959:                                 goto err;
 3960:                             }
 3961:                             
 3962:                             stcnv_m2c (objvar);
 3963:                             
 3964:                             codptr += 2;                            
 3965:                 
 3966:                             /* this is probably an object instantiation */
 3967:                             expr (NAME);
 3968:                             if (merr () > OK) goto err;
 3969: 
 3970:                             stcpy (class, varnam);
 3971:                             stcnv_m2c (class);                                                       
 3972:                             new_object = TRUE;
 3973:                             codptr++;
 3974:                             
 3975:                             obj_get_constructor (constructor, class, objvar);
 3976: 
 3977:                             for (dat_res = 0; dat_res < strlen (class); dat_res++) {
 3978:                                 if (class[dat_res] == '\202') {
 3979:                                     class[dat_res] = '\0';
 3980:                                     break;
 3981:                                 }
 3982:                             }
 3983:                             
 3984:                             obj_create_symbols (objvar, class);
 3985: 
 3986:                             if (merr () > OK) goto err;
 3987: 
 3988:                             snprintf (&tmp3[1], 255, "%s\201", &constructor[1]);
 3989:                             goto private;
 3990: 
 3991:                         }
 3992:                         else {
 3993:                             if (*codptr == '$') {
 3994:                                 expr (STRING);
 3995:                                 new_and_set = TRUE;
 3996:                             }
 3997:                             else {
 3998:                                 merr_raise (ILLFUN);
 3999:                                 goto err;
 4000:                             }
 4001:                         }                        
 4002:                     }
 4003:                         
 4004:                     
 4005:                     goto set2;
 4006:                 }
 4007: 
 4008: post_new:
 4009:                 
 4010:                 ch = nstx;
 4011:                 
 4012:                 while (nestc[ch] == FOR) ch--;       /* FOR does not define a NEW level */
 4013: 
 4014: #ifdef DEBUG_NEWPTR
 4015:                 printf ("Xecline 04 (DANGER): ");
 4016:                 printf ("[ch] is %d, [nestnew] is %d\r\n", ch, nestnew[ch]);
 4017: #endif
 4018: 
 4019:                 if (nestnew[ch] == 0) nestnew[ch] = newptr;
 4020:                 
 4021:                 symtab (new_sym, varnam, "");
 4022:                 break;
 4023:             }
 4024: 
 4025:             /* exclusive new */
 4026:             tmp[0] = SP;
 4027:             tmp[1] = EOL;
 4028:             
 4029:             for (;;) {
 4030:                 codptr++;
 4031:                 expr (NAME);
 4032: 
 4033:                 if (merr () > OK) goto err;
 4034: 
 4035:                 if (varnam[0] == '^') {
 4036:                     merr_raise (GLOBER);
 4037:                     goto err;
 4038:                 }
 4039: 
 4040:                 if (varnam[0] == '$') {
 4041:                     merr_raise (INVREF);
 4042:                     goto err;
 4043:                 }
 4044: 
 4045:                 i = 0;
 4046:                 while (varnam[i] != EOL) {
 4047: 
 4048:                     if (varnam[i] == DELIM) {
 4049:                         merr_raise (SBSCR);
 4050:                         goto err;
 4051:                     }
 4052: 
 4053:                     i++;
 4054:                 }
 4055: 
 4056:                 if (stcat (tmp, varnam) == 0) {
 4057:                     merr_raise (M75);
 4058:                     goto err;
 4059:                 }
 4060: 
 4061:                 if (stcat (tmp, " \201") == 0) {
 4062:                     merr_raise (M75);
 4063:                     goto err;
 4064:                 }
 4065: 
 4066:                 if ((ch = *++codptr) == ')') {
 4067:                     codptr++;
 4068:                     break;
 4069:                 }
 4070: 
 4071:                 if (ch != ',') {
 4072:                     merr_raise (COMMAER);
 4073:                     goto err;
 4074:                 }
 4075:             }
 4076: 
 4077:             ch = nstx;
 4078:             while (nestc[ch] == FOR) ch--;           /* FOR does not define a NEW level */
 4079: 
 4080: #ifdef DEBUG_NEWPTR
 4081:             printf ("Xecline 05 (TODO): ");
 4082:             printf ("[ch] is %d, [nestnew] is %d\r\n", ch, nestnew[ch]);
 4083: #endif
 4084: 
 4085:             if (nestnew[ch] == 0) nestnew[ch] = newptr;
 4086:             
 4087:             symtab (newexcl, tmp, "");
 4088:             break;
 4089: 
 4090:         case LOCK:
 4091: 
 4092:             /* argumentless: UNLOCK */
 4093:             if ((ch = *codptr) == SP || ch == EOL) {
 4094:                 locktab_unlock_all ();
 4095:                 break;
 4096:             }
 4097: 
 4098:             if (ch == '+' || ch == '-') {
 4099: 
 4100:                 if ((rtn_dialect () == D_M77) ||
 4101:                     (rtn_dialect () == D_M84)) {
 4102:                     merr_raise (NOSTAND);
 4103:                     goto err;
 4104:                 }
 4105:                 
 4106:                 tmp[0] = ch;
 4107:                 ch = (*++codptr);
 4108:             }
 4109:             else {
 4110:                 tmp[0] = SP;
 4111:             }
 4112: 
 4113:             if (ch != '(') {
 4114:                 expr (NAME);
 4115:             
 4116:                 if (merr () > OK) goto err;
 4117: 
 4118:                 stcpy (&tmp[1], varnam);
 4119:                 stcat (tmp, "\001\201");
 4120:             }
 4121:             else {           /* multiple lock */
 4122:                 tmp[1] = EOL;
 4123: 
 4124:                 for (;;) {
 4125:                     codptr++;
 4126:                     expr (NAME);
 4127:                 
 4128:                     if (merr () > OK) goto err;
 4129: 
 4130:                     stcat (tmp, varnam);
 4131:                     stcat (tmp, "\001\201");
 4132:                     
 4133:                     if ((ch = *++codptr) == ')') break;
 4134:                     
 4135:                     if (ch != ',') {
 4136:                         merr_raise (COMMAER);
 4137:                         goto err;
 4138:                     }
 4139:                 }
 4140: 
 4141:             }
 4142: 
 4143:             frm_timeout = (-1L);        /* no timeout */
 4144:             
 4145:             if (*++codptr == ':') {
 4146:                 codptr++;
 4147:                 expr (STRING);
 4148:             
 4149:                 frm_timeout = intexpr (argptr);
 4150:             
 4151:                 if (merr () > OK) goto err;
 4152:                 if (frm_timeout < 0L) frm_timeout = 0L;
 4153:             }
 4154: 
 4155:             lock (tmp, frm_timeout, LOCK);
 4156:             break;
 4157: 
 4158:         case USE:
 4159: 
 4160:             if (*codptr == SP || *codptr == EOL) {
 4161:                 merr_raise (ARGER);
 4162:                 goto err;
 4163:             }
 4164: 
 4165:             expr (STRING);
 4166:             j = intexpr (argptr);
 4167: 
 4168:             if (j > MAXSEQ && j < MAXDEV) {
 4169:                 io = j;
 4170:                 goto use_socket;
 4171:             }
 4172: 
 4173:             if (j < 0 || j > MAXDEV) {
 4174:                 merr_raise (NODEVICE);
 4175:             }
 4176:             else if (j != HOME && devopen[j] == 0) {
 4177:                 merr_raise (NOPEN);
 4178:             }
 4179: 
 4180:             if (merr () > OK) goto err;
 4181: 
 4182:             io = j;
 4183: 
 4184:             if (io == HOME && *codptr == ':' && *(codptr + 1) == '(') {
 4185: 
 4186: use0:          /* entry point for processing of device parameters */
 4187: 
 4188:                 codptr += 2;
 4189:                 j = 1;
 4190:                 setpiece = TRUE;    /* so a surplus closing bracket will not be an error */
 4191:                 
 4192:                 while (*codptr != ')') {
 4193: 
 4194:                     if (*codptr == ':') {
 4195:                         codptr++;
 4196:                         j++;
 4197:                     
 4198:                         continue;
 4199:                     }
 4200:                     
 4201:                     expr (STRING);
 4202:                     
 4203:                     if (merr () > OK) {
 4204:                         setpiece = FALSE;
 4205:                         goto err;
 4206:                     }
 4207: 
 4208:                     switch (j) {
 4209: 
 4210:                         case 1:
 4211:                             i = intexpr (argptr);
 4212: 
 4213:                             if (i < 0) i = 0;
 4214:                             if (i > 255) i = 255;
 4215:                             
 4216:                             RightMargin = i;                            
 4217:                             break;
 4218:                         
 4219:                         case 3:
 4220:                             i = intexpr (argptr);
 4221:                             
 4222:                             if (i < 0) i = 0;
 4223:                             if (i > 255) i = 255;
 4224: 
 4225:                             InFieldLen = i;
 4226:                             break;
 4227:                         
 4228:                         case 5:
 4229:                             DSW = intexpr (argptr);
 4230:                             break;
 4231:                         
 4232:                         case 7:
 4233:                             i = intexpr (argptr);
 4234:                             ypos[HOME] = i / 256;
 4235:                             xpos[HOME] = i % 256;
 4236:                             
 4237:                             if (DSW & BIT7) {
 4238:                                 
 4239:                                 i = io;
 4240:                                 io = HOME;
 4241:                                 argptr[0] = ESC;
 4242:                                 argptr[1] = '[';
 4243:                                 argptr[2] = EOL;
 4244: 
 4245:                                 if (ypos[HOME]) {
 4246:                                     intstr (&argptr[2], ypos[HOME] + 1);
 4247:                                 }
 4248: 
 4249:                                 if (xpos[HOME]) {
 4250:                                     tmp3[0] = ';';
 4251:                                     
 4252:                                     intstr (&tmp3[1], xpos[HOME] + 1);
 4253:                                     stcat (argptr, tmp3);
 4254:                                 }
 4255: 
 4256:                                 stcat (argptr, "H\201");
 4257:                                 write_m (argptr);
 4258:                                 
 4259:                                 io = i;
 4260:                             }
 4261:                             break;
 4262:                         
 4263:                         case 9:
 4264:                             i = 0;
 4265:                             j = 0;
 4266: 
 4267:                             while ((ch = argptr[i++]) != EOL) LineTerm[j++] = ch;
 4268:                             
 4269:                             LineTerm[j] = EOL;
 4270:                             break;
 4271:                         
 4272:                         case 10:
 4273:                             BrkKey = (*argptr);
 4274:                             
 4275:                             /* make new break active */
 4276:                             set_io (UNIX);
 4277:                             set_io (MUMPS);
 4278:                     }
 4279:                 }
 4280:                 
 4281:                 setpiece = FALSE;
 4282:                 codptr++;
 4283:                 
 4284:                 break;
 4285:             }
 4286:             else if (*codptr == ':') {
 4287:                 codptr++;
 4288:                 
 4289:                 if (io == HOME) {           /* old syntax: enable/disable echo */
 4290:                     expr (STRING);
 4291:                 
 4292:                     if (merr () > OK) goto err;
 4293:                     
 4294:                     if (tvexpr (argptr)) {
 4295:                         DSW &= ~BIT0;
 4296:                     }
 4297:                     else {
 4298:                         DSW |= BIT0;
 4299:                     }
 4300: 
 4301:                 }
 4302:                 else {
 4303: 
 4304:                     if (*codptr == '(') {
 4305:                         codptr++;
 4306:                         setpiece = TRUE;
 4307:                     }
 4308: 
 4309:                     j = 1;
 4310:                     
 4311:                     while (*codptr != ')') {
 4312: 
 4313:                         if (*codptr == ':') {
 4314:                             codptr++;
 4315:                             j++;
 4316:                             
 4317:                             continue;
 4318:                         }
 4319:                         else if (setpiece == FALSE) {
 4320:                             merr_raise (SPACER);
 4321:                             goto err;
 4322:                         }
 4323: 
 4324:                         expr (STRING);
 4325:                     
 4326:                         if (merr () > OK) {
 4327:                             setpiece = FALSE;
 4328:                             goto err;
 4329:                         }
 4330:                     
 4331:                         switch (j) {
 4332:                             
 4333:                             case 1:
 4334:                                 fseek (opnfile[io], (long) intexpr (argptr), 0);
 4335:                                 break;
 4336: 
 4337:                             case 2:
 4338:                                 frm_crlf[io] = tvexpr (argptr);
 4339:                                 break;
 4340:                             
 4341:                             case 3:
 4342:                                 fm_nodelay[io] = tvexpr (argptr);
 4343:                                 break;
 4344:                         }
 4345:                     
 4346:                         if (setpiece == FALSE) break;
 4347:                     }
 4348:                     
 4349:                     if (setpiece) {
 4350:                         codptr++;
 4351:                         setpiece = FALSE;
 4352:                     }
 4353: 
 4354:                     break;
 4355:                 }
 4356:             }
 4357:             break;
 4358: 
 4359: 
 4360: use_socket:
 4361:             {
 4362:                 char use_parm[256];
 4363:                 int upct = 0;                
 4364: 
 4365:                 if (*codptr == ':') {
 4366:                     codptr++;
 4367:                 }
 4368:                 else {
 4369:                     while ((ch = *(codptr++)) != SP && ch != EOL);
 4370:                     codptr--;
 4371:                     break;
 4372:                 }
 4373: 
 4374:                 if (*codptr != '/') {
 4375:                     merr_raise (ARGLIST);
 4376:                     goto err;
 4377:                 }
 4378: 
 4379:                 codptr++;
 4380: 
 4381:                 while ((ch = *codptr++) != SP && ch != EOL && isalpha (ch)) {
 4382:                     use_parm[upct++] = ch;
 4383:                 }
 4384: 
 4385:                 use_parm[upct] = NUL;
 4386: 
 4387:                 for (upct = 0; upct < strlen (use_parm); upct++) {
 4388:                     use_parm[upct] = toupper (use_parm[upct]);
 4389:                 }
 4390: 
 4391:                 if (strcmp (use_parm, "CONNECT") == 0) {
 4392: 
 4393:                     msck_connect (io);
 4394: 
 4395:                     if (merr () > OK) goto err;
 4396: 
 4397:                 }
 4398:                 else if (strcmp (use_parm, "BIND") == 0) {
 4399:                     write_m("BIND\r\n\201");
 4400:                 }
 4401:                 else {
 4402:                     merr_raise (ARGLIST);
 4403:                     goto err;
 4404:                 }
 4405: 
 4406:                 break;
 4407: 
 4408:             }
 4409: 
 4410:         case OPEN:
 4411: 
 4412:             {                
 4413:                 short k;
 4414: 
 4415:                 if (*codptr == SP || *codptr == EOL) {
 4416:                     merr_raise (FILERR);
 4417:                     goto err;
 4418:                 }
 4419: 
 4420:                 expr (STRING);
 4421:                 k = intexpr (argptr);
 4422:                 
 4423:                 if (merr () > OK) goto err;
 4424: 
 4425:                 
 4426:                 if (k < 0 || k > MAXDEV) {
 4427:                     merr_raise (NODEVICE);
 4428:                     goto err;
 4429:                 }
 4430: 
 4431:                 if (k > MAXSEQ) goto open_socket;
 4432: 
 4433:                 if (restricted_mode) {
 4434:                     merr_raise (NOSTAND);
 4435:                     goto err;
 4436:                 }
 4437: 
 4438:                 /* need to evaluate the following 6 lines carefully - smw 2023-10-15 */
 4439:                 if (k != HOME) {
 4440:                     frm_crlf[k] = FALSE;
 4441:                     fm_nodelay[k] = FALSE;
 4442:                     xpos[k] = 0;
 4443:                     ypos[k] = 0;
 4444:                 }
 4445:                 
 4446:                 /* OPEN implies a previous CLOSE on same channel */
 4447:                 if ((k != HOME) && devopen[k]) {
 4448:                     
 4449:                     fclose (opnfile[k]);
 4450:                     devopen[k] = 0;
 4451:                 
 4452:                     if (io == k) io = HOME;
 4453:                 }
 4454: 
 4455:                 /* process device parameters on HOME at USE command. */
 4456:                 if (k == HOME && *codptr == ':' && *(codptr + 1) == '(') goto use0;
 4457:                 
 4458:                 if (*codptr != ':') {
 4459: 
 4460:                     if (k == HOME) break;
 4461:                     
 4462:                     if (dev[k][0] == EOL) {
 4463:                         merr_raise (FILERR);
 4464:                         merr_set_iochan_err (k, FILERR, "file not found");
 4465:                         goto err;
 4466:                     }
 4467: 
 4468:                     goto open10;
 4469:                 }
 4470: 
 4471:                 codptr++;
 4472:                 
 4473:                 if (k == HOME) {
 4474: 
 4475:                     if (*codptr != ':') {           /* turn echo on/off */
 4476:                         
 4477:                         expr (STRING);
 4478:                         
 4479:                         if (merr () > OK) goto err;
 4480: 
 4481:                         if (tvexpr (argptr)) {
 4482:                             DSW &= ~BIT0;
 4483:                         }
 4484:                         else {
 4485:                             DSW |= BIT0;
 4486:                         }
 4487:                     }
 4488: 
 4489:                     if (*codptr == ':') {           /* dummy timeout on HOME */
 4490:                         codptr++;
 4491: 
 4492:                         if (*codptr != SP && *codptr != EOL) {
 4493:                             expr (STRING);
 4494:                     
 4495:                             if (merr () > OK) goto err;
 4496:                         
 4497:                             test = TRUE;
 4498:                             break;
 4499:                         }
 4500:                         else {
 4501:                             merr_raise (INVEXPR);
 4502:                             goto err;
 4503:                         }
 4504:                     }
 4505:                 }
 4506:                 else {
 4507:                     int op_pos;
 4508: 
 4509:                     expr (STRING);
 4510: 
 4511:                     if (merr () > OK) goto err;
 4512:                     
 4513:                     stcpy (dev[k], argptr);
 4514:                     frm_timeout = (-1L);
 4515:                     
 4516:                     if (*codptr == ':') {
 4517:                         
 4518:                         codptr++;
 4519: 
 4520:                         expr (STRING);                        
 4521:                         frm_timeout = intexpr (argptr);
 4522:                         
 4523:                         if (merr () > OK) goto err;
 4524:                         if (frm_timeout < 0L) frm_timeout = 0L;
 4525:                     }
 4526: 
 4527: open10:
 4528: 
 4529:                     j = stcpy (tmp, dev[k]);
 4530:                     i = dev[k][j - 1];
 4531:                     
 4532:                     while (--j >= 0) {
 4533:                         if (dev[k][j] == '/') break;
 4534:                     }
 4535: 
 4536:                     stcpy (tmp2, dev[k]);
 4537:                     
 4538:                     if (j <= 0) {
 4539:                         tmp2[stlen (tmp2)] = NUL;
 4540:                         tmp[1] = 'r';
 4541:                         i = '+';
 4542:                     }                  
 4543:                     else { /* default is read+write */
 4544:                         tmp2[j] = NUL;
 4545: 
 4546:                         j = stcpy (&tmp[1], &tmp[j + 1]);
 4547:                         
 4548:                         tmp[0] = SP;
 4549:                         tmp[j + 1] = SP;
 4550:                         tmp[j + 2] = EOL;
 4551:                         
 4552:                         j = 0;
 4553:                         
 4554:                         while ((ch = tmp[++j]) != EOL) if (ch >= 'A' && ch <= 'Z') tmp[j] = ch + 32;
 4555:                         
 4556:                         if (find (" r w a r+ w+ a+ read write append read+ write+ append+ \201", tmp) == FALSE) {
 4557:                             tmp[1] = 'r';
 4558:                             i = '+';
 4559:                         
 4560:                             tmp2[strlen (tmp2)] = '/';
 4561:                         }
 4562:                     }
 4563: 
 4564:                     tmp[0] = tmp[1];
 4565:                     tmp[1] = NUL;   /* NUL not EOL !!! */
 4566:                     
 4567:                     if (i == '+') {
 4568:                         tmp[1] = i;
 4569:                         tmp[2] = NUL;
 4570:                     }
 4571: 
 4572:                     op_pos = 0;
 4573: 
 4574:                 open20:
 4575:                     
 4576:                     if (oucpath[op_pos] != EOL) {
 4577: 
 4578:                         j = stlen (dev[k]);
 4579:                         
 4580:                         while (--j >= 0) if (dev[k][j] == '/') break;                        
 4581:                         while (--j >= 0) if (dev[k][j] == '/') break;
 4582:                         
 4583:                         if (j < 0) {
 4584: 
 4585:                             strcpy (tmp3, tmp2);
 4586:                             stcpy (tmp2, &oucpath[op_pos]);
 4587:                             
 4588:                             j = 0;
 4589:                             while (tmp2[j] != ':' && tmp2[j] != EOL) j++;
 4590: 
 4591:                             tmp2[j] = EOL;
 4592:                             
 4593:                             stcpy (act_oucpath[k], tmp2);
 4594:                             op_pos += j;
 4595:                             
 4596:                             if (j) tmp2[j++] = '/';
 4597: 
 4598:                             strcpy (&tmp2[j], tmp3);
 4599:                         }
 4600:                     }
 4601: 
 4602:                     /* r  = READ only access;
 4603:                     * w  = WRITE new file;
 4604:                     * a  = WRITE append;
 4605:                     * r+ = READ/WRITE access;
 4606:                     * w+ = WRITE new file;
 4607:                     * a+ = WRITE append;
 4608:                     */
 4609:                     j = tmp[0];
 4610:                     sq_modes[k] = j;
 4611: 
 4612:                     if (j == 'r' && tmp[1] == '+') {
 4613:                         sq_modes[k] = '+';
 4614:                     }
 4615:                     
 4616:                     if (j == 'r' && frm_timeout < 0L) {
 4617: 
 4618:                         errno = 0;
 4619:                         
 4620:                         while ((opnfile[k] = fopen (tmp2, tmp)) == NULL) {
 4621:                             
 4622:                             if (errno == EINTR) {
 4623:                                 errno = 0;
 4624:                                 continue;
 4625:                             }       /* interrupt */
 4626:                             
 4627:                             if (errno == EMFILE || errno == ENFILE) {
 4628:                                 close_all_globals ();
 4629:                                 continue;
 4630:                             }
 4631: 
 4632:                             if (dev[k][0] != '/' && oucpath[op_pos++] != EOL) {
 4633:                                 strcpy (tmp2, tmp3);
 4634:                                 goto open20;
 4635:                             }
 4636: 
 4637:                             act_oucpath[k][0] = EOL;
 4638:                             merr_raise ((errno == ENOENT ? FILERR : PROTECT));
 4639: 
 4640:                             switch (merr ()) {
 4641:                                 
 4642:                                 case FILERR:
 4643:                                     merr_set_iochan_err (k, FILERR, "file not found");
 4644:                                     break;
 4645: 
 4646:                                 case PROTECT:
 4647:                                     merr_set_iochan_err (k, PROTECT, "file protection violation");
 4648:                                     break;
 4649: 
 4650:                             }
 4651:                             
 4652:                             goto err;
 4653:                         }
 4654:                         
 4655:                         ssvn_job_add_device (k, tmp2);                         
 4656:                         
 4657:                         devopen[k] = ((i == '+') ? i : j);
 4658:                         break;
 4659:                     }
 4660: 
 4661:                     if (j == 'r' || j == 'w' || j == 'a') {
 4662:                         
 4663:                         if (frm_timeout >= 0L) {
 4664:                             
 4665:                             test = TRUE;
 4666:                             
 4667:                             if (setjmp (sjbuf)) {
 4668:                                 test = FALSE;
 4669:                                 goto endopn;
 4670:                             }
 4671:                             
 4672:                             sig_attach (SIGALRM, &ontimo);
 4673:                             alarm ((unsigned) (frm_timeout < 3 ? 3 : frm_timeout));
 4674:                         }
 4675: 
 4676:                         for (;;) {
 4677:                             errno = 0;
 4678: 
 4679:                             if ((opnfile[k] = fopen (tmp2, tmp)) != NULL) break;
 4680:                             if (merr () == INRPT) goto err;
 4681:                             if (errno == EINTR) continue;   /* interrupt */
 4682:                             
 4683:                             if (errno == EMFILE || errno == ENFILE) {
 4684:                                 close_all_globals ();
 4685:                                 continue;
 4686:                             }
 4687: 
 4688:                             if (frm_timeout < 0L) {
 4689: 
 4690:                                 if (dev[k][0] != '/' && oucpath[op_pos++] != EOL) {
 4691:                                     strcpy (tmp2, tmp3);
 4692:                                     goto open20;
 4693:                                 }
 4694: 
 4695:                                 if (errno == ENOENT) continue;
 4696: 
 4697:                                 act_oucpath[k][0] = EOL;
 4698:                                 merr_raise (PROTECT);
 4699: 
 4700:                                 merr_set_iochan_err (k, PROTECT, "file protection violation");
 4701:                                 
 4702:                                 goto err;
 4703:                             }
 4704: 
 4705:                             if (frm_timeout == 0L) {
 4706:                                 test = FALSE;
 4707:                                 goto endopn;
 4708:                             }
 4709: 
 4710:                             sleep (1);
 4711:                             frm_timeout--;
 4712:                         }
 4713: 
 4714:                         devopen[k] = ((i == '+') ? i : j);
 4715:                         endopn:;
 4716:                         
 4717:                         alarm (0);  /* reset alarm request */
 4718:                     }
 4719:                     else {
 4720:                         merr_raise (ARGLIST);
 4721:                         merr_set_iochan_err (k, ARGLIST, "invalid argument");
 4722:                         goto err;
 4723:                     }
 4724:                 }
 4725: 
 4726: 
 4727: open_socket:
 4728:                 if (*codptr != ':') {
 4729:                     if (j == 'w') {
 4730:                         merr_raise (FILEXWR);
 4731:                         merr_set_iochan_err (k, FILEXWR, "cannot open existing file for WRITE");
 4732:                     }
 4733:                     else {
 4734:                         merr_raise (ARGLIST);
 4735:                         merr_set_iochan_err (k, ARGLIST, "invalid argument");
 4736:                     }
 4737:                     goto err;
 4738:                 }
 4739: 
 4740:                 codptr++;
 4741:                 expr (STRING);
 4742: 
 4743:                 if (merr () > OK) goto err;
 4744: 
 4745: 
 4746:                 stcpy (vn, argptr);
 4747:                 stcnv_m2c (vn);
 4748: 
 4749:                 msck_open (k, vn);
 4750: 
 4751:                 if (merr () > OK) goto err;
 4752:                 
 4753:                 ssvn_job_add_device (k, vn);
 4754:                 
 4755:                 break; 
 4756:             }
 4757:             break;
 4758: 
 4759:           
 4760: 
 4761: 
 4762: 
 4763:         case CLOSE:
 4764: 
 4765:             /* no arguments: close all exept HOME */
 4766:             if (*codptr == SP || *codptr == EOL) {
 4767: 
 4768:                 if (rtn_dialect () != D_FREEM) {
 4769:                     merr_raise (NOSTAND);
 4770:                     break;
 4771:                 }
 4772: 
 4773:                 j = 1;
 4774:                 
 4775:                 while (j <= MAXDEV) {
 4776:                     
 4777:                     if (j < FIRSTSCK) {
 4778:                         if (jour_flag && (j == 2)) {
 4779:                             j++;
 4780:                             continue;
 4781:                         }
 4782:                 
 4783:                         if (devopen[j]) fclose (opnfile[j]);
 4784: 
 4785:                         ssvn_job_remove_device (j);
 4786:                         
 4787:                         devopen[j++] = 0;
 4788:                     }
 4789:                     else {
 4790:                         msck_close (j++);
 4791:                     }
 4792: 
 4793:                 }
 4794: 
 4795:                 io = HOME;
 4796:                 break;
 4797:             }
 4798: 
 4799:             expr (STRING);
 4800:             j = intexpr (argptr);
 4801: 
 4802:             if (merr () > OK) break;
 4803: 
 4804:             if (j >= FIRSTSCK && j < MAXDEV) {
 4805:                 msck_close (j);
 4806:                 ssvn_job_remove_device (j);
 4807:                 break;
 4808:             }
 4809: 
 4810:             /*ignore close on illgal units */
 4811:             if ((j >= 0 && j <= MAXDEV && j != HOME) && (jour_flag == 0 || (j != 2))) {           /*ignore close on protocol channel */
 4812:                 
 4813:                 if (devopen[j]) fclose (opnfile[j]);
 4814:                 
 4815:                 devopen[j] = 0;
 4816:                 
 4817:                 ssvn_job_remove_device (j);
 4818:                 
 4819:                 if (io == j) io = HOME;
 4820: 
 4821:             }
 4822: 
 4823:             /* parse any 'device parameters', but ignore them otherwise */
 4824:             if (*codptr == ':') {
 4825:                 if (*++codptr != '(') {
 4826:                     expr (STRING);
 4827:                 }
 4828:                 else {
 4829:                     setpiece = TRUE;    /* to avoid bracket error at end of deviceparameters */
 4830:                     for (;;)
 4831:                     {
 4832:                     if (*++codptr != ':')
 4833:                     expr (STRING);
 4834:                     if (*codptr == ':')
 4835:                     continue;
 4836:                     if (*codptr++ != ')')
 4837:                     merr_raise (ARGER);
 4838:                     break;
 4839:                     }
 4840:                     setpiece = FALSE;
 4841:                 }
 4842:             }
 4843: 
 4844:             break;
 4845: 
 4846:         case ZHALT:     /* ZHALT */
 4847:             
 4848:             if (is_standard ()) {
 4849:                 merr_raise (NOSTAND);
 4850:                 goto err;
 4851:             }
 4852:             
 4853:         case HA:            /* HALT or HANG */
 4854: 
 4855: 
 4856:             /* no arguments: HALT */
 4857:             if (*codptr == SP || *codptr == EOL || mcmnd == ZHALT) {
 4858: 
 4859:                 if (mcmnd == ZHALT && *codptr != SP && *codptr != EOL) {
 4860:                     expr (STRING);
 4861:                     i = intexpr (argptr);
 4862:                 
 4863:                     if (merr () > OK) break;
 4864:                 }
 4865:                 else {
 4866:                     halt:i = 0;
 4867:                 }
 4868: 
 4869:                 cleanup ();
 4870:                 
 4871:                 if (father) {           /* advertise death to parent *//* make sure father is waiting !!! */
 4872:                     if ((time (0L) - jobtime) < 120) sleep (2);
 4873:                     
 4874:                     kill (father, SIGUSR1);
 4875:                 }
 4876: 
 4877:                 exit (i);       /* terminate mumps */
 4878:             };
 4879:             /* with arguments: HANG */
 4880: 
 4881: 
 4882:         case HANG:          /* HANG */
 4883: 
 4884:             {
 4885:                 unsigned long int waitsec;
 4886:                 int millisec;
 4887:                 
 4888: #ifdef USE_GETTIMEOFDAY
 4889:                 struct timeval timebuffer;
 4890: #else
 4891:                 struct timeb timebuffer;
 4892: #endif
 4893: 
 4894:                 expr (STRING);
 4895:                 numlit (argptr);
 4896: 
 4897:                 if (merr () > OK) break;
 4898: 
 4899: #if !defined(__linux__)                
 4900:                 if (argptr[0] == '-') break;      /* negative values without effect */
 4901:                 if (argptr[0] == '0') break;      /* zero without effect */
 4902: #else
 4903:                 /* on linux, return scheduler timeslice to kernel scheduler for hang 0 and hang with negative values
 4904:                    for compatibility with Reference Standard M, only when process is using a realtime scheduling policy */
 4905:                 if ((argptr[0] == '-') || (argptr[0] == '0')) {                    
 4906:                     int policy;
 4907: 
 4908:                     policy = sched_getscheduler (0);
 4909:                     if ((policy == -1) || ((policy != SCHED_FIFO) && (policy != SCHED_RR))) break;
 4910: 
 4911:                     sched_yield ();
 4912:                 }
 4913: #endif
 4914:                 
 4915:                 waitsec = 0;
 4916:                 millisec = 0;
 4917:                 i = 0;
 4918:                 
 4919:                 for (;;) {       /* get integer and fractional part */ 
 4920:                     
 4921:                     if ((ch = argptr[i++]) == EOL) break;
 4922:                     
 4923:                     if (ch == '.') {
 4924:                         millisec = (argptr[i++] - '0') * 100;
 4925:                     
 4926:                         if ((ch = argptr[i++]) != EOL) {
 4927:                             millisec += (ch - '0') * 10;
 4928:         
 4929:                             if ((ch = argptr[i]) != EOL) {
 4930:                                 millisec += (ch - '0');
 4931:                             }
 4932:                         }
 4933:                     
 4934:                         break;
 4935:                     }
 4936: 
 4937:                     waitsec = waitsec * 10 + ch - '0';
 4938:                 }
 4939: 
 4940:                 if ((i = waitsec) > 2) i -= 2;
 4941: 
 4942: #ifdef USE_GETTIMEOFDAY
 4943:                 gettimeofday (&timebuffer, NULL);   /* get current time */
 4944: 
 4945:                 waitsec += timebuffer.tv_sec;   /* calculate target time */
 4946:                 millisec += timebuffer.tv_usec;
 4947: #else
 4948:                 ftime (&timebuffer);    /* get current time */
 4949:                 
 4950:                 waitsec += timebuffer.time; /* calculate target time */
 4951:                 millisec += timebuffer.millitm;
 4952: #endif
 4953: 
 4954:                 if (millisec >= 1000) {
 4955:                     waitsec++;
 4956:                     millisec -= 1000;
 4957:                 }
 4958: 
 4959:                 /* do the bulk of the waiting with sleep() */
 4960:                 while (i > 0) {
 4961:                     j = time (0L);
 4962:                     sleep ((unsigned) (i > 32767 ? 32767 : i)); /* sleep max. 2**15-1 sec */
 4963:                     i -= time (0L) - j; /* subtract actual sleeping time */
 4964: 
 4965:                     if (merr () == INRPT) goto err;
 4966: 
 4967:                     if (evt_async_enabled && (merr () == ASYNC)) goto err;
 4968:                 }
 4969: 
 4970:                 /* do the remainder of the waiting watching the clock */
 4971:                 for (;;) {
 4972:                 
 4973: #ifdef USE_GETTIMEOFDAY
 4974:                 
 4975:                     gettimeofday (&timebuffer, NULL);
 4976:                 
 4977:                     if (timebuffer.tv_sec > waitsec) break;
 4978:                     if (timebuffer.tv_sec == waitsec && timebuffer.tv_usec >= millisec) break;
 4979: #else
 4980:                     ftime (&timebuffer);
 4981: 
 4982:                     if (timebuffer.time > waitsec) break;
 4983:                     if (timebuffer.time == waitsec && timebuffer.millitm >= millisec) break;
 4984: #endif
 4985:                     if (merr () == INRPT) goto err;
 4986:                     
 4987:                 }
 4988:             }
 4989:             break;
 4990: 
 4991: 
 4992:         case HALT:          /* HALT */
 4993: 
 4994:             if (*codptr == SP || *codptr == EOL) goto halt;
 4995:             
 4996:             merr_raise (ARGLIST);
 4997:             break;
 4998: 
 4999: 
 5000:         case BREAK:
 5001: 
 5002:             
 5003:             if (*codptr == SP || *codptr == EOL) {
 5004:                 
 5005:                 if (breakon == FALSE) break;      /* ignore BREAK */
 5006:                 
 5007:                 if (usermode == 0) {
 5008:                     merr_raise (BKERR);
 5009:                     goto err;
 5010:                 }
 5011:                 
 5012:                 zbflag = TRUE;
 5013:                 merr_raise (OK - CTRLB);
 5014:                 zb_entry:loadsw = TRUE;
 5015:                 
 5016: #ifdef DEBUG_NEWSTACK
 5017:                 printf ("CHECK 08 (Stack PUSH)\r\n");
 5018: #endif
 5019:                 
 5020: 
 5021: 
 5022:                 if (++nstx > NESTLEVLS) {
 5023:                     nstx--;
 5024:                     merr_raise (STKOV);
 5025:                 
 5026:                     goto err;
 5027:                 }
 5028:                 else {
 5029:                     estack++;
 5030:                 }
 5031: 
 5032:                 nestc[nstx] = BREAK;
 5033: 
 5034: #ifdef DEBUG_NEWSTACK
 5035: 
 5036:                 if (!cmdptr) printf ("CMDPTR is ZERO!\r\n");
 5037: 
 5038: #endif
 5039: 
 5040:                 nestp[nstx] = cmdptr;   /* command stack address */
 5041:                 nestn[nstx] = 0;    /*!!! save name */
 5042:                 nestr[nstx] = roucur - rouptr;  /* save roucur */
 5043:                 nestnew[nstx] = 0;
 5044:                 ztrap[nstx][0] = EOL;
 5045:                 nestlt[nstx] = level;
 5046:                 level = 0;      /* save level */
 5047:                 /* save BREAK information   */
 5048:                 brkstk[nstx] = (((ECHOON ? 1 : 0) << 1) | test) << 3 | io;
 5049: 
 5050:                 io = HOME;
 5051:                 forsw = FALSE;
 5052:                 cmdptr += stcpy (cmdptr, codptr) + 1;
 5053:                 zerr = BKERR;
 5054:                 goto restart;
 5055:             }
 5056: 
 5057:             if (is_standard ()) {
 5058:                 merr_raise (NOSTAND);
 5059:                 goto err;
 5060:             }
 5061:             
 5062:             expr (STRING);
 5063:             if (merr () > OK) break;
 5064: 
 5065:             switch (intexpr (argptr)) {
 5066:                 
 5067:                 case 2:
 5068:                     DSM2err = TRUE;
 5069:                     break;      /* enable DSM V 2 error processing */
 5070:                 
 5071:                 case -2:
 5072:                     DSM2err = FALSE;
 5073:                     break;      /* enable normal error processing  */
 5074:                 
 5075:                 case 0:
 5076:                     breakon = FALSE;
 5077:                     break;      /* disable CTRL/C */
 5078:                 
 5079:                 default:
 5080:                     breakon = TRUE;
 5081:                     break;      /* enable CTRL/C  */
 5082:             }
 5083:             break;
 5084: 
 5085:         case VIEW:
 5086: 
 5087:             view_com ();
 5088: 
 5089:             if (repQUIT) {           /* VIEW 26: repeated QUIT action */
 5090:                 
 5091:                 while (repQUIT-- > 0) {
 5092: 
 5093: #ifdef DEBUG_NEWSTACK
 5094:                     printf ("CHECK 09 (Stack POP)\r\n");
 5095: #endif
 5096: 
 5097:                     if (nestc[nstx] == BREAK) {
 5098: //                        printf ("nestc[nstx] was BREAK\r\n");
 5099:                         if (repQUIT) continue;
 5100:                         merr_raise (OK - CTRLB);
 5101:                         
 5102:                         goto zgo;   /*cont. single step */
 5103:                     }
 5104: //                    else {
 5105: //                        printf ("nestc[nstx] was _not_ BREAK\r\n");
 5106: //                    }
 5107: 
 5108:                     if (nestc[nstx] == FOR) {
 5109: 
 5110:                         stcpy (code, cmdptr = nestp[nstx--]);
 5111:                         estack--;
 5112:                         
 5113:                         codptr = code;
 5114:                         ftyp = fortyp[--forx];
 5115:                         fvar = forvar[forx];
 5116:                         finc = forinc[forx];
 5117:                         flim = forlim[forx];
 5118:                         fi = fori[forx];
 5119:                         
 5120:                         if (repQUIT) continue;
 5121:                         if ((forsw = (nestc[nstx] == FOR))) goto for_end;
 5122: 
 5123:                         goto next_line;
 5124:                     }
 5125: 
 5126:                     if (nestn[nstx]) {       /* reload routine */
 5127:                         namptr = nestn[nstx];
 5128:                         
 5129:                         if ((nestc[nstx] != XECUTE) || loadsw) {
 5130:                             stcpy (rou_name, namptr);
 5131:                             zload (rou_name);
 5132: 
 5133:                             ssvn_job_update ();
 5134:                             
 5135:                             dosave[0] = 0;
 5136:                         }
 5137: 
 5138:                         namptr--;
 5139:                     }
 5140: 
 5141:                     if (nestnew[nstx]) unnew ();   /* un-NEW variables */
 5142:                     
 5143:                     /* restore old pointers */
 5144:                     if ((mcmnd = nestc[nstx]) == BREAK) {
 5145:                         if (repQUIT) continue;
 5146:                         
 5147:                         goto restore;
 5148:                     }       /*cont. single step */
 5149:                     
 5150:                     if (mcmnd == DO_BLOCK) {
 5151:                         test = nestlt[nstx];
 5152:                         level--;
 5153:                     }                
 5154:                     else { /* pop $TEST */
 5155:                         level = nestlt[nstx];   /* pop level */
 5156:                     }
 5157: 
 5158:                     roucur = nestr[nstx] + rouptr;
 5159:                     stcpy (codptr = code, cmdptr = nestp[nstx--]);
 5160:                     estack--;
 5161:                     forsw = (nestc[nstx] == FOR);
 5162: 
 5163: 
 5164:                     loadsw = TRUE;
 5165: 
 5166:                     if (mcmnd == '$') {
 5167:                         if (repQUIT) return 0;
 5168:                         merr_raise (NOVAL);
 5169:                     }
 5170:                 }
 5171:                 repQUIT = 0;
 5172:             }
 5173:             break;
 5174: 
 5175:         /* Z-COMMANDS */
 5176:         case ZGO:
 5177: 
 5178:             /* ZGO with arguments: same as GOTO but with BREAK on */
 5179:             if (*codptr != EOL && *codptr != SP) {
 5180:                 mcmnd = GOTO;
 5181:                 zbflag = TRUE;
 5182:                 merr_raise (OK - CTRLB);
 5183:                 
 5184:                 goto do_goto;
 5185:             }
 5186: 
 5187:             /* argumentless ZGO resume execution after BREAK */
 5188: 
 5189:             if (nestc[nstx] != BREAK) {
 5190:                 merr_raise (LVLERR);
 5191:                 break;
 5192:             }
 5193: 
 5194: 
 5195: 
 5196:             merr_clear ();      /* stop BREAKing */
 5197: 
 5198: zgo:
 5199: 
 5200: #ifdef DEBUG_NEWSTACK
 5201:             printf ("Zgoing: (Stack POP)\r\n");
 5202: #endif
 5203: 
 5204: 
 5205: 
 5206:             if (nestn[nstx]) {           /* reload routine */
 5207:                 stcpy (rou_name, (namptr = nestn[nstx]));
 5208:                 zload (rou_name);
 5209: 
 5210:                 ssvn_job_update ();
 5211: 
 5212:                 if (merr () > OK) break;
 5213:             }
 5214: 
 5215:             level = nestlt[nstx];
 5216:             roucur = nestr[nstx] + rouptr;
 5217:             io = brkstk[nstx];
 5218:             
 5219:             if (io & 020) {
 5220:                 DSW &= ~BIT0;
 5221:             }
 5222:             else {
 5223:                 DSW |= BIT0;        /* restore echo state */
 5224:             }
 5225: 
 5226:             test = (io & 010) >> 3; /* restore $TEST */
 5227: 
 5228:             /* restore $IO; default to HOME if channel not OPEN */
 5229:             if ((io &= 07) != HOME && devopen[io] == 0) io = HOME;
 5230:             
 5231:             stcpy (codptr = code, cmdptr = nestp[nstx--]);
 5232:             estack--;
 5233:             
 5234:             forsw = (nestc[nstx] == FOR);
 5235: 
 5236: 
 5237:             loadsw = TRUE;
 5238:             zbflag = FALSE;
 5239:             
 5240:             goto next0;
 5241: 
 5242: 
 5243:         case ZBREAK:
 5244: 
 5245:             if (*codptr == SP || *codptr == EOL) {
 5246:                 merr_raise (ARGLIST);
 5247:                 break;
 5248:             }
 5249: 
 5250:             expr (STRING);
 5251:             if (merr () > OK) break;
 5252: 
 5253:             zbreakon = tvexpr (argptr);
 5254:             if (hardcopy == DISABLE) set_zbreak (zbreakon ? STX : -1);   /* enable/disable CTRL/B */
 5255: 
 5256:             zbflag = FALSE;
 5257:             break;
 5258: 
 5259: 
 5260: 
 5261:     
 5262:         case ZLOAD:
 5263: 
 5264:             if (*codptr == EOL || *codptr == SP) {
 5265:                 stcpy (varnam, rou_name);
 5266:             }
 5267:             else {
 5268:                 expr (NAME);
 5269:             
 5270:                 if (merr () > OK) break;
 5271:             
 5272:                 codptr++;
 5273:             }
 5274: 
 5275:             dosave[0] = EOL;
 5276: 
 5277:             if (varnam[0] == EOL) {
 5278:                 varerr[0] = EOL;
 5279:                 merr_raise (NOPGM);
 5280:                 break;
 5281:             }           /*error */
 5282: 
 5283:             loadsw = TRUE;
 5284: 
 5285:             /* a ZLOAD on the active routine always loads from disk */
 5286:             if (stcmp (varnam, rou_name) == 0) {                
 5287:                 for (i = 0; i < NO_OF_RBUF; i++) {
 5288:             
 5289:                     if (rouptr == (buff + (i * PSIZE0))) {
 5290:                         pgms[i][0] = EOL;
 5291:             
 5292:                         break;
 5293:                     }
 5294:                 }
 5295:             }
 5296: 
 5297:             zload (varnam);
 5298: 
 5299:             if (merr () > OK) break;          /* load file */
 5300: 
 5301:             stcpy (rou_name, varnam);
 5302:             ssvn_job_update ();
 5303: 
 5304:             break;
 5305: 
 5306:         case ZSAVE:
 5307: 
 5308:             if (*codptr == EOL || *codptr == SP) {
 5309: 
 5310:                 if (rou_name[0] == EOL) {
 5311:                     varerr[0] = EOL;
 5312:                     merr_raise (NOPGM);
 5313: 
 5314:                     break;
 5315:                 }           /*error */
 5316: 
 5317:                 stcpy (varnam, rou_name);
 5318:             }
 5319:             else {
 5320:                 expr (NAME);
 5321: 
 5322:                 if (varnam[0] == '^') merr_raise (GLOBER);
 5323:                 if (varnam[0] == '$') merr_raise (INVREF);
 5324:                 if (merr () > OK) break;
 5325:                 
 5326:                 stcpy (rou_name, varnam);
 5327:                 ssvn_job_update ();
 5328: 
 5329:                 codptr++;
 5330:             }
 5331: 
 5332:             zsave (varnam);
 5333:             break;
 5334: 
 5335: 
 5336:         case ZREMOVE:
 5337: 
 5338:             {
 5339:                 char *beg, *end;
 5340: 
 5341:                 dosave[0] = EOL;
 5342: 
 5343:                 if (*codptr == SP || *codptr == EOL) {           /* no args is ZREMOVE  all */
 5344:                     loadsw = TRUE;
 5345: 
 5346:                     for (i = 0; i < NO_OF_RBUF; i++) {
 5347: 
 5348:                         if (rouptr == buff + (i * PSIZE0)) {
 5349:                             pgms[i][0] = EOL;
 5350:                             break;
 5351:                         }
 5352: 
 5353:                     }
 5354: 
 5355:                     rouptr = buff + (i * PSIZE0);
 5356:                     rouend = rouins = rouptr;
 5357:                     roucur = buff + (NO_OF_RBUF * PSIZE0 + 1);
 5358:                     
 5359:                     *(rouptr) = EOL;
 5360:                     *(rouptr + 1) = EOL;
 5361:                     *(rouptr + 2) = EOL;
 5362:                     
 5363:                     argptr = partition;
 5364:                     rou_name[0] = EOL;
 5365: 
 5366:                     ssvn_job_update ();
 5367:                     
 5368:                     break;
 5369:                 }
 5370:                 if (*codptr == ':') {
 5371:                     beg = rouptr;
 5372:                 }
 5373:                 else if (*codptr == '*') {
 5374:                     beg = rouptr;
 5375:                 
 5376:                     while ((end = (beg + UNSIGN (*beg) + 2)) < rouins) beg = end;
 5377:                 
 5378:                     codptr++;
 5379:                 }
 5380:                 else {
 5381:                     lineref (&beg);
 5382:                     if (merr () > OK) break;
 5383:                 }
 5384: 
 5385:                 if ((end = beg) == 0) {
 5386:                     merr_raise (M13);
 5387:                     break;
 5388:                 }
 5389: 
 5390:                 if (*codptr == ':') {           /* same as above */
 5391:                     codptr++;
 5392:                 
 5393:                     if (*codptr == '*') {
 5394:                         end = rouins;
 5395:                         codptr++;
 5396:                     }
 5397:                     else if (*codptr == ',' || *codptr == SP || *codptr == EOL) {
 5398:                         end = rouend;
 5399:                     }
 5400:                     else {
 5401:                         lineref (&end);
 5402:                         
 5403:                         if (end == 0) merr_raise (M13);
 5404:                         if (merr () > OK) break;
 5405:                 
 5406:                         end = end + UNSIGN (*end) + 2;
 5407:                     }
 5408:                 }
 5409:                 else {
 5410:                     end = end + UNSIGN (*end) + 2;
 5411:                 }
 5412: 
 5413:                 if (beg < rouend) {           /* else there's nothing to zremove */
 5414: 
 5415:                     if (end >= rouend) {
 5416:                         end = rouend = beg;
 5417:                     }
 5418:                     else {
 5419:                         rouins = beg;
 5420: 
 5421:                         while (end <= rouend) *beg++ = (*end++);
 5422:                         
 5423:                         i = beg - end;
 5424:                         rouend += i;
 5425:                         
 5426:                         if (roucur > end) roucur += i;
 5427:                     }
 5428:                     
 5429:                     *end = EOL;
 5430:                     *(end + 1) = EOL;
 5431:                     
 5432:                     for (i = 0; i < NO_OF_RBUF; i++) {
 5433:                         if (rouptr == (buff + (i * PSIZE0))) {
 5434:                             ends[i] = rouend;
 5435:                             break;
 5436:                         }
 5437:                     }
 5438: 
 5439:                 }
 5440:                 break;
 5441:             }
 5442: 
 5443:         case ZINSERT:
 5444: 
 5445:             {
 5446:                 char *beg;
 5447: 
 5448:                 if (*codptr == EOL || *codptr == SP) {
 5449:                     merr_raise (ARGLIST);
 5450:                     break;
 5451:                 }           /*error */
 5452:                 
 5453:                 dosave[0] = EOL;
 5454: 
 5455:                 /* parse stringlit */
 5456:                 expr (STRING);
 5457:                 
 5458:                 if (merr () > OK) break;
 5459:                 
 5460:                 if (*codptr != ':') {
 5461:                     zi (argptr, rouins);
 5462:                     break;
 5463:                 }
 5464: 
 5465:                 stcpy (tmp, argptr);
 5466:                 codptr++;
 5467:                 lineref (&beg);
 5468:                 
 5469:                 if (merr () > OK) break;      /* parse label */
 5470:                 
 5471:                 if (beg) {
 5472:                     beg = beg + UNSIGN (*beg) + 2;
 5473:                 }
 5474:                 else {
 5475:                     beg = rouptr;
 5476:                 }
 5477:                 
 5478:                 if (beg > rouend + 1) {
 5479:                     merr_raise (M13);
 5480:                     break;
 5481:                 }
 5482: 
 5483:                 /* insert stuff */
 5484:                 zi (tmp, beg);
 5485:                 break;
 5486:             }
 5487: 
 5488: 
 5489:         /* PRINT is convenient -
 5490:         * but non-standard ZPRINT should be used instead */
 5491:         case 'p':
 5492: 
 5493:             if (is_standard ()) {
 5494:                 merr_raise (NOSTAND);
 5495:                 break;
 5496:             }
 5497: 
 5498: 
 5499:         case ZPRINT:
 5500:             
 5501:             {
 5502:                 char *beg, *end;
 5503: 
 5504:                 if (*codptr == SP || *codptr == EOL) {           /* no args is ZPRINT all */
 5505:                     beg = rouptr;
 5506:                     end = rouend;
 5507:                 }
 5508:                 else {
 5509:                     if (*codptr == ':') {
 5510:                         beg = rouptr;   /* from begin */
 5511:                     }
 5512:                     else if (*codptr == '*') {           /* from 'linepointer' */
 5513:                         beg = rouptr;
 5514:                         
 5515:                         while ((end = (beg + UNSIGN (*beg) + 2)) < rouins) beg = end;
 5516:                         codptr++;
 5517:                     }
 5518:                     else {
 5519:                         lineref (&beg);                        
 5520:                         if (merr () > OK) break;
 5521:                     }           /* line reference */
 5522:                     
 5523:                     if (beg == 0) {
 5524:                         beg = rouptr;
 5525:                         rouins = beg;
 5526:                         
 5527:                         if (*codptr != ':') break;
 5528:                     }
 5529: 
 5530:                     if (*codptr == ':') {
 5531:                         codptr++;   /* to end */
 5532:                     
 5533:                         if (*codptr == SP || *codptr == ',' || *codptr == EOL)
 5534:                             end = rouend;
 5535:                         else {
 5536:                             if (*codptr == '*') {
 5537:                                 end = rouins;
 5538:                                 codptr++;
 5539:                             }               
 5540:                             else {  /* to 'linepointer' */
 5541:                                 lineref (&end);
 5542:                     
 5543:                                 if (merr () > OK) break;  /* line reference */
 5544:                                 end = end + UNSIGN (*end) + 2;
 5545:                             }
 5546:                         }
 5547:                     }
 5548:                     else {
 5549:                         end = beg + 1;
 5550:                     }
 5551:                 }
 5552:                 if (rouend < end) end = rouend - 1;
 5553: 
 5554:                 for (; beg < end; beg += UNSIGN (*beg) + 2) {
 5555:                     
 5556:                     if (frm_crlf[io]) {
 5557:                         write_m ("\012\201");
 5558:                     }
 5559:                     else {
 5560:                         write_m ("\012\015\201");
 5561:                     }
 5562:                     
 5563:                     if ((*(beg + 1)) == EOL) break;
 5564:                     
 5565:                     write_m (beg + 1);
 5566:                     if (merr () > OK) break;
 5567:                 }
 5568:                 
 5569:                 rouins = beg;
 5570:             }
 5571: 
 5572:             if (frm_crlf[io]) {
 5573:                 write_m ("\012\201");
 5574:             }
 5575:             else {
 5576:                 write_m ("\012\015\201");
 5577:             }
 5578: 
 5579:             break;
 5580: 
 5581:         case WATCH:
 5582:             {
 5583:                 char op;
 5584: 
 5585: 
 5586:                 if (((ch = *codptr) == SP) || ch == EOL) {
 5587:                     
 5588:                     set_io(UNIX);                        
 5589:                     
 5590:                     if (dbg_enable_watch) {
 5591:                         printf ("Watchpoints disabled.\n"); 
 5592:                         dbg_enable_watch = 0;
 5593:                     }
 5594:                     else {
 5595:                         printf ("Watchpoints enabled.\n");
 5596:                         dbg_enable_watch = 1;
 5597:                     }
 5598:                     
 5599:                     break;        
 5600: 
 5601:                 }
 5602: 
 5603:                 if ((ch = *codptr) == '(') {
 5604:                     merr_raise (ARGLIST);
 5605:                     goto err;
 5606:                 }
 5607: 
 5608:                 for (;;) {
 5609: 
 5610:                     switch (ch) {
 5611:                         
 5612:                         case '?':
 5613:                         case '+':
 5614:                         case '-':
 5615:                             op = ch;
 5616:                             codptr++;
 5617:                             break;
 5618: 
 5619:                         default: 
 5620:                             merr_raise (ARGLIST);
 5621:                             goto err;
 5622:                     }
 5623: 
 5624:                     expr (NAME);                            /* try to interpret an mname */
 5625:                     
 5626:                     if (merr () > OK) goto err;
 5627: 
 5628:                     stcpy (vn, varnam);
 5629: 
 5630:                     switch (op) {
 5631:                         
 5632:                         case '+':
 5633:                             dbg_add_watch (vn);
 5634:                             break;
 5635: 
 5636:                         case '-':
 5637:                             dbg_remove_watch (vn);
 5638:                             break;
 5639: 
 5640:                         case '?':
 5641:                             dbg_dump_watch (vn);
 5642:                             break;
 5643: 
 5644:                     }                
 5645: 
 5646:                     if (merr () > OK) goto err;
 5647: 
 5648:                     if ((ch = *(codptr + 1)) == EOL) {
 5649:                         codptr++;
 5650:                         break;
 5651:                     }
 5652:                     else if ((ch = *(codptr + 1)) == ',') {
 5653:                         codptr += 2;
 5654:                         ch = *codptr;
 5655:                     }
 5656:                     else {
 5657:                         merr_raise (ARGLIST);
 5658:                         goto err;
 5659:                     }
 5660:                 } 
 5661:                 
 5662: 
 5663:                 break;
 5664:             }
 5665: 
 5666: 
 5667:         case ASSERT_TKN:
 5668:             {
 5669:                 expr (STRING);
 5670: 
 5671:                 if (merr () > OK) goto err;
 5672: 
 5673:                 if (tvexpr (argptr) == 0) {
 5674:                     merr_raise (ASSERT);
 5675:                     goto err;
 5676:                 }
 5677: 
 5678:                 break;
 5679:             }
 5680: 
 5681:         case ZWRITE:
 5682: 
 5683: 
 5684: zwrite:
 5685:             {
 5686:                 short k;
 5687:                 char w_tmp[512];
 5688:                 char zwmode;
 5689: 
 5690: 
 5691:                 if (io != HOME && devopen[io] == 'r') {
 5692:                     merr_raise (NOWRITE);
 5693:                     goto err;
 5694:                 }
 5695: 
 5696:                 tmp3[0] = SP;
 5697:                 tmp3[1] = EOL;
 5698:                 
 5699:                 if ((ch = (*codptr)) == '(') {    /* exclusive zwrite */
 5700: 
 5701:                     for (;;) {
 5702:                         
 5703:                         codptr++;
 5704:                         expr (NAME);
 5705:                         
 5706:                         if (merr () > OK) goto err;
 5707:                         if (varnam[0] == '^') {
 5708:                             merr_raise (GLOBER);
 5709:                             goto err;
 5710:                         }
 5711: 
 5712:                         i = 0;
 5713: 
 5714:                         while (varnam[i] != EOL) {
 5715:                             
 5716:                             if (varnam[i] == DELIM) {
 5717:                                 merr_raise (SBSCR);
 5718:                                 goto err;
 5719:                             }
 5720: 
 5721:                             i++;
 5722:                         }
 5723: 
 5724:                         if (stcat (tmp3, varnam) == 0) {
 5725:                             merr_raise (M75);
 5726:                             goto err;
 5727:                         }
 5728: 
 5729:                         if (stcat (tmp3, " \201") == 0) {
 5730:                             merr_raise (M75);
 5731:                             goto err;
 5732:                         }
 5733: 
 5734:                         if ((ch = *++codptr) == ')') {
 5735:                             codptr++;
 5736:                             break;
 5737:                         }
 5738: 
 5739:                         if (ch != ',') {
 5740:                             merr_raise (COMMAER);
 5741:                             goto err;
 5742:                         }
 5743:                     }
 5744:                 }
 5745:                 else {
 5746:                     if (ch != SP && ch != EOL) goto zwritep;
 5747:                 }
 5748: 
 5749:                 /* no arguments: write local symbol table. */
 5750:                 stcpy (tmp, " $\201");
 5751: 
 5752:                 for (;;) {
 5753:                     ordercnt = 1L;
 5754:                     
 5755:                     symtab (bigquery, &tmp[1], tmp2);
 5756:                     
 5757:                     if (*tmp2 == EOL || merr () == INRPT) break;
 5758:                     w_tmp[0] = '=';
 5759: 
 5760:                     /* subscripts: internal format different from external one */
 5761:                     k = 0;
 5762:                     i = 1;
 5763:                     j = 0;
 5764:                     
 5765:                     while ((ch = tmp2[k++]) != EOL) {
 5766:                         
 5767:                         if (ch == '"') {
 5768:                             
 5769:                             if (j && tmp2[k] == ch) {
 5770:                                 k++;
 5771:                             }
 5772:                             else {
 5773:                                 toggle (j);
 5774:                                 continue;
 5775:                             }
 5776: 
 5777:                         }
 5778:                         
 5779:                         if (j == 0) {
 5780:                     
 5781:                             if (ch == '(' || ch == ',') {
 5782:                                 tmp[i++] = DELIM;
 5783:                                 
 5784:                                 continue;
 5785:                             }
 5786:                     
 5787:                             if (ch == ')') break;
 5788:                         }
 5789:                     
 5790:                         tmp[i++] = ch;
 5791:                     }
 5792:                     
 5793:                     tmp[i] = EOL;
 5794:                     if (kill_ok (tmp3, tmp) == 0) continue;
 5795: 
 5796:                     write_m (tmp2);
 5797:                     symtab (get_sym, &tmp[1], &w_tmp[1]);
 5798:                     write_m (w_tmp);
 5799:                     write_m ("\012\015\201");
 5800:                 }
 5801:                 
 5802:                 break;
 5803: 
 5804: zwritep:
 5805: 
 5806:                 expr (NAME);
 5807: 
 5808:                 //if (varnam[0] == '^') merr_raise (GLOBER);
 5809:                 if (merr () > OK) goto err;
 5810:                 
 5811:                 codptr++;
 5812: 
 5813:                 if (varnam[0] == '$') {
 5814:                 
 5815:                     if ((varnam[1] | 0140) == 'z' && (varnam[2] | 0140) == 'f') {
 5816:                         w_tmp[0] = '$';
 5817:                         w_tmp[1] = 'Z';
 5818:                         w_tmp[2] = 'F';
 5819:                         w_tmp[3] = '(';
 5820:                 
 5821:                         for (i = 0; i < 44; i++) {
 5822: 
 5823:                             if (zfunkey[i][0] != EOL) {
 5824:                                 intstr (&w_tmp[4], i + 1);
 5825:                                 stcat (w_tmp, ")=\201");
 5826:                                 write_m (w_tmp);
 5827:                                 write_m (zfunkey[i]);
 5828:                                 write_m ("\012\015\201");
 5829:                             }
 5830: 
 5831:                         }
 5832: 
 5833:                         break;
 5834:                     }
 5835:                     else {
 5836:                         break;      /* do not zwrite special variables etc. other than $ZF */
 5837:                     }
 5838:                 }
 5839:                 
 5840:                 if (varnam[0] != '^') {
 5841:                     symtab (fra_dat, varnam, tmp2);
 5842:                     zwmode = 'L';
 5843:                 }
 5844:                 else {
 5845:                     if (varnam[1] == '$') {
 5846:                         ssvn (fra_dat, varnam, tmp2);
 5847:                         zwmode = '$';
 5848:                     }
 5849:                     else {
 5850:                         global (fra_dat, varnam, tmp2);
 5851:                         zwmode = '^';
 5852:                     }
 5853:                 }
 5854: 
 5855:                 if (tmp2[0] == '0') break;      /* variable not defined */
 5856:                 
 5857:                 /* if $D(@varnam)=10 get next entry */
 5858:                 if (tmp2[1] == '0') {
 5859:                     ordercnt = 1L;
 5860: 
 5861:                     if (varnam[0] != '^') {
 5862:                         symtab (fra_query, varnam, tmp2);
 5863:                         zwmode = 'L';
 5864:                     }
 5865:                     else {
 5866:                         if (varnam[1] == '$') {
 5867:                             ssvn (fra_query, varnam, tmp2);
 5868:                             zwmode = '$';
 5869:                         }
 5870:                         else {
 5871:                             global (fra_query, varnam, tmp2);
 5872:                             zwmode = '^';
 5873:                         }
 5874:                     }
 5875:                 }
 5876:                 else {
 5877:                     k = 0;
 5878:                     i = 0;
 5879:                     j = 0;
 5880:                 
 5881:                     while ((ch = varnam[k++]) != EOL) {
 5882:                         
 5883:                         if (ch == DELIM) {
 5884:                             
 5885:                             if (j) {
 5886:                                 tmp2[i++] = '"';
 5887:                                 tmp2[i++] = ',';
 5888:                                 tmp2[i++] = '"';
 5889: 
 5890:                                 continue;
 5891:                             }
 5892: 
 5893:                             j++;
 5894:                 
 5895:                             tmp2[i++] = '(';
 5896:                             tmp2[i++] = '"';
 5897:                 
 5898:                             continue;
 5899:                         }
 5900:                 
 5901:                         if ((tmp2[i++] = ch) == '"')
 5902:                         tmp2[i++] = ch;
 5903:                     }
 5904:                 
 5905:                     if (j) {
 5906:                         tmp[i++] = '"';
 5907:                         tmp2[i++] = ')';
 5908:                     }
 5909:                 
 5910:                     tmp2[i] = EOL;
 5911:                 }
 5912:                 
 5913:                 for (;;) {           /* subscripts: internal format different from external one */
 5914:                     k = 0;
 5915:                     i = 0;
 5916:                     j = 0;
 5917: 
 5918:                     while ((ch = tmp2[k++]) != EOL) {
 5919: 
 5920:                         if (ch == '"') {
 5921:                             if (j && tmp2[k] == ch)
 5922:                                 k++;
 5923:                             else {
 5924:                                 toggle (j);
 5925:                                 continue;
 5926:                             }
 5927:                         }
 5928:                         
 5929:                         if (j == 0) {
 5930:                             
 5931:                             if (ch == '(' || ch == ',') {
 5932:                                 tmp[i++] = DELIM;
 5933:                         
 5934:                                 continue;
 5935:                             }
 5936:                         
 5937:                             if (ch == ')') break;
 5938:                         }
 5939: 
 5940:                         tmp[i++] = ch;
 5941:                     }
 5942: 
 5943:                     tmp[i] = EOL;
 5944:                     i = 0;
 5945:                     
 5946:                     while (tmp[i] == varnam[i]) {
 5947: 
 5948:                         if (varnam[i] == EOL) break;
 5949:                     
 5950:                         i++;
 5951:                     }
 5952: 
 5953:                     if (varnam[i] != EOL) break;
 5954:                     if (tmp[i] != EOL && tmp[i] != DELIM) break;
 5955:                     
 5956:                     tmp3[0] = EOL;
 5957: 
 5958:                     switch (zwmode) {
 5959: 
 5960:                         case 'L':
 5961:                             symtab (fra_dat, tmp, tmp3);
 5962:                             symtab (get_sym, tmp, &w_tmp[1]);
 5963: 
 5964:                             break;
 5965: 
 5966: 
 5967:                         case '$':
 5968:                             ssvn (fra_dat, tmp, tmp3);
 5969:                             ssvn (get_sym, tmp, &w_tmp[1]);
 5970: 
 5971:                             break;
 5972: 
 5973: 
 5974:                         case '^':
 5975:                             global (fra_dat, tmp, tmp3);
 5976:                             global (get_sym, tmp, &w_tmp[1]);
 5977: 
 5978:                             break;
 5979:                     }
 5980: 
 5981:                     if (tmp3[0] != '0' && tmp3[1] != '0') {                        
 5982:                         
 5983:                         write_m (tmp2);
 5984:                         
 5985:                         w_tmp[0] = '=';
 5986:                         
 5987:                         write_m (w_tmp);
 5988:                         write_m ("\012\015\201");
 5989: 
 5990:                     }
 5991:                     
 5992:                     ordercnt = 1L;
 5993:                     
 5994:                     switch (zwmode) {
 5995: 
 5996:                         case 'L':
 5997:                             symtab (fra_query, tmp, tmp2);
 5998: 
 5999:                             break;
 6000: 
 6001: 
 6002:                         case '$':
 6003:                             ssvn (fra_query, tmp, tmp2);
 6004: 
 6005:                             break;
 6006: 
 6007: 
 6008:                         case '^':
 6009:                             global (fra_query, tmp, tmp2);
 6010: 
 6011:                             break;
 6012: 
 6013:                     }
 6014:                     
 6015:                     if (merr () == INRPT) break;
 6016:                 }
 6017: 
 6018:                 break;
 6019:             }
 6020: 
 6021: 
 6022:         case ZTRAP:
 6023: 
 6024:             if (*codptr == SP || *codptr == EOL) {
 6025:                 merr_raise (ZTERR);
 6026:                 varnam[0] = EOL;
 6027:                 
 6028:                 break;
 6029:             }
 6030: 
 6031:             expr (NAME);
 6032:             stcpy (varerr, varnam);
 6033: 
 6034:             if (merr ()) break;
 6035: 
 6036:             if (*++codptr == ':') {           /* parse postcond */
 6037:                 codptr++;
 6038: 
 6039:                 expr (STRING);
 6040: 
 6041:                 if (merr () > OK) goto err;
 6042: 
 6043:                 if (tvexpr (argptr) == FALSE) break;
 6044:             }
 6045: 
 6046:             merr_raise (ZTERR);
 6047:             break;
 6048: 
 6049: 
 6050:         /* user defined Z-COMMAND */
 6051:         case PRIVATE:
 6052: 
 6053: private:            /* for in-MUMPS defined commands */
 6054:             i = 0;
 6055:             j = 0;
 6056:             ch = 0;
 6057: 
 6058:             while ((tmp2[i] = *codptr) != EOL) {
 6059:                 
 6060:                 if (tmp2[i] == SP && !j) {
 6061:                     tmp2[i] = EOL;
 6062:                     break;
 6063:                 }
 6064: 
 6065:                 if (tmp2[i] == '"') j = (!j);
 6066:                 
 6067:                 if (!j) {
 6068:                     
 6069:                     if (tmp2[i] == '(') ch++;
 6070:                     if (tmp2[i] == ')') ch--;
 6071:                 
 6072:                     if (!ch && tmp2[i] == ',') {       /* next argument: */
 6073:                 
 6074:                         tmp2[i] = EOL;  /* call afterwards again */
 6075:                         i = 0;
 6076:                 
 6077:                         while (tmp3[i] != EOL) i++;
 6078: 
 6079:                         j = i;
 6080:                         ch = 1;
 6081:                 
 6082:                         while (ch < i) tmp3[j++] = tmp3[ch++];
 6083:                 
 6084:                         tmp3[j - 1] = SP;
 6085:                         tmp3[j] = EOL;
 6086:                 
 6087:                         codptr++;
 6088:                 
 6089:                         j = 0;
 6090:                         ch = 0;
 6091:                 
 6092:                         break;
 6093:                     }
 6094:                 }
 6095:                 
 6096:                 i++;
 6097:                 codptr++;            
 6098:             }
 6099: 
 6100:             if (j || ch) {
 6101:                 merr_raise (INVREF);
 6102:                 goto err;
 6103:             }
 6104: 
 6105:             stcat (tmp3, codptr);
 6106: 
 6107:             if (destructor_run) {
 6108:                 stcpy (code, "d \201");
 6109:                 destructor_run = FALSE;
 6110:             }
 6111:             else {
 6112:                 if (new_object) {
 6113:                     stcpy (code, "d ^\201");
 6114:                     new_object = FALSE;
 6115:                 }
 6116:                 else {
 6117:                     stcpy (code, "d ^%\201");
 6118:                 }
 6119:             }
 6120: 
 6121:             stcat (code, &tmp3[1]);
 6122: 
 6123:             codptr = code;
 6124:             privflag = TRUE;
 6125: 
 6126:             goto next_cmnd;
 6127: 
 6128: evthandler:            /* for event handlers */
 6129:             i = 0;
 6130:             j = 0;
 6131:             ch = 0;
 6132: 
 6133:             while ((tmp2[i] = *codptr) != EOL) {
 6134:                 
 6135:                 if (tmp2[i] == SP && !j) {
 6136:                     tmp2[i] = EOL;
 6137:                     break;
 6138:                 }
 6139: 
 6140:                 if (tmp2[i] == '"') j = (!j);
 6141:                 
 6142:                 if (!j) {
 6143:                     
 6144:                     if (tmp2[i] == '(') ch++;
 6145:                     if (tmp2[i] == ')') ch--;
 6146:                 
 6147:                     if (!ch && tmp2[i] == ',') {       /* next argument: */
 6148:                 
 6149:                         tmp2[i] = EOL;  /* call afterwards again */
 6150:                         i = 0;
 6151:                 
 6152:                         while (tmp3[i] != EOL) i++;
 6153: 
 6154:                         j = i;
 6155:                         ch = 1;
 6156:                 
 6157:                         while (ch < i) tmp3[j++] = tmp3[ch++];
 6158:                 
 6159:                         tmp3[j - 1] = SP;
 6160:                         tmp3[j] = EOL;
 6161:                 
 6162:                         codptr++;
 6163:                 
 6164:                         j = 0;
 6165:                         ch = 0;
 6166:                 
 6167:                         break;
 6168:                     }
 6169:                 }
 6170:                 
 6171:                 i++;
 6172:                 codptr++;            
 6173:             }
 6174: 
 6175:             if (j || ch) {
 6176:                 merr_raise (INVREF);
 6177:                 goto err;
 6178:             }
 6179: 
 6180:             stcpy (code, "d \201");
 6181:             stcat (code, tmp3);
 6182: 
 6183:             codptr = code;
 6184:             privflag = TRUE;
 6185: 
 6186:             goto next_cmnd;            
 6187: 
 6188:         case ABLOCK:
 6189:         case AUNBLOCK:
 6190:             {
 6191:                 short evt_mask[EVT_MAX];
 6192:                 
 6193:                 if ((rtn_dialect () != D_MDS) &&
 6194:                     (rtn_dialect () != D_FREEM)) {
 6195:                     merr_raise (NOSTAND);
 6196:                     goto err;
 6197:                 }
 6198: 
 6199:                 /* declare and initialize table of events to be blocked/unblocked with this command */
 6200: 
 6201:                 
 6202:                 for (i = 0; i < EVT_MAX; i++) evt_mask[i] = 0;
 6203: 
 6204: 
 6205:                 /* argumentless ABLOCK/AUNBLOCK: block/unblock everything */
 6206:                 if (((ch = *codptr) == SP) || ch == EOL) {
 6207:                     
 6208:                     for (i = 0; i < EVT_MAX; i++) evt_mask[i] = 1;
 6209: 
 6210:                 }
 6211:                 else if (*codptr == '(') {
 6212:                     /* exclusive ABLOCK/AUNBLOCK */
 6213: 
 6214:                     short evt_exclusions[EVT_MAX];
 6215:                     
 6216:                     codptr++;
 6217: 
 6218: 
 6219:                     for (i = 0; i < EVT_MAX; i++) evt_exclusions[i] = FALSE;
 6220: 
 6221:                     for (;;) {
 6222: 
 6223:                         expr (STRING);
 6224: 
 6225:                         if (merr () == BRAER) merr_clear ();
 6226:                         if (merr () > OK) goto err;
 6227: 
 6228:                         codptr++;
 6229: 
 6230:                         stcpy (vn, argptr);
 6231: 
 6232:                         if (stcmp (vn, "COMM\201") == 0) {
 6233:                             evt_exclusions[EVT_CLS_COMM] = TRUE;
 6234:                         }
 6235:                         else if (stcmp (vn, "HALT\201") == 0) {
 6236:                             evt_exclusions[EVT_CLS_HALT] = TRUE;
 6237:                         }
 6238:                         else if (stcmp (vn, "IPC\201") == 0) {
 6239:                             evt_exclusions[EVT_CLS_IPC] = TRUE;
 6240:                         }
 6241:                         else if (stcmp (vn, "INTERRUPT\201") == 0) {
 6242:                             evt_exclusions[EVT_CLS_INTERRUPT] = TRUE;
 6243:                         }
 6244:                         else if (stcmp (vn, "POWER\201") == 0) {
 6245:                             evt_exclusions[EVT_CLS_POWER] = TRUE;
 6246:                         }
 6247:                         else if (stcmp (vn, "TIMER\201") == 0) {
 6248:                             evt_exclusions[EVT_CLS_TIMER] = TRUE;
 6249:                         }
 6250:                         else if (stcmp (vn, "USER\201") == 0) {
 6251:                             evt_exclusions[EVT_CLS_USER] = TRUE;
 6252:                         }
 6253:                         else if (stcmp (vn, "WAPI\201") == 0) {
 6254:                             evt_exclusions[EVT_CLS_WAPI] = TRUE;
 6255:                         }
 6256:                         else {
 6257:                             merr_raise (CMMND);
 6258:                             goto err;
 6259:                         }
 6260: 
 6261:                         if ((ch = *(codptr + 1)) == EOL || ch == SP) {
 6262:                             codptr++;
 6263:                             break;
 6264:                         }                       
 6265:                         if ((ch = *(codptr + 1)) == ')') {
 6266:                             codptr++;
 6267:                             break;
 6268:                         }
 6269: 
 6270:                     }
 6271:                 
 6272:                     for (i = 0; i < EVT_MAX; i++) {
 6273: 
 6274:                         if (evt_exclusions[i] == FALSE) evt_mask[i] = 1;
 6275: 
 6276:                     }
 6277: 
 6278:                 }
 6279:                 else {
 6280:                     /* inclusive ABLOCK/AUNBLOCK */
 6281: 
 6282:                     for (;;) {
 6283: 
 6284:                         expr (STRING);                            /* try to interpret a string */                        
 6285:                         if (merr () > OK) goto err;
 6286: 
 6287:                         codptr++;
 6288: 
 6289:                         stcpy (vn, argptr);
 6290: 
 6291:                         if (stcmp (vn, "COMM\201") == 0) {
 6292:                             evt_mask[EVT_CLS_COMM] = 1;
 6293:                         }
 6294:                         else if (stcmp (vn, "HALT\201") == 0) {
 6295:                             evt_mask[EVT_CLS_HALT] = 1;
 6296:                         }
 6297:                         else if (stcmp (vn, "IPC\201") == 0) {
 6298:                             evt_mask[EVT_CLS_IPC] = 1;
 6299:                         }
 6300:                         else if (stcmp (vn, "INTERRUPT\201") == 0) {
 6301:                             evt_mask[EVT_CLS_INTERRUPT] = 1;
 6302:                         }
 6303:                         else if (stcmp (vn, "POWER\201") == 0) {
 6304:                             evt_mask[EVT_CLS_POWER] = 1;
 6305:                         }
 6306:                         else if (stcmp (vn, "TIMER\201") == 0) {
 6307:                             evt_mask[EVT_CLS_TIMER] = 1;
 6308:                         }
 6309:                         else if (stcmp (vn, "TRIGGER\201") == 0) {
 6310:                             evt_mask[EVT_CLS_TRIGGER] = 1;
 6311:                         }
 6312:                         else if (stcmp (vn, "USER\201") == 0) {
 6313:                             evt_mask[EVT_CLS_USER] = 1;
 6314:                         }
 6315:                         else if (stcmp (vn, "WAPI\201") == 0) {
 6316:                             evt_mask[EVT_CLS_WAPI] = 1;
 6317:                         }
 6318:                         else {
 6319:                             merr_raise (CMMND);
 6320:                             goto err;
 6321:                         }
 6322:                     
 6323:                         if (merr () > OK) goto err;
 6324: 
 6325: 
 6326:                         if ((ch = *(codptr)) == EOL || ch == SP) {                            
 6327:                             break;
 6328:                         }
 6329: 
 6330:                     } 
 6331: 
 6332:                 }
 6333: 
 6334:                 for (i = 0; i < EVT_MAX; i++) {                    
 6335: 
 6336:                     if (evt_mask[i] > 0) {
 6337: 
 6338:                         if (mcmnd == ABLOCK) {
 6339:                             evt_ablock (i);
 6340:                         }
 6341:                         else {
 6342:                             evt_aunblock (i);
 6343:                         }
 6344:                     }
 6345: 
 6346:                 }
 6347:             
 6348:                 
 6349:                 break;
 6350:             }
 6351: 
 6352: 
 6353:         case ASSIGN:
 6354:             merr_raise (CMMND);
 6355:             break;
 6356: 
 6357: 
 6358:         case ASTOP:
 6359:         case ASTART:
 6360:             {
 6361:                 short evt_mask[EVT_MAX];
 6362:                 short new_status;
 6363:                 
 6364:                 if ((rtn_dialect () != D_MDS) &&
 6365:                     (rtn_dialect () != D_FREEM)) {
 6366:                     merr_raise (NOSTAND);
 6367:                     goto err;
 6368:                 }
 6369:                 
 6370:                 /* declare and initialize table of events to be enabled with this command */
 6371: 
 6372:                 if (mcmnd == ASTART) {
 6373:                     new_status = EVT_S_ASYNC;
 6374:                 }
 6375:                 else {
 6376:                     new_status = EVT_S_DISABLED;
 6377:                 }
 6378: 
 6379: 
 6380:                 for (i = 0; i < EVT_MAX; i++) evt_mask[i] = EVT_S_NOMODIFY;
 6381: 
 6382: 
 6383:                 /* argumentless ASTART/ASTOP: enable/disable everything */
 6384:                 if (((ch = *codptr) == SP) || ch == EOL) {
 6385:                     
 6386:                     for (i = 0; i < EVT_MAX; i++) evt_mask[i] = new_status;
 6387: 
 6388:                 }
 6389:                 else if (*codptr == '(') {
 6390:                     /* exclusive ASTART */
 6391:                     
 6392:                     short evt_exclusions[EVT_MAX];
 6393: 
 6394:                     codptr++;
 6395: 
 6396:                     for (i = 0; i < EVT_MAX; i++) evt_exclusions[i] = FALSE;
 6397: 
 6398:                     for (;;) {
 6399: 
 6400:                         expr (STRING);
 6401: 
 6402:                         if (merr () == BRAER) merr_clear ();
 6403:                         if (merr () > OK) goto err;
 6404: 
 6405:                         codptr++;
 6406: 
 6407:                         stcpy (vn, argptr);
 6408: 
 6409:                         if (stcmp (vn, "COMM\201") == 0) {
 6410:                             evt_exclusions[EVT_CLS_COMM] = TRUE;
 6411:                         }
 6412:                         else if (stcmp (vn, "HALT\201") == 0) {
 6413:                             evt_exclusions[EVT_CLS_HALT] = TRUE;
 6414:                         }
 6415:                         else if (stcmp (vn, "IPC\201") == 0) {
 6416:                             evt_exclusions[EVT_CLS_IPC] = TRUE;
 6417:                         }
 6418:                         else if (stcmp (vn, "INTERRUPT\201") == 0) {
 6419:                             evt_exclusions[EVT_CLS_INTERRUPT] = TRUE;
 6420:                         }
 6421:                         else if (stcmp (vn, "POWER\201") == 0) {
 6422:                             evt_exclusions[EVT_CLS_POWER] = TRUE;
 6423:                         }
 6424:                         else if (stcmp (vn, "TIMER\201") == 0) {
 6425:                             evt_exclusions[EVT_CLS_TIMER] = TRUE;
 6426:                         }
 6427:                         else if (stcmp (vn, "USER\201") == 0) {
 6428:                             evt_exclusions[EVT_CLS_USER] = TRUE;
 6429:                         }
 6430:                         else if (stcmp (vn, "WAPI\201") == 0) {
 6431:                             evt_exclusions[EVT_CLS_WAPI] = TRUE;
 6432:                         }
 6433:                         else if (stcmp (vn, "TRIGGER\201") == 0) {
 6434:                             evt_exclusions[EVT_CLS_TRIGGER] = TRUE;
 6435:                         }
 6436:                         else {
 6437:                             merr_raise (CMMND);
 6438:                             goto err;
 6439:                         }
 6440: 
 6441:                         if ((ch = *(codptr + 1)) == EOL || ch == SP) {
 6442:                             codptr++;
 6443:                             break;
 6444:                         }                       
 6445:                         if ((ch = *(codptr + 1)) == ')') {
 6446:                             codptr++;
 6447:                             break;
 6448:                         }
 6449: 
 6450:                     }
 6451:                 
 6452:                     for (i = 0; i < EVT_MAX; i++) {
 6453: 
 6454:                         if (evt_exclusions[i] == FALSE) evt_mask[i] = new_status;
 6455: 
 6456:                     }
 6457: 
 6458:                 }
 6459:                 else {
 6460:                     /* inclusive ASTART */
 6461: 
 6462:                     for (;;) {
 6463: 
 6464:                         expr (STRING);                            /* try to interpret a string */                        
 6465:                         if (merr () > OK) goto err;
 6466: 
 6467:                         codptr++;
 6468: 
 6469:                         stcpy (vn, argptr);
 6470: 
 6471:                         if (stcmp (vn, "COMM\201") == 0) {
 6472:                             evt_mask[EVT_CLS_COMM] = new_status;
 6473:                         }
 6474:                         else if (stcmp (vn, "HALT\201") == 0) {
 6475:                             evt_mask[EVT_CLS_HALT] = new_status;
 6476:                         }
 6477:                         else if (stcmp (vn, "IPC\201") == 0) {
 6478:                             evt_mask[EVT_CLS_IPC] = new_status;
 6479:                         }
 6480:                         else if (stcmp (vn, "INTERRUPT\201") == 0) {
 6481:                             evt_mask[EVT_CLS_INTERRUPT] = new_status;
 6482:                         }
 6483:                         else if (stcmp (vn, "POWER\201") == 0) {
 6484:                             evt_mask[EVT_CLS_POWER] = new_status;
 6485:                         }
 6486:                         else if (stcmp (vn, "TIMER\201") == 0) {
 6487:                             evt_mask[EVT_CLS_TIMER] = new_status;
 6488:                         }
 6489:                         else if (stcmp (vn, "USER\201") == 0) {
 6490:                             evt_mask[EVT_CLS_USER] = new_status;
 6491:                         }
 6492:                         else if (stcmp (vn, "WAPI\201") == 0) {
 6493:                             evt_mask[EVT_CLS_WAPI] = new_status;
 6494:                         }
 6495:                         else if (stcmp (vn, "TRIGGER\201") == 0) {
 6496:                             evt_mask[EVT_CLS_TRIGGER] = new_status;
 6497:                         }
 6498:                         else {
 6499:                             merr_raise (CMMND);
 6500:                             goto err;
 6501:                         }
 6502:                     
 6503:                         if (merr () > OK) goto err;
 6504: 
 6505: 
 6506:                         if ((ch = *(codptr)) == EOL || ch == SP) {                            
 6507:                             break;
 6508:                         }
 6509: 
 6510:                     } 
 6511: 
 6512:                 }
 6513: 
 6514:                 for (i = 0; i < EVT_MAX; i++) {                    
 6515: 
 6516:                     if (evt_status[i] == EVT_S_SYNC && evt_mask[i] == EVT_S_ASYNC) {
 6517:                         
 6518:                         /* cannot enable both synchronous and asynchronous 
 6519:                            event processing on the same event class at the
 6520:                            same time */
 6521: 
 6522:                         merr_raise (M102);
 6523:                         goto err;
 6524: 
 6525:                     }
 6526:                     else {
 6527: 
 6528:                         if (evt_mask[i] > EVT_S_NOMODIFY) {
 6529:                             evt_status[i] = evt_mask[i];
 6530:                         }
 6531:                         
 6532:                     }
 6533: 
 6534:                 }
 6535:             
 6536:                 if (mcmnd == ASTART)  {
 6537:                     evt_async_enabled = TRUE;
 6538:                 }
 6539:                 else {                    
 6540:                     short disabled_evt_count = 0;
 6541: 
 6542:                     for (i = 0; i < EVT_MAX; i++) {
 6543:                         if (evt_status[i] == EVT_S_DISABLED) {
 6544:                             disabled_evt_count++;
 6545:                         }
 6546:                     }
 6547: 
 6548:                     if (disabled_evt_count == (EVT_MAX - 1)) evt_async_enabled = FALSE;
 6549: 
 6550:                 }
 6551: 
 6552:                 break;
 6553:             }
 6554: 
 6555: 
 6556: 
 6557: 
 6558:         case ETRIGGER:
 6559: 
 6560:             merr_raise (CMMND);
 6561:             break;
 6562:         
 6563: 
 6564: #if defined(HAVE_MWAPI_MOTIF)            
 6565:         case ESTART:
 6566:             if ((rtn_dialect () != D_MDS) &&
 6567:                 (rtn_dialect () != D_FREEM)) {
 6568:                 merr_raise (NOSTAND);
 6569:                 goto err;
 6570:             }
 6571: 
 6572:             {
 6573:                 if (in_syn_event_loop == TRUE) break;
 6574: 
 6575:                 int evt_count;
 6576:                 char *syn_handlers = (char *) malloc (STRLEN * sizeof (char));
 6577:                 
 6578:                 /* stack ^$EVENT */
 6579:                 char key[100] = "^$EVENT\202\201";
 6580:                 symtab (new_sym, key, " \201");
 6581: 
 6582:                 evt_sync_enabled = TRUE;
 6583:                 in_syn_event_loop = TRUE;
 6584:                 
 6585:                 while (evt_sync_enabled) {
 6586: 
 6587:                     
 6588:                     /* run the next iteration of GTK's event loop */
 6589:                     //TODO: replace with libXt event loop
 6590:                     //gtk_main_iteration_do (TRUE);
 6591: 
 6592:                     /* dequeue any events */
 6593:                     evt_count = mwapi_dequeue_events (syn_handlers);
 6594: 
 6595:                     if (evt_count) {
 6596:                         /* write them out */
 6597:                         //printf ("event handlers = '%s'\r\n", syn_handlers);
 6598: 
 6599:                         syn_event_entry_nstx = nstx;
 6600:                         
 6601:                         stcnv_c2m (syn_handlers);
 6602:                         stcpy (tmp3, syn_handlers);
 6603:                         
 6604:                         syn_handlers[0] = '\0';
 6605:                         
 6606:                         goto evthandler;
 6607:                     }
 6608: 
 6609: syn_evt_loop_bottom:
 6610:                     continue;
 6611:                 }
 6612: 
 6613:                 in_syn_event_loop = FALSE;
 6614:                 evt_sync_enabled = FALSE;
 6615: 
 6616:                 break;
 6617:             }
 6618:         
 6619:         
 6620:         case ESTOP:
 6621:             if ((rtn_dialect () != D_MDS) &&
 6622:                 (rtn_dialect () != D_FREEM)) {
 6623:                 merr_raise (NOSTAND);
 6624:                 goto err;
 6625:             }
 6626: 
 6627:             evt_sync_enabled = FALSE;
 6628:             break;
 6629: #endif            
 6630: 
 6631:             
 6632:         default:
 6633:             merr_raise (CMMND);
 6634:     
 6635:     }               /* command switch */
 6636: 
 6637:     if ((ch = *codptr) == EOL) {
 6638:         if (merr () != OK) goto err;
 6639:         if (forsw) goto for_end;        
 6640:         
 6641:         mcmnd = 0;
 6642:         
 6643:         goto next_line;
 6644:     }
 6645: 
 6646:     if (ch == SP) {
 6647:         if (merr () == OK) goto next0;
 6648: 
 6649:         goto err;
 6650:     }
 6651: 
 6652:     if (ch != ',' && merr () == OK) { 
 6653:         merr_raise (SPACER);
 6654:     }
 6655:     else if ((ierr <= OK) || (debug_mode == TRUE)) {
 6656:         if (debug_mode) goto direct_mode;
 6657:         if (*++codptr != SP && *codptr != EOL) goto again;
 6658: 
 6659:         merr_raise (ARGLIST);
 6660:     }
 6661:     
 6662:     /* else goto err; */
 6663: 
 6664: /* error */
 6665: err:
 6666: 
 6667:     /* avoid infinite loops resulting from errors in argumentless FOR loops */
 6668:     if (merr () != OK && merr () != ASYNC && forsw && ftyp == 0) {
 6669:         argless_forsw_quit = TRUE;
 6670:         goto for_end;
 6671:     }    
 6672:     
 6673:     /*
 6674:      * ierr == ASYNC means that the previous command was interrupted by
 6675:      * an async event. It is not a real error, so just go on to the next
 6676:      * command after resetting ierr = OK. 
 6677:      */
 6678:     if (merr () == ASYNC) {
 6679:             merr_clear ();
 6680:             goto next_cmnd;
 6681:     }
 6682: 
 6683:     if (merr () > OK) {
 6684:         job_set_status (pid, JSTAT_ERROR);
 6685:     }
 6686:     
 6687:     if (ierr < 0) {
 6688:         
 6689:         ierr += CTRLB;
 6690: 
 6691:         if (merr () == OK) {
 6692:             zbflag = TRUE;
 6693:             
 6694:             goto zb_entry;
 6695:         }
 6696:     }
 6697: 
 6698:     if (merr () > OK ) {
 6699: 
 6700:         char er_buf[ERRLEN];
 6701:         
 6702:         merr_set_ecode_ierr ();
 6703: 
 6704:         stcpy (er_buf, errmes[merr ()]);
 6705:         stcnv_m2c (er_buf);
 6706: 
 6707: #if !defined(MSDOS)
 6708:         m_log (LOG_ERR, er_buf);
 6709: #endif
 6710: 	
 6711:     }
 6712: 
 6713:     zerr = ierr;    
 6714:     merr_clear ();
 6715:     
 6716:     /*     goto restart;    */
 6717: 
 6718: 
 6719: restart:
 6720:     
 6721:     if (param) goto restore;
 6722: 
 6723:     dosave[0] = EOL;
 6724:     setpiece = FALSE;
 6725:     setop = 0;
 6726:     privflag = FALSE;
 6727: 
 6728:     if (merr () == INRPT) goto err;
 6729:     if (zerr == STORE) symtab (kill_all, "", "");
 6730: 
 6731:     if (errfunlvl > 0) {
 6732:         errfunlvl--;
 6733:     }
 6734:     else {
 6735: 
 6736:         if (zerr == OK) {
 6737:             zerror[0] = EOL;    /* reset error */
 6738:         }
 6739:         else {
 6740: 
 6741: #ifdef DEBUG_STACK
 6742:             printf ("Storing NESTERR\r\n");
 6743: #endif
 6744: 
 6745:             nesterr = nstx; /* save stack information at error */
 6746: 
 6747:             for (i = 1; i <= nstx; i++) getraddress (callerr[i], i);
 6748:             
 6749:             zerror[0] = '<';
 6750: 
 6751:             if (etxtflag) {
 6752:                 stcpy (&zerror[1], errmes[zerr]);
 6753:             }
 6754:             else {
 6755:                 intstr (&zerror[1], zerr);
 6756:             }
 6757: 
 6758:             stcat (zerror, ">\201");
 6759: 
 6760:             if (rou_name[0] != EOL) {
 6761:                 char *j0;
 6762:                 char *j1;
 6763:                 char tmp1[256];
 6764: 
 6765: 
 6766:             
 6767:                 if (nestc[nstx] == XECUTE) {
 6768:                     
 6769:                     if (nestn[nstx]) {       /* reload routine */
 6770:                         zload (nestn[nstx]);
 6771:                         merr_clear ();
 6772:                     }
 6773:                 
 6774:                     roucur = nestr[nstx] + rouptr;  /* restore roucur */
 6775:                 }
 6776: 
 6777: 
 6778:             
 6779:                 j0 = (rouptr - 1);
 6780:                 j = 0;
 6781:                 tmp1[0] = EOL;
 6782:                 j0++;
 6783:                 
 6784:                 if (roucur < rouend) {
 6785:                     
 6786:                     while (j0 < (roucur - 1)) {
 6787: 
 6788:                         j1 = j0++;
 6789:                         j++;
 6790: 
 6791:                         if ((*j0 != TAB) && (*j0 != SP)) {
 6792:                         
 6793:                             j = 0;
 6794:                         
 6795:                             while ((tmp1[j] = (*(j0++))) > SP) {
 6796:                         
 6797:                                 if (tmp1[j] == '(') tmp1[j] = EOL;
 6798:                         
 6799:                                 j++;
 6800:                             }
 6801:                         
 6802:                             tmp1[j] = EOL;
 6803:                             j = 0;
 6804:                         }
 6805:                         
 6806:                         j0 = j1;
 6807:                         j0 += (UNSIGN (*j1)) + 2;
 6808:                     }
 6809:                 }
 6810: 
 6811:                 stcat (zerror, tmp1);
 6812: 
 6813:                 if (j > 0) {
 6814:                     i = stlen (zerror);
 6815:                     zerror[i++] = '+';
 6816:                     
 6817:                     intstr (&zerror[i], j);
 6818:                 }
 6819: 
 6820:                 stcat (zerror, "^\201");
 6821:             
 6822: 
 6823:             
 6824:                 if (nestc[nstx] == XECUTE) {
 6825:                     
 6826:                     if (nestn[nstx]) {       /* reload routine */
 6827:                         zload (rou_name);
 6828: 
 6829:                         ssvn_job_update ();
 6830: 
 6831:                         merr_clear ();
 6832:                     }
 6833:                 
 6834:                     stcat (zerror, nestn[nstx]);
 6835:                 }
 6836:                 else
 6837:                     stcat (zerror, rou_name);
 6838:             }
 6839: 
 6840:             if (zerr == UNDEF) zerr = M6;
 6841: 
 6842:             /* undefined: report variable name */
 6843:             if (zerr == UNDEF || zerr == SBSCR || zerr == NAKED || zerr == ZTERR || zerr == DBDGD || zerr == LBLUNDEF || zerr == NOPGM || zerr == M6 || zerr == M7 || zerr == M13) { 
 6844: 
 6845:                 int f;      /* include erroneous reference */
 6846: 
 6847:                 f = stlen (zerror);
 6848:                 zerror[f++] = SP;
 6849:                 zname (&zerror[f], varerr);
 6850:             }           /* end varnam section */
 6851:         }
 6852:     }
 6853: 
 6854:     roucur = buff + (NO_OF_RBUF * PSIZE0 + 1);
 6855:     tmp4[0] = EOL;
 6856: 
 6857:     while (ierr != (OK - CTRLB)) {
 6858: 
 6859: 
 6860:         /* standard error handling */
 6861:         if (etrap[0] != EOL && stcmp (ecode, "") != 0)  {
 6862: 
 6863:             on_frame_entry ();
 6864:             
 6865:             /* disable $ZTRAP error handling */
 6866:             ztrap[nstx][0] = EOL;
 6867: 
 6868:             stcpy (tmp4, etrap);
 6869:             stcat (tmp4, " quit:$quit \"\" quit\201");
 6870: 
 6871:             if (etrap_lvl > 1) {
 6872:                 /* we've encountered an error within an error handler. 
 6873:                    save off the error code at merr_stack[nstx + 1].ECODE */
 6874: 
 6875:                 stcpy (merr_stack[nstx + 1].ECODE, ecode);
 6876:                 merr_topstk = nstx + 1;
 6877:                 etrap_lvl++;
 6878: 
 6879:             }
 6880:             else {
 6881:                 merr_topstk = nstx;
 6882:                 etrap_lvl++;
 6883:             }
 6884: 
 6885:             break;
 6886: 
 6887:         }
 6888: 
 6889: 
 6890: 
 6891:         if (ztrap[nstx][0] != EOL && !DSM2err) {           
 6892: 
 6893: #ifdef DEBUG_NEWSTACK
 6894: 
 6895:             printf ("Dropped into Ztrap [");
 6896:             
 6897:             for (loop = 0; loop < 20 && ztrap[nstx][loop] != EOL; loop++) {
 6898:                 printf ("%c", ztrap[nstx][loop]);
 6899:             }
 6900: 
 6901:             printf ("]\r\n");
 6902: 
 6903: #endif
 6904: 
 6905:             tmp4[0] = GOTO;
 6906:             tmp4[1] = SP;
 6907:             stcpy (&tmp4[2], ztrap[nstx]);
 6908:             ztrap[nstx][0] = EOL;
 6909: 
 6910: #ifdef DEBUG_NEWSTACK
 6911: 
 6912:             printf ("Set tmp4 to [");
 6913:             for (loop = 0; tmp4[loop] != EOL; loop++) printf ("%c", tmp4[loop]);            
 6914:             printf ("]\r\n");
 6915: 
 6916: #endif
 6917: 
 6918:             break;
 6919:         }
 6920: 
 6921: 
 6922: 
 6923:         if (nstx == 0) {
 6924: 
 6925: #ifdef DEBUG_NEWSTACK
 6926:             printf ("Nestx was Zero\r\n");
 6927: #endif
 6928:         
 6929:             forx = 0;
 6930:             cmdptr = cmdstack;
 6931:             namptr = namstck;
 6932:             level = 0;
 6933:             errfunlvl = 0;
 6934:             io = HOME;      /* trap to direct mode: USE 0 */
 6935:             
 6936:             if (zerr == INRPT && frm_filter) {
 6937:                 tmp4[0] = 'h';
 6938:                 tmp4[1] = EOL;
 6939:             }
 6940: 
 6941:             if (DSM2err && (ztrap[NESTLEVLS + 1][0] != EOL)) {           /* DSM V.2 error trapping */
 6942: 
 6943: #ifdef DEBUG_NEWSTACK
 6944:                 printf ("Ztrap 2\r\n");
 6945: #endif
 6946: 
 6947:                 tmp4[0] = GOTO;
 6948:                 tmp4[1] = SP;   /* GOTO errorhandling */
 6949:                 
 6950:                 stcpy (&tmp4[2], ztrap[NESTLEVLS + 1]);
 6951:                 ztrap[NESTLEVLS + 1][0] = EOL;
 6952:                 
 6953:             }
 6954: 
 6955:             break;
 6956:         }
 6957: 
 6958: #ifdef DEBUG_NEWSTACK
 6959:         printf ("Nestc[nstx] is [%d]\r\n", nestc[nstx]);
 6960: #endif
 6961: 
 6962:         if (nestc[nstx] == BREAK) break;
 6963: 
 6964:         if (merr () > OK) goto err;
 6965:         
 6966:         if (nestc[nstx] == FOR) {
 6967:             if (forx == 0) goto for_quit;
 6968:             ftyp = fortyp[--forx];
 6969:             fvar = forvar[forx];
 6970:             finc = forinc[forx];
 6971:             flim = forlim[forx];
 6972:             fi = fori[forx];
 6973:         }
 6974:         else {
 6975: 
 6976:             if (nestc[nstx] == DO_BLOCK) {
 6977:                 test = nestlt[nstx];
 6978:                 level--;
 6979:             }
 6980:             else { /* pop $TEST */
 6981:                 level = nestlt[nstx];   /* pop level */
 6982:             }
 6983: 
 6984: #ifdef DEBUG_NEWSTACK
 6985:             printf ("Nestn[nstx] is [%d]\r\n", nestn[nstx]);
 6986: #endif
 6987: 
 6988:             if (nestn[nstx]) {           /* 'reload' routine */
 6989:                 namptr = nestn[nstx];
 6990:                 stcpy (rou_name, namptr);
 6991:                 zload (rou_name);
 6992: 
 6993:                 ssvn_job_update ();
 6994:                 
 6995:                 dosave[0] = 0;
 6996:                 
 6997:                 namptr--;
 6998:             }
 6999: 
 7000: #ifdef DEBUG_NEWSTACK
 7001:             printf ("Execcing the rest...\r\n");
 7002: #endif
 7003: 
 7004:             roucur = nestr[nstx] + rouptr;
 7005: 
 7006:             if (nestnew[nstx]) unnew ();       /* un-NEW variables */
 7007:             
 7008:             cmdptr = nestp[nstx];
 7009: 
 7010:             if (nestc[nstx--] == '$') {           /* extrinsic function/variable */
 7011:                 *argptr = EOL;
 7012:                 merr_raise (zerr);
 7013:                 errfunlvl++;
 7014:                 
 7015:                 return 0;
 7016:             }
 7017:             estack--;
 7018:         }
 7019:     }
 7020: 
 7021:     forsw = FALSE;
 7022: 
 7023:     /* PRINTING ERROR MESSAGES */
 7024:     if (tmp4[0] == EOL) {
 7025:         
 7026:         if (zerr == BKERR && brkaction[0] != EOL) {
 7027:             stcpy (code, brkaction);
 7028:             codptr = code;
 7029: 
 7030:             if (libcall == TRUE) {
 7031:                 return zerr;
 7032:             } 
 7033:             else {
 7034:                 goto next_cmnd;
 7035:             }
 7036:         }
 7037: 
 7038:         if (libcall == TRUE) return zerr;
 7039: 
 7040:         DSW &= ~BIT0;       /* enable ECHO */
 7041: 
 7042:         // print here
 7043:         {
 7044:             char *t_rtn;
 7045:             char *t_nsn = (char *) malloc (STRLEN * sizeof (char));
 7046:             char *t_cod;
 7047:             int t_pos;
 7048: 
 7049: 	    NULLPTRCHK(t_nsn,"xecline");
 7050: 	    
 7051:             t_rtn = strtok (zerror, ">");
 7052:             t_rtn = strtok (NULL, ">");
 7053: 
 7054:             if (t_rtn != NULL && t_rtn[1] == '%') {
 7055:                 strcpy (t_nsn, "SYSTEM");
 7056:             }
 7057:             else {
 7058:                 strcpy (t_nsn, nsname);
 7059:             }
 7060: 
 7061:             if (deferred_ierr > OK) {
 7062:                 t_cod = deferrable_code;
 7063:                 t_pos = deferrable_codptr - code + 3;
 7064:             }
 7065:             else {
 7066:                 t_cod = code;
 7067:                 t_pos = codptr - code + 3;
 7068:             }
 7069: 
 7070:             if (t_rtn != NULL) {
 7071:                 merr_dump (zerr, t_rtn, t_nsn, t_cod, t_pos);
 7072:             }
 7073:             else {
 7074:                 merr_dump (zerr, "<UNKNOWN>", t_nsn, t_cod, t_pos);
 7075:             }
 7076:             
 7077:             
 7078:             free (t_nsn);
 7079:         }
 7080: 
 7081: 
 7082:     }
 7083:     else {            
 7084:         stcpy (code, tmp4);
 7085:         
 7086:         codptr = code;
 7087:         tmp4[0] = EOL;
 7088: 
 7089:         goto next_cmnd;
 7090:     }
 7091: 
 7092: restore:
 7093: 
 7094:     io = HOME;
 7095:     codptr = code;
 7096: 
 7097:     if (param > 0) {
 7098: 
 7099:         j = 0;
 7100:         ch = 0;
 7101:         paramx++;
 7102:         param--;
 7103:         
 7104:         for (;;) {
 7105:             if (m_argv[++j][0] == '-') {
 7106:                 i = 0;
 7107:             
 7108:                 while ((m_argv[j][++i] != 0) && (m_argv[j][i] != 'x'));
 7109:                 
 7110:                 if (m_argv[j][i] != 'x') continue;
 7111:             
 7112:                 j++;
 7113:             
 7114:                 if (++ch < paramx) continue;
 7115:             
 7116:                 strcpy (code, m_argv[j]);
 7117:                 break;
 7118:             }
 7119:             else {
 7120:                 if (++ch < paramx) continue;
 7121:             
 7122:                 strcpy (code, "d ");
 7123:                 strcpy (&code[2], m_argv[j]);
 7124:                 break;
 7125:             }
 7126:         }
 7127:         code[strlen (code)] = EOL;
 7128:         codptr = code;
 7129:         goto next_cmnd;
 7130: 
 7131:     }
 7132: 
 7133:     if (usermode == 0) {               /* application mode: direct mode implies HALT */
 7134:         code[0] = 'H';
 7135:         code[1] = EOL;
 7136:         codptr = code;
 7137: 
 7138:         goto next_cmnd;
 7139:     }
 7140:     else {
 7141:        if (debug_mode) goto direct_mode;
 7142:     }
 7143: 
 7144:     if (libcall == TRUE) {             /* library mode: don't go to direct mode, just return */
 7145:         return merr ();
 7146:     }
 7147: 
 7148: 
 7149:     do {
 7150: 
 7151:         if (frm_filter == FALSE && promflag) {
 7152:             stcpy (code, " \201");
 7153:             stcpy (&code[2], " \201");                
 7154:             promflag = FALSE;
 7155:         }
 7156:         else {
 7157: 
 7158: direct_mode:
 7159: 
 7160:             if (dbg_enable_watch && dbg_pending_watches) dbg_dump_watchlist ();
 7161: 
 7162:             /* DIRECT-MODE PROMPT HERE */
 7163: #if defined(HAVE_LIBREADLINE) && !defined(_AIX)
 7164:             {
 7165:                 char *fmrl_buf;
 7166:                 char fmrl_prompt[256];
 7167:                 HIST_ENTRY **hist_list;                
 7168:                 int hist_idx;
 7169:                 HIST_ENTRY *hist_ent;
 7170: 
 7171:                 if (quiet_mode == FALSE) {
 7172:                     if (tp_level == 0) {
 7173:                         snprintf (fmrl_prompt, 255, "\r\n%s.%s> ", shm_env, nsname);
 7174:                     }
 7175:                     else {
 7176:                         snprintf (fmrl_prompt, 255, "\r\nTL%d:%s.%s> ", tp_level, shm_env, nsname);
 7177:                     }
 7178:                 }
 7179:                 set_io (UNIX);
 7180: 
 7181:                 job_set_status (pid, JSTAT_DIRECTMODE);
 7182:                 
 7183:                 /* readline() does its own malloc() */
 7184:                 fmrl_buf = readline (fmrl_prompt);
 7185:                 
 7186:                 if (!fmrl_buf) {
 7187:                     set_io (UNIX);
 7188:                     printf ("\n");
 7189:                     set_io (MUMPS);
 7190:                     
 7191:                     goto halt;
 7192:                 }
 7193:                 
 7194:                 if (strlen (fmrl_buf) > 0) {
 7195:                     add_history (fmrl_buf);
 7196:                 }                    
 7197: 
 7198:                 if (fmrl_buf[0] == '?') {
 7199: 
 7200:                     char kb[20];
 7201:                     char db[255];
 7202:                     
 7203:                     snprintf (kb, 19, "%%SYS.HLP\201");
 7204:                     snprintf (db, 19, "\201");
 7205: 
 7206:                     symtab (kill_sym, kb, db);
 7207:                     
 7208:                     /* Invoke Online Help */
 7209: 
 7210:                     set_io (MUMPS);
 7211:                     stcpy (code, "DO ^%ZHELP\201");
 7212:                     
 7213:                     if (strlen (fmrl_buf) > 1) {
 7214:                         snprintf (db, 254, "%s\201", &fmrl_buf[1]);
 7215:                         symtab (set_sym, kb, db);
 7216:                     }
 7217:                     
 7218:                 }
 7219:                 else if (strcmp (fmrl_buf, "step") == 0) {
 7220:                     debug_mode = TRUE;
 7221:                     goto zgo;
 7222:                 }
 7223:                 else if ((strcmp (fmrl_buf, "cont") == 0) || (strcmp (fmrl_buf, "continue") == 0)) {
 7224:                     debug_mode = FALSE;
 7225:                 }
 7226:                 else if (strcmp (fmrl_buf, "rbuf") == 0) {
 7227:                     rbuf_dump ();
 7228:                 }
 7229:                 else if (strcmp (fmrl_buf, "jobtab") == 0) {
 7230:                     job_dump ();
 7231:                 }
 7232:                 else if (strcmp (fmrl_buf, "locktab") == 0) {
 7233:                     locktab_dump ();
 7234:                     code[0] = '\201';
 7235:                     codptr = code;
 7236:                 }
 7237:                 else if (strcmp (fmrl_buf, "shmstat") == 0) {
 7238:                     shm_dump ();
 7239:                 }
 7240:                 else if (strcmp (fmrl_buf, "shmpages") == 0) {
 7241:                     shm_dump_pages ();
 7242:                 }
 7243:                 else if (strcmp (fmrl_buf, "glstat") == 0) {
 7244:                     gbl_dump_stat ();
 7245:                 }
 7246:                 else if (strcmp (fmrl_buf, "events") == 0) {
 7247: 
 7248:                     char stat_desc[30];
 7249:                     char *evclass_name;
 7250: 
 7251:                     printf ("\n%-20s %-15s %s\n", "Event Class", "Processing Mode", "ABLOCK Count");
 7252:                     printf ("%-20s %-15s %s\n", "-----------", "---------------", "------------");
 7253: 
 7254:                     for (i = 0; i < EVT_MAX; i++) {
 7255: 
 7256:                         evclass_name = evt_class_name_c (i);
 7257: 
 7258:                         switch (evt_status[i]) {
 7259:                             case EVT_S_DISABLED:
 7260:                                 strcpy (stat_desc, "Disabled");
 7261:                                 break;
 7262:                             case EVT_S_ASYNC:
 7263:                                 strcpy (stat_desc, "Asynchronous");
 7264:                                 break;
 7265:                             case EVT_S_SYNC:
 7266:                                 strcpy (stat_desc, "Synchronous");
 7267:                         }
 7268: 
 7269:                         printf ("%-20s %-15s %d\n", evclass_name, stat_desc, evt_blocks[i]);
 7270: 
 7271:                     }
 7272:                     
 7273:                     
 7274:                 }
 7275:                 else if (strcmp (fmrl_buf, "wh") == 0) {
 7276:                     write_history (history_file);
 7277:                 }
 7278:                 else if (strcmp (fmrl_buf, "trantab") == 0) {
 7279:                     tp_tdump();
 7280:                 }
 7281:                 else if (isdigit(fmrl_buf[0]) || (fmrl_buf[0] == '(') || (fmrl_buf[0] == '-') || (fmrl_buf[0] == '\'') || (fmrl_buf[0] == '+') || (fmrl_buf[0] == '$') || (fmrl_buf[0] == '^')) {
 7282: 
 7283:                     snprintf (code, 255, "W %s", fmrl_buf);
 7284:                     stcnv_c2m (code);
 7285: 
 7286:                     set_io (MUMPS);
 7287: 
 7288:                 }
 7289: #if !defined(__APPLE__)
 7290:                 else if (strcmp (fmrl_buf, "history") == 0) {
 7291: 
 7292:                     /* History List */                                                
 7293: 
 7294:                     hist_list = history_list ();
 7295:                     if (hist_list) {
 7296: 
 7297:                         for (i = 0; hist_list[i]; i++) {
 7298:                             printf("%d: %s\n", i + history_base, hist_list[i]->line);
 7299:                         }
 7300:                         
 7301:                     }
 7302: 
 7303:                     stcpy (code, " \201");
 7304: 
 7305:                     set_io (MUMPS);
 7306: 
 7307:                 }
 7308: #endif                    
 7309:                 else if (strncmp (fmrl_buf, "rcl", 3) == 0) {
 7310: 
 7311:                     /* Recall History Item */
 7312:                     
 7313:                                             
 7314:                     
 7315:                     if (!isdigit (fmrl_buf[4])) {
 7316:                         fprintf (stderr, "invalid history index '%s'\n", &fmrl_buf[4]);
 7317: 
 7318:                         set_io (MUMPS);
 7319:                         stcpy (code, " \201");
 7320: 
 7321:                         break;
 7322:                     }
 7323: 
 7324:                     hist_idx = atoi (&fmrl_buf[4]);
 7325: 
 7326:                     if ((hist_idx > history_length) || (hist_idx < 1)) {
 7327:                         fprintf (stderr, "history entry %d out of range (valid entries are 1-%d)\n", hist_idx, history_length);
 7328: 
 7329:                         set_io (MUMPS);
 7330:                         stcpy (code, " \201");
 7331: 
 7332:                         break;
 7333:                     }                        
 7334: 
 7335:                     hist_ent = history_get (hist_idx);
 7336: 
 7337:                     printf ("%s\n", hist_ent->line);
 7338: 
 7339:                     strncpy (code, hist_ent->line, 255);
 7340:                     stcnv_c2m (code);
 7341: 
 7342:                     set_io (MUMPS);
 7343: 
 7344:                 }
 7345:                 else {
 7346: 
 7347:                     /* Pass to M Interpreter */
 7348: 
 7349:                     set_io (MUMPS);
 7350: 
 7351:                     strncpy (code, fmrl_buf, 255);
 7352:                     stcnv_c2m (code);
 7353: 
 7354:                 }
 7355: 
 7356:                 /* free the buffer malloc()'d by readline() */
 7357:                 if (fmrl_buf) free (fmrl_buf);                    
 7358:             }
 7359: #else
 7360: 
 7361:             {
 7362:                 char fmrl_prompt[256];
 7363: 
 7364:                 if (tp_level == 0) {
 7365:                     snprintf (fmrl_prompt, 256, "\r\n%s> \201", nsname);
 7366:                 }
 7367:                 else {
 7368:                     snprintf (fmrl_prompt, 256, "\r\nTL%d:%s> \201", tp_level, nsname);
 7369:                 }
 7370:                 
 7371:                 write_m (fmrl_prompt);
 7372: 
 7373:                 read_m (code, -1L, 0, 255); /* Not necessarily STRLEN? */
 7374:             }
 7375: 
 7376:             promflag = TRUE;
 7377: #endif
 7378: 
 7379:             if (merr () > OK) goto err;
 7380: 
 7381: 
 7382:             //      printf ("zbflag = %d\r\n", zbflag);
 7383:             
 7384:             if (code[0] == EOL && zbflag && nestc[nstx] == BREAK) {
 7385: 
 7386:                 //printf ("cont single step\r\n");
 7387:                 debug_mode = TRUE;
 7388:                 merr_raise (OK - CTRLB);
 7389: 
 7390:                 //printf ("ierr now '%d'\r\n", ierr);
 7391:                 goto zgo;
 7392:             }           /* single step */
 7393:         }
 7394:     } 
 7395:     while (code[0] == EOL);
 7396: 
 7397:     if (promflag) write_m ("\r\n\201");
 7398: 
 7399:     /* automatic ZI in direct mode: insert an entry with TAB */
 7400:     i = (-1);
 7401:     j = 0;
 7402:     merr_clear ();
 7403: 
 7404:     while (code[++i] != EOL) {
 7405:         if (code[i] == '"') toggle (j);
 7406: 
 7407:         if (code[i] == TAB && j == 0) {
 7408:             dosave[0] = EOL;
 7409: 
 7410:             zi (code, rouins);
 7411:             if (merr ()) goto err;
 7412:             goto restore;
 7413:         }
 7414:     }
 7415: 
 7416:     code[++i] = EOL;
 7417:     code[++i] = EOL;
 7418: 
 7419:     roucur = buff + (NO_OF_RBUF * PSIZE0 + 1);
 7420: 
 7421:     goto next_cmnd;
 7422: 
 7423: skip_line:
 7424: 
 7425:     if (forsw) goto for_end;
 7426:     goto next_line;
 7427: 
 7428: }               /*end of xecline() */
 7429: 
 7430: void on_frame_entry(void)
 7431: {
 7432:     return;
 7433: }
 7434: 
 7435: void rbuf_dump(void)
 7436: {
 7437:     register int i;
 7438:     char rnam[256];
 7439:     char rpth[256];
 7440:     char ldtime[80];
 7441:     char flgs[80];
 7442:     time_t ag;
 7443:     struct tm tld;
 7444: 
 7445:     
 7446:     printf ("ROUTINE BUFFER CONFIGURATION\r\n");
 7447:     printf ("    ROUTINE BUFFER COUNT:                 %ld\r\n", NO_OF_RBUF);
 7448:     printf ("    MAX. ROUTINE BUFFER COUNT:            %d\r\n", MAXNO_OF_RBUF);
 7449:     printf ("    DEFAULT ROUTINE BUFFER SIZE (EACH):   %d BYTES\r\n", DEFPSIZE0 - 1);
 7450:     printf ("    CURRENT ROUTINE BUFFER SIZE (EACH):   %ld BYTES\r\n\r\n", PSIZE0 - 1);
 7451:     printf ("BUFFERS IN USE:\r\n\r\n");
 7452: 
 7453:     
 7454:     for (i = 0; i < NO_OF_RBUF; i++) {
 7455: 
 7456:         sprintf (flgs, "");
 7457:         
 7458:         if (ages[i] == 0) {
 7459:             sprintf (rnam, "---------");
 7460:             sprintf (rpth, "[buffer empty]");
 7461:             sprintf (ldtime, "n/a");
 7462:             sprintf (flgs, "n/a");
 7463:         }
 7464:         else {
 7465:             stcpy (rnam, pgms[i]);
 7466:             stcnv_m2c (rnam);
 7467: 
 7468:             stcpy (rpth, path[i]);
 7469:             stcnv_m2c (rpth);
 7470: 
 7471:             ag = ages[i];
 7472:             tld = *localtime (&ag);
 7473:             
 7474:             strftime (ldtime, 80, "%a %Y-%m-%d %H:%M:%S %Z", &tld);
 7475:             if (rbuf_flags[i].dialect != D_FREEM) {
 7476:                 strcat (flgs, "STANDARD");
 7477: 
 7478:                 switch (rbuf_flags[i].dialect) {
 7479: 
 7480:                     case D_M77:
 7481:                         strcat (flgs, " [M 1977]");
 7482:                         break;
 7483: 
 7484:                     case D_M84:
 7485:                         strcat (flgs, " [M 1984]");
 7486:                         break;
 7487: 
 7488:                     case D_M90:
 7489:                         strcat (flgs, " [M 1990]");
 7490:                         break;
 7491: 
 7492:                     case D_M95:
 7493:                         strcat (flgs, " [M 1995]");
 7494:                         break;
 7495: 
 7496:                     case D_MDS:
 7497:                         strcat (flgs, " [MILLENNIUM DRAFT]");
 7498:                         break;
 7499: 
 7500:                     case D_M5:
 7501:                         strcat (flgs, " [M5]");
 7502:                         break;
 7503:                 }
 7504:                 
 7505:             }
 7506:             else {
 7507:                 strcat (flgs, "FREEM");
 7508:             }
 7509:         }
 7510: 
 7511:         if (ages[i] != 0) {
 7512:             printf ("#%d [ROUTINE '%s']\r\n", i, rnam);
 7513:             printf ("  UNIX PATH:        %s\r\n", rpth);
 7514:             printf ("  LAST ACCESS:      %s\r\n", ldtime);
 7515:             printf ("  DIALECT:          %s\r\n", flgs);
 7516:         }
 7517:         
 7518:     }
 7519:     
 7520: }
 7521: 
 7522: short rbuf_slot_from_name(char *rnam)
 7523: {
 7524:     register short i;
 7525: 
 7526:     for (i = 0; i < NO_OF_RBUF; i++) {
 7527:         if (stcmp (rnam, pgms[i]) == 0) {
 7528:             return i;
 7529:         }
 7530:     }
 7531: 
 7532:     return -1;
 7533: }
 7534: 
 7535: short is_standard(void)
 7536: {
 7537: 
 7538:     if (rtn_dialect () == D_FREEM) {
 7539:         return FALSE;
 7540:     }
 7541:     else {
 7542:         return TRUE;
 7543:     }
 7544:     
 7545: }
 7546: 
 7547: int rtn_dialect(void)
 7548: {
 7549:     short slot;
 7550: 
 7551:     slot = rbuf_slot_from_name (rou_name);
 7552: 
 7553:     return rbuf_flags[slot].dialect;
 7554: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>