File:  [Coherent Logic Development] / freem / src / xecline.c
Revision 1.9: download - view: text, annotated - select for diffs
Mon Mar 24 04:13:12 2025 UTC (6 months ago) by snw
Branches: MAIN
CVS tags: HEAD
Replace action macro dat with fra_dat to avoid symbol conflict on OS/2

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

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