Annotation of freem/src/expr.c, revision 1.19

1.1       snw         1: /*
1.19    ! snw         2:  *   $Id: expr.c,v 1.18 2025/05/02 16:30:16 snw Exp $
1.1       snw         3:  *    expression parser
                      4:  *
                      5:  *  
1.4       snw         6:  *   Author: Serena Willis <snw@coherent-logic.com>
1.1       snw         7:  *    Copyright (C) 1998 MUG Deutschland
1.5       snw         8:  *    Copyright (C) 2020, 2023, 2025 Coherent Logic Development LLC
1.1       snw         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:  *
1.6       snw        26:  *   $Log: expr.c,v $
1.19    ! snw        27:  *   Revision 1.18  2025/05/02 16:30:16  snw
        !            28:  *   Fix broken build due to time issues
        !            29:  *
1.18      snw        30:  *   Revision 1.17  2025/05/01 03:56:29  snw
                     31:  *   -m
                     32:  *
1.17      snw        33:  *   Revision 1.16  2025/04/30 20:03:09  snw
                     34:  *   Work on entryref parser
                     35:  *
1.16      snw        36:  *   Revision 1.15  2025/04/30 14:41:03  snw
                     37:  *   Further debugger work
                     38:  *
1.15      snw        39:  *   Revision 1.14  2025/04/14 23:20:23  snw
                     40:  *   Restore support for any 8-bit character in
                     41:  *
1.14      snw        42:  *   Revision 1.13  2025/04/13 04:22:43  snw
                     43:  *   Fix snprintf calls
                     44:  *
1.13      snw        45:  *   Revision 1.12  2025/04/10 01:24:38  snw
                     46:  *   Remove C++ style comments
                     47:  *
1.12      snw        48:  *   Revision 1.11  2025/03/30 01:36:58  snw
                     49:  *   Make it easier to bring back fma_gedit, fix double-free in global handler, limit $CHAR to 7-bit ASCII
                     50:  *
1.11      snw        51:  *   Revision 1.10  2025/03/24 04:13:11  snw
                     52:  *   Replace action macro dat with fra_dat to avoid symbol conflict on OS/2
                     53:  *
1.10      snw        54:  *   Revision 1.9  2025/03/24 01:32:22  snw
                     55:  *   Guard declaration of time function in expr.c for portability
                     56:  *
1.9       snw        57:  *   Revision 1.8  2025/03/22 04:47:18  snw
                     58:  *   Silently truncate long names in STRING exprs when  evaluates to an obsolete MDC standard
                     59:  *
1.8       snw        60:  *   Revision 1.7  2025/03/22 03:39:23  snw
                     61:  *   Fix reverse query polyfill call-in from C side and make NAME exprs silently truncate long names in obsolete MDC dialects
                     62:  *
1.7       snw        63:  *   Revision 1.6  2025/03/22 03:05:19  snw
                     64:  *   Comply with X11-96/13 portable length of names
                     65:  *
1.6       snw        66:  *   Revision 1.5  2025/03/09 19:14:24  snw
                     67:  *   First phase of REUSE compliance and header reformat
                     68:  *
1.5       snw        69:  *
                     70:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
                     71:  * SPDX-License-Identifier: AGPL-3.0-or-later 
1.1       snw        72:  **/
                     73: 
                     74: #if !defined(__osf__)
                     75: #include <sys/types.h>
                     76: #endif
                     77: #if !defined(__OpenBSD__) && !defined(__FreeBSD__)
                     78: # include <sys/timeb.h>
                     79: #endif
                     80: #include <stdlib.h>
                     81: #include <string.h>
                     82: #include <ctype.h>
                     83: 
                     84: /* mumps expression evaluator */
                     85: 
                     86: #include "mpsdef.h"
                     87: #include "transact.h"
                     88: #include "merr.h"
                     89: #include "mtok.h"
                     90: #include "version.h"
                     91: #if defined(HAVE_STDINT_H)
                     92: # include <stdint.h>
                     93: #endif
                     94: #if !defined(__osf__) && !defined(_AIX)
                     95: # define _XOPEN_SOURCE
                     96: #endif
                     97: 
                     98: #if defined(USE_SYS_TIME_H) && !defined(MSDOS) && !defined(__osf__)
                     99: # include <sys/time.h>
                    100: #else
                    101: # include <time.h> 
                    102: #endif
                    103: 
                    104: #if defined(MSDOS) || defined(__linux__)
                    105: # include <time.h>
                    106:   char *strptime(const char *restrict s, const char *restrict format, struct tm *restrict tm);
                    107: #endif
                    108: 
                    109: #include "mref.h"
                    110: #include "journal.h"
                    111: #include "datatypes.h"
                    112: #include "objects.h"
                    113: 
                    114: #define OPERAND       1
                    115: #define ARRAY         2
                    116: #define FNUMBER       3
                    117: #define REVERSE       4
                    118: #define TRANSLATE     5
                    119: #define QLENGTH       6
                    120: #define QSUBSCRIPT    7
                    121: #define TYPE          31
                    122: #define INSTANCEOF    32
                    123: 
                    124: #define ZCRC          8
                    125: #define ZDATA         9
                    126: #define ZLSD         11
                    127: #define ZNEXT        12
                    128: #define ZPREVIOUS    17
                    129: #define ZTRAP        18
                    130: 
                    131: #define SVNsystem    19
                    132: #define SVNtimezone  20
                    133: #define SVNtlevel    22
                    134: #define SVNtrollback 23
                    135: #define SVNecode     24
                    136: #define SVNestack    25
                    137: #define SVNetrap     26
                    138: #define SVNstack     27
                    139: #define SVNpdisplay   28
                    140: #define SVNdialect    29
                    141: #define SVNzut 30
                    142: 
                    143: #define OR                '!'
                    144: #define MODULO            '#'
                    145: #define DIVIDE            '/'
                    146: #define AND               '&'
                    147: #define NOT               '\''
                    148: #define XOR               '~'
                    149: #define MULTIPLY          '*'
                    150: #define POWER             ' '
                    151: #define PLUS              '+'
                    152: #define MINUS             '-'
                    153: #define LESS              '<'
                    154: #define EQUAL             '='
                    155: #define GREATER           '>'
                    156: #define PATTERN           '?'
                    157: #define INDIRECT          '@'
                    158: #define CONTAINS          '['
                    159: #define INTDIVIDE         '\\'
                    160: #define FOLLOWS           ']'
                    161: #define CONCATENATE       '_'
                    162: #define SORTSAFTER        '.'
                    163: #define EQFOLLOWS         ','
                    164: #define EQSORTS           ';'
                    165: #define MAXOP             ':'
                    166: #define MINOP             '%'
                    167: 
                    168: #define GET               'Y'
                    169: #define GETX              ':'
                    170: 
1.18      snw       171: #if !defined(__OpenBSD__) && !defined(_AIX) && !defined(__osf__) && !defined(MSDOS) && !defined(__vax__) && !defined(__OS2__) && !defined(__linux__)
1.1       snw       172: long    time ();
                    173: #endif
1.2       snw       174: void cond_round (char *a, int digits);
                    175: void zkey (char *a, long type);
                    176: int levenshtein (char *word1, char *word2);
1.1       snw       177: time_t     horolog_to_unix (char *horo);
                    178: extern int xecline(int typ);
                    179: short      rbuf_slot_from_name(char *);
                    180: 
                    181: 
                    182: short obj_field = FALSE;
                    183: char object_instance[50];
                    184: char object_class[50];
                    185: 
                    186: 
                    187: /*
                    188:  * expr():  expression parser
                    189:  *  extyp:  type of expression; one of:
                    190:  *          STRING
                    191:  *          NAME
                    192:  *          LABEL
                    193:  *          OFFSET
                    194:  *          ARGIND
                    195:  */
                    196: void expr (short extyp)
                    197: {
                    198:     char op_stck[PARDEPTH + 1]; /* operator/operandflag stack */
                    199:     short spx;          /* stack pointer:             */
                    200:     short zexflag;          /* z 'intrinsic' function flag */
                    201:     int atyp, btyp;         /* DM/EUR currency types */
                    202:     char *a;                /* pointer to current (left) argument */
                    203:     char *b;                /* pointer to right hand argument     */
                    204:     char tmp[256];
                    205:     int refsx;          /* zref/zloc stack_counter  */
                    206:     char *refsav[PARDEPTH];     /* zref/zloc stack          */
                    207:     
                    208: 
                    209:     register int i = 0;
                    210:     register int j = 0;
                    211:     register int f = 0;
                    212:     volatile int ch = 0;
                    213:     
                    214:     short   group;          /* flag to scan grouped patterns */
1.6       snw       215: 
                    216:     int  max_namlen = 255;
                    217: 
                    218:     if ((rtn_dialect () == D_MDS) || (rtn_dialect () == D_M5) || (rtn_dialect () == D_FREEM)) {
                    219:         max_namlen = 255;
                    220:     }
                    221:     else {
                    222:         max_namlen = 8;
                    223:     }
1.1       snw       224:     
                    225: #ifdef DEBUG_NEWPTR
                    226:     int loop;
                    227: #endif
                    228: 
                    229:     refsx = 0;
                    230: 
                    231:     if (extyp == NAME) {
                    232: 
                    233:         f = *codptr;
                    234:         varnam[0] = f;
                    235:         
                    236:         if ((f >= 'A' && f <= 'Z') || (f >= 'a' && f <= 'z') || f == '^' || f == '$' || f == '%') {
                    237:             
                    238:             i = 1;
                    239:             
                    240:             while (((ch = *++codptr) >= 'A' && ch <= 'Z') ||
                    241:                    (ch >= 'a' && ch <= 'z') ||
                    242:                    (ch >= '0' && ch <= '9' && (i > 1 || f != '^')) ||
                    243:                    f == '^' &&
                    244:                    (((ch == '%' || ch == '$') && i == 1) ||
                    245:                     (ch == '|') ||
                    246:                     (standard == 0 &&
                    247:                      (ch == '.' ||
                    248:                       (ch == '/' && i == 1) ||
                    249:                       (((ch == '/' && varnam[i - 1] != '/') ||
                    250:                         (ch == '%' && varnam[i - 1] == '/')) &&
                    251:                        (varnam[1] == '.' || varnam[1] == '/'))))) || (f != '^') && (ch == '.')) {
                    252: 
1.6       snw       253:                 if ((i + 1) <= max_namlen) {
                    254:                     varnam[i++] = ch;
                    255:                 }
                    256:                 else {
1.7       snw       257:                     if ((rtn_dialect () == D_M77) ||
                    258:                         (rtn_dialect () == D_M84) ||
                    259:                         (rtn_dialect () == D_M90) ||
                    260:                         (rtn_dialect () == D_M95)) {
                    261:                         /* silently truncate... yeah, the standard is stupid af */
                    262:                         continue;
                    263:                     }
                    264:                     else {
                    265:                         merr_raise (M56);
                    266:                         return;
                    267:                     }
1.6       snw       268:                 }                
1.1       snw       269:                 
                    270:             }
                    271: 
1.7       snw       272:             varnam[i] = EOL;
                    273: 
                    274:             #if 0
                    275:             {
                    276:                 char gooby[256];
                    277:                 stcpy (gooby, varnam);
                    278:                 stcnv_m2c (gooby);
                    279:                 printf ("name = '%s'\r\n", gooby);
                    280:             }
                    281:             #endif
1.1       snw       282:             
                    283:             if (ch == '(') {        /* it's an array */
                    284:                 
                    285:                 op_stck[0] = 0;
                    286:                 op_stck[1] = ARRAY;
                    287:                 spx = 1;
                    288:                 a = argptr;
                    289:                 
                    290:                 if ((argstck[1] = a) >= s) {
                    291:                     
                    292:                     char   *bak;
                    293: 
                    294:                     bak = partition;
                    295: 
                    296:                     if (getpmore () == 0) {
                    297:                         merr_raise (STKOV);
                    298:                         return;
                    299:                     }
                    300:                     
                    301:                     a = a - bak + partition;
                    302:                     b = b - bak + partition;
                    303: 
                    304:                 }
                    305: 
                    306:                 a += stcpy (a, varnam) + 1;
                    307:                 
                    308:                 arg = 1;
                    309:                 codptr++;
                    310:                 
                    311:                 goto nextchr;
                    312:             }
                    313: 
                    314:             codptr--;
                    315: 
                    316:             if (i == 1 && f == '^') {
                    317:                 merr_raise (INVEXPR);
                    318:             }
                    319: 
                    320:             return;
                    321: 
                    322:         }
                    323: 
                    324:         if (f != '@') {
                    325:             merr_raise (INVREF);
                    326:             return;
                    327:         }
                    328:     
                    329:     }                   /* end if (extyp ==NAME) */
                    330: 
                    331:     arg = 0;
                    332:     spx = 0;                /* initialisation */
                    333:     op_stck[0] = 0;
                    334:     a = argptr;
                    335: 
                    336:     nextchr:
                    337:     ch = *codptr;
                    338: 
                    339:     if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '%') {
                    340: 
                    341: 
                    342: scan_name:        
                    343: 
                    344:         varnam[0] = ch;
                    345:         i = 1;
                    346:         
                    347:         if (ch == '^') {        /* global variable name */
                    348: 
                    349:             int vb_ct;
                    350:             int qt_ct;
                    351:             char lastch;
                    352:             char nextch;
                    353:             
                    354:             vb_ct = 0;
                    355:             qt_ct = 0;
                    356:             
                    357:             lastch = ' ';
                    358:             
                    359:             while (((ch = *++codptr) >= 'A' && ch <= 'Z') ||
                    360:                    (ch >= 'a' && ch <= 'z') ||
                    361:                    (ch >= '0' && ch <= '9' && i > 1) ||
                    362:                    (ch == '|') || (ch == '%') || (ch == '\"') ||
                    363:                    (((ch == '%' || ch == '$') && i == 1) ||
                    364:                     (standard == 0 &&
                    365:                      (ch == '.' ||
                    366:                       (ch == '/' && i == 1) ||
                    367:                       (((ch == '/' && varnam[i - 1] != '/') ||
                    368:                         (ch == '%' && varnam[i - 1] == '/')) &&
                    369:                        (varnam[1] == '.' || varnam[1] == '/')))))) {
                    370: 
                    371:                 nextch = *(codptr + 1);
                    372:                 
                    373:                 if (ch == '|') vb_ct++;
                    374: 
                    375:                 if (ch == '\"') {
                    376:                     qt_ct++;
                    377:                     
                    378:                     if ((lastch != '|') && (nextch != '|')) {
                    379:                         merr_raise (INVEXPR);
                    380:                         return;
                    381:                     }
                    382:                     
                    383:                 }
                    384: 
                    385:                 if ((ch == '|') && ((nextch != '\"') && (lastch != '\"'))) {
                    386: 
                    387:                     if ((qt_ct == 1) && (vb_ct == 2)) {
                    388:                         merr_raise (QUOTER);
                    389:                         return;
                    390:                     }
                    391:                     else if ((vb_ct == 2) && (qt_ct == 1)){
                    392:                         merr_raise (INVEXPR);
                    393:                         return;
                    394:                     }
                    395:                     
                    396:                 }
                    397:                 
                    398:                 if (vb_ct > 2) {
                    399:                     merr_raise (INVEXPR);
                    400:                     return;
                    401:                 }
1.8       snw       402: 
                    403:                 if ((i + 1) <= max_namlen) {
                    404:                     varnam[i++] = ch;
                    405:                 }
                    406:                 else {
                    407:                     if ((rtn_dialect () == D_M77) ||
                    408:                         (rtn_dialect () == D_M84) ||
                    409:                         (rtn_dialect () == D_M90) ||
                    410:                         (rtn_dialect () == D_M95)) {
                    411:                         /* silently truncate... yeah, the standard is stupid af */
                    412:                         continue;
                    413:                     }
                    414:                     else {
                    415:                         merr_raise (M56);
                    416:                         return;
                    417:                     }
                    418:                 }                
1.1       snw       419: 
                    420:                 lastch = ch;
                    421:             }
                    422: 
                    423:             varnam[i] = EOL;          
                    424:             
                    425:             if (i == 1 && ch != '(') {
                    426:                 merr_raise (INVEXPR);
                    427:                 return;
                    428:             }
                    429: 
                    430:         } 
                    431:         else {          /* local variable name */
                    432: 
                    433:             while (isalnum (ch = *++codptr)) {
1.8       snw       434:                 
                    435:                 if ((i + 1) <= max_namlen) {
                    436:                     varnam[i++] = ch;
                    437:                 }
                    438:                 else {
                    439:                     if ((rtn_dialect () == D_M77) ||
                    440:                         (rtn_dialect () == D_M84) ||
                    441:                         (rtn_dialect () == D_M90) ||
                    442:                         (rtn_dialect () == D_M95)) {
                    443:                         /* silently truncate... yeah, the standard is stupid af */
                    444:                         continue;
                    445:                     }
                    446:                     else {
                    447:                         merr_raise (M56);
                    448:                         return;
                    449:                     }
                    450:                 }                
                    451:                 
1.1       snw       452:             }
                    453:         
                    454:             varnam[i] = EOL;
                    455: 
                    456:             
                    457:             if (*codptr == '.') {
                    458:                 if (*(codptr + 1) == '$') {
                    459:                     codptr++;
                    460: 
                    461:                     obj_field = TRUE;
                    462:                     stcpy (object_instance, varnam);
                    463:                     stcnv_m2c (object_instance);
                    464:                     obj_get_attribute (object_instance, "CLASS", object_class);
                    465: 
                    466:                     stcnv_m2c (object_instance);
                    467:                     stcnv_c2m (object_class);
                    468:                     
                    469:                     expr (STRING);
                    470:                     return;
                    471:                 }
                    472:                 else {
                    473:                     merr_raise (INVEXPR);
                    474:                     return;
                    475:                 }
                    476:             }
                    477:             
                    478:         }
                    479:         
                    480:         if (ch == '(') {        /* it's an array */
                    481:             
                    482:             if (extyp == LABEL) {
                    483:                 codptr--;
                    484:                 return;
                    485:             }
                    486: 
                    487:             if (++spx >= PARDEPTH) {
                    488:                 merr_raise (STKOV);
                    489:                 return;
                    490:             }
                    491: 
                    492:             op_stck[spx] = ARRAY;
                    493:             
                    494:             if ((argstck[++arg] = a) >= s) {
                    495:                 
                    496:                 char   *bak;
                    497:                 bak = partition;
                    498: 
                    499:                 if (getpmore () == 0) {
                    500:                     merr_raise (STKOV);
                    501:                     return;
                    502:                 }
                    503:                 
                    504:                 a = a - bak + partition;
                    505:                 b = b - bak + partition;
                    506: 
                    507:             }
                    508: 
                    509:             a += stcpy (a, varnam) + 1;
                    510:             codptr++;
                    511:             
                    512:             goto nextchr;
                    513: 
                    514:         }
                    515: 
                    516:         if (spx == 0) {
                    517:             
                    518:             if (extyp != STRING && extyp != ARGIND && extyp != OFFSET) {
                    519:                 codptr--;
                    520:                 return;
                    521:             }
                    522: 
                    523:             if (varnam[0] != '^') {
                    524:                 symtab (get_sym, varnam, a);
                    525:             }
                    526:             else if (varnam[1] != '$') {
                    527:                 global (get_sym, varnam, a);
                    528:             }
                    529:             else {
                    530:                 ssvn (get_sym, varnam, a);
                    531:             }
                    532:             
                    533:             if (merr () != OK) {
                    534: 
                    535:                 stcpy (varerr, varnam);
                    536:                 
                    537:                 if (merr () == UNDEF || merr () == M6 || merr () == M7) {
                    538:                     arg = 1;
                    539:                     codptr--;
                    540:                     
                    541:                     goto undefglvn;
                    542:                 }
                    543: 
                    544:             }
                    545: 
                    546:             if (ch == EOL || ch == SP || (extyp == ARGIND) || ch == ',' || ch == ':' || ch == ')' || ch == '@' || (merr () > OK)) {
                    547:                 return;
                    548:             }
                    549: 
                    550:             arg = 1;
                    551:             argstck[1] = a;
                    552:             f = OPERAND;
                    553:             op_stck[1] = f;
                    554:             spx = 2;
                    555: 
                    556:             goto op10;          /* shortcut: following char is garbage or operator */
                    557: 
                    558:         }
                    559: 
                    560:         codptr--;
                    561:         
                    562:         if ((argstck[++arg] = a) >= s) {
                    563:             
                    564:             char   *bak;
                    565:             bak = partition;
                    566: 
                    567:             if (getpmore () == 0) {
                    568:                 merr_raise (STKOV);
                    569:                 return;
                    570:             }
                    571: 
                    572:             a = a - bak + partition;
                    573:             b = b - bak + partition;
                    574: 
                    575:         }
                    576: 
                    577:         /* evaluate glvn or $_(glvn) */
                    578: 
                    579: var1:
                    580:         
                    581:         if (op_stck[spx] == '$') {
                    582: 
                    583:             f = op_stck[spx - 1];
                    584: 
                    585:             
                    586:             switch (f) {
                    587: 
                    588: 
                    589:                 case 'd':           /* $DATA */
                    590:                     
1.10      snw       591:                     ch = fra_dat;
1.1       snw       592: 
                    593: glv_fcn:
                    594: 
                    595:                     if (varnam[0] != '^') {
                    596:                         symtab (ch, varnam, a);
                    597:                     }
                    598:                     else if (varnam[1] != '$'){
                    599:                         global  (ch, varnam, a);
                    600:                     }
                    601:                     else {
                    602:                         ssvn (ch, varnam, a);
                    603:                     }
                    604: 
                    605: d_o_n:
                    606: 
                    607:                     if (*++codptr != ')') merr_raise (INVEXPR);
                    608: 
                    609:                     if (merr () > OK) {
                    610:                         stcpy (varerr, varnam);
                    611:                         return;
                    612:                     }
                    613: 
                    614:                     spx -= 2;
                    615:                     
                    616:                     goto nxt_operator;
                    617: 
                    618: 
                    619:                 case 'o':           /* $ORDER */
                    620: 
                    621:                     if (rtn_dialect () == D_M77) {
                    622:                         merr_raise (NOSTAND);
                    623:                         return;
                    624:                     }
                    625:                     
                    626:                     ch = fra_order;
                    627:                     ordercnt = 1L;
                    628:                     
                    629:                     if (*(codptr + 1) != ',') {
                    630:                         ordercounter = 0;
                    631:                         goto glv_fcn;
                    632:                     }
                    633: 
                    634:                     if (++spx > PARDEPTH) {
                    635:                         merr_raise (STKOV);
                    636:                         return;
                    637:                     }
                    638: 
                    639:                     stcpy (a, varnam);
                    640:                     
                    641:                     op_stck[spx] = OPERAND;
                    642:                     codptr++;
                    643:                     
                    644:                     goto nextchr;
                    645: 
                    646: 
                    647:                 case 'n':           /* $NEXT */
                    648: 
                    649:                     ordercnt = 1L;
                    650:                     ordercounter = 0;
                    651:                     
                    652:                     if (varnam[0] != '^') {
                    653:                         symtab (fra_order, varnam, a);
                    654:                     }
                    655:                     else if (varnam[1] != '$') {
                    656:                         global  (fra_order, varnam, a);
                    657:                     }
                    658:                     else {
                    659:                         ssvn (fra_order, varnam, a);
                    660:                     }
                    661: 
                    662:                     if (a[0] == EOL) {
                    663:                         a[0] = '-';
                    664:                         a[1] = '1';
                    665:                         a[2] = EOL;
                    666:                     }
                    667: 
                    668:                     goto d_o_n;
                    669: 
                    670: 
                    671:                 case 'q':           /* $QUERY */
                    672:                 case 'O':           /* $ZORDER */
                    673:                 
                    674:                     ch = fra_query;
                    675:                     ordercnt = 1L;
                    676:                     
                    677:                     if (*(codptr + 1) != ',') goto glv_fcn;
                    678: 
                    679:                     if (++spx > PARDEPTH) {
                    680:                         merr_raise (STKOV);
                    681:                         return;
                    682:                     }
                    683: 
                    684:                     stcpy (a, varnam);
                    685:                     
                    686:                     op_stck[spx] = OPERAND;
                    687:                     codptr++;
                    688:                     
                    689:                     goto nextchr;
                    690: 
                    691: 
                    692:                 case ZNEXT:     /* $ZNEXT */
                    693: 
                    694:                     ordercnt = 1L;
                    695:                     
                    696:                     if (varnam[0] != '^') {
                    697:                         symtab (fra_query, varnam, a);
                    698:                     }
                    699:                     else if (varnam[1] != '$') {
                    700:                         global  (fra_query, varnam, a);
                    701:                     }
                    702:                     else {
                    703:                         ssvn (fra_query, varnam, a);
                    704:                     }
                    705:                     
                    706:                     if (a[0] == EOL) {
                    707:                         a[0] = '-';
                    708:                         a[1] = '1';
                    709:                         a[2] = EOL;
                    710:                     }
                    711: 
                    712:                     goto d_o_n;
                    713: 
                    714: 
                    715:                 case 'N':           /* $NAME */
                    716: 
                    717:                     /* resolve naked reference */
                    718:                     if (varnam[0] == '^' && varnam[1] == DELIM) {
                    719:                         
                    720:                         stcpy (a, zref);
                    721:                         ch = stlen (a);
                    722:                         
                    723:                         while (a[ch--] != DELIM) {
                    724:                         
                    725:                             if (ch <= 0) {
                    726:                                 merr_raise (NAKED);
                    727:                                 return;
                    728:                             }
                    729:                         
                    730:                         }
                    731: 
                    732:                         stcpy (&a[++ch], &varnam[1]);
                    733:                         stcpy (varnam, a);
                    734: 
                    735:                     }
                    736: 
                    737:                     if (*(codptr + 1) != ',') {
                    738:                         zname (a, varnam);
                    739:                         goto d_o_n;
                    740:                     }
                    741: 
                    742:                     if (++spx > PARDEPTH) {
                    743:                         merr_raise (STKOV);
                    744:                         return;
                    745:                     }
                    746: 
                    747:                     stcpy (a, varnam);
                    748:                     
                    749:                     op_stck[spx] = OPERAND;
                    750:                     codptr++;
                    751:                     
                    752:                     goto nextchr;
                    753: 
                    754: 
                    755:                 case ZPREVIOUS:     /* $ZPREVIOUS */
                    756: 
                    757:                     ordercnt = (-1L);
                    758:                     ordercounter = 0;
                    759:                     ch = fra_order;
                    760:                     
                    761:                     goto glv_fcn;
                    762: 
                    763: 
                    764:                 case ZDATA:     /* $ZDATA */
                    765: 
                    766:                     ch = zdata;
                    767:                     goto glv_fcn;
                    768: 
                    769: 
                    770:                 case 'g':           /* $GET */
                    771:                     
                    772:                     if (varnam[0] != '^') {
                    773:                         symtab (get_sym, varnam, a);
                    774:                     }
                    775:                     else if (varnam[1] != '$') {
                    776:                         global (get_sym, varnam, a);
                    777:                     }
                    778:                     else {
                    779:                         ssvn (get_sym, varnam, a);
                    780:                     }
                    781: 
                    782:                     if (merr () == M7 || merr () == M6) merr_raise (UNDEF);
                    783: 
                    784:                     if (merr () > OK) {
                    785: 
                    786:                         stcpy (varerr, varnam);
                    787:                     
                    788:                         if (merr () != UNDEF) return;
                    789:                     }
                    790:                     
                    791:                     if (merr () == UNDEF) {
                    792: 
1.12      snw       793:                         /* smw 15 nov 2023 merr_raise (ierr < 0 ? OK - CTRLB : OK); */
1.1       snw       794:                         merr_clear ();
                    795:                         
                    796:                         if (*++codptr == ',') {
                    797: 
                    798:                             if (standard) {
                    799:                                 merr_raise (NOSTAND);
                    800:                                 return;
                    801:                             }
                    802: 
                    803:                             op_stck[spx - 1] = GET;     /* dummy function for $GET */
                    804:                             arg--;
                    805:                             codptr++;
                    806:                             
                    807:                             goto nextchr;
                    808:                         
                    809:                         } 
                    810:                         else {
                    811: 
                    812:                             if (*codptr != ')') {
                    813:                                 merr_raise (INVEXPR);
                    814:                                 return;
                    815:                             }
                    816: 
                    817:                             *a = EOL;
                    818: 
                    819:                         }
                    820: 
                    821:                     } 
                    822:                     else {        /* glvn was defined */
                    823:                         
                    824:                         if (*++codptr == ',') { /* skip second argument */
                    825:                             
                    826:                             i = 0;      /* quote flag */                            
                    827:                             f = 0;      /* bracket counter */
                    828: 
                    829:                             for (;;) {
                    830: 
                    831:                                 ch = *++codptr;
                    832:                                 
                    833:                                 if (ch == EOL) {
                    834:                                     merr_raise (INVEXPR);
                    835:                                     return;
                    836:                                 }
                    837: 
                    838:                                 if (ch == '"') {
                    839:                                     i = !i;
                    840:                                     continue;
                    841:                                 }
                    842: 
                    843:                                 if (i) continue;
                    844:                                 
                    845:                                 if (ch == '(') {
                    846:                                     f++;
                    847:                                     continue;
                    848:                                 }
                    849: 
                    850:                                 if (ch == ')') {
                    851:                                     if (--f < 0) break;
                    852:                                 }
                    853: 
                    854:                             }
                    855: 
                    856:                         } 
                    857:                         else if (*codptr != ')') {
                    858:                             merr_raise (INVEXPR);
                    859:                             return;
                    860:                         }
                    861: 
                    862:                     }
                    863: 
                    864:                     spx -= 2;
                    865:                     goto nxt_operator;
                    866: 
                    867:                 case 'i':           /* $INCREMENT */
                    868:                     
                    869:                     if (varnam[0] != '^') {
                    870:                         symtab (getinc, varnam, a);
                    871:                     }
                    872:                     else {
                    873:                         
                    874:                         int setopsav;
                    875: 
                    876:                         setopsav = setop;
                    877:                         setop = '+';
                    878:                         a[0] = '1';
                    879:                         a[1] = EOL;
                    880:                         
                    881:                         if (varnam[1] != '$') {
                    882:                             global  (set_sym, varnam, a);
                    883:                         }
                    884:                         else {
                    885:                             ssvn (set_sym, varnam, a);
                    886:                         }
                    887: 
                    888:                         setop = setopsav;
                    889: 
                    890:                     }
                    891: 
                    892:                     goto d_o_n;
                    893: 
                    894: 
                    895:                 case OPERAND:       /* three arguments $TEXT */
                    896: 
                    897:                     if (spx >= 6 && op_stck[spx - 5] == 't' && op_stck[spx - 4] == '$' && op_stck[spx - 2] == '$') {
                    898:                         
                    899:                         stcpy (a, &varnam[varnam[0]=='^']); /* third argument */
                    900:                         
                    901:                         if (++spx > PARDEPTH) {
                    902:                             merr_raise (STKOV);
                    903:                             return;
                    904:                         }
                    905: 
                    906:                         op_stck[spx] = OPERAND;
                    907:                         codptr++;
                    908:                         
                    909:                         goto nextchr;
                    910: 
                    911:                     }
                    912: 
                    913:             }               /* end switch */
                    914:         }
                    915:         
                    916:         /* retrieve look-up */
                    917: 
                    918:         if (varnam[0] != '^') {
                    919:             symtab (get_sym, varnam, a);
                    920:         }
                    921:         else if (varnam[1] != '$') {
                    922:             global  (get_sym, varnam, a);
                    923:         }
                    924:         else {
                    925:             ssvn (get_sym, varnam, a);
                    926:         }
                    927: 
                    928: 
                    929: undefglvn:
                    930: 
                    931: 
                    932:         if (merr ()) stcpy (varerr, varnam);
                    933:         
                    934:         if ((merr () == M6) || (merr () == M7) || (merr () == UNDEF)) {
                    935:             
                    936:             stcpy (tmp, codptr + 1);
                    937:             
                    938:             if (varnam[0] == '^') { /* is there a default expression?? */
                    939:                 
                    940:                 if (gvndefault[0] == EOL) return;
                    941:                 
                    942:                 stcpy (&code[1], gvndefault);
                    943: 
                    944:             } 
                    945:             else {
                    946: 
                    947:                 if (lvndefault[0] == EOL) return;
                    948:             
                    949:                 stcpy (&code[1], lvndefault);
                    950:             
                    951:             }
                    952:             
                    953:             /* simulate a $GET function */
                    954:             code[0] = SP;
                    955:             
                    956:             stcat (code, ")\201");
                    957:             stcat (code, tmp);
                    958:             
                    959:             codptr = &code[1];
                    960:             
                    961:             if (((++spx) + 1) > PARDEPTH) {
                    962:                 merr_raise (STKOV);
                    963:                 return;
                    964:             }
                    965: 
                    966:             op_stck[spx] = GETX;    /* dummy function for $GET */
                    967:             op_stck[++spx] = '$';
                    968:             
                    969:             /* stack $ZREFERENCE and $ZLOCAL */
                    970:             if ((refsav[refsx] = calloc (1, 2 * 256)) == NULL) {
                    971:                 merr_raise (STKOV);
                    972:                 return;
                    973:             }               /* could not allocate stuff...     */
                    974:             
                    975:             stcpy (refsav[refsx], zref);
                    976:             stcpy (refsav[refsx++] + 256, zloc);
                    977:             
1.12      snw       978:             ierr -= M7; 
1.1       snw       979:             arg--;
                    980:             
                    981:             goto nextchr;
                    982: 
                    983:         }
                    984: 
                    985:         if (merr () > OK) return;
                    986: 
                    987:         if (spx == 0) {
                    988: 
                    989:             if ((ch = *++codptr) == EOL || ch == SP || ch == ',' || ch == ':') return;
                    990: 
                    991:             if (++spx > PARDEPTH) {
                    992:                 merr_raise (STKOV);
                    993:                 return;
                    994:             }
                    995: 
                    996:             op_stck[spx] = OPERAND;
                    997:             
                    998:             goto next10;
                    999: 
                   1000:         }
                   1001: 
                   1002:         f = op_stck[spx];
                   1003:         
                   1004:         if (f == ARRAY || f == '(') {
                   1005:             
                   1006:             if (++spx > PARDEPTH) {
                   1007:                 merr_raise (STKOV);
                   1008:                 return;
                   1009:             }
                   1010: 
                   1011:             op_stck[spx] = OPERAND;
                   1012:             codptr++;
                   1013:             
                   1014:             goto nextchr;
                   1015: 
                   1016:         }
                   1017: 
                   1018:         if (f == INDIRECT && (extyp == STRING || extyp == ARGIND || extyp == OFFSET)) {
                   1019:             spx--;
                   1020:             goto indirect;      /* VARIABLE indirection */
                   1021:         }
                   1022: 
                   1023:         goto nxt_expr;
                   1024: 
                   1025:     }
                   1026: 
                   1027:     if (ch >= '0' && ch <= '9') {
                   1028: 
                   1029:         if (extyp == LABEL) goto scan_name;     /* scan_label */
                   1030: 
                   1031:         /* scan number */
                   1032:         i = 0;              /* point flag */
                   1033:         j = 0;              /* exp flag */
                   1034:         f = ch;             /* first character */
                   1035: 
                   1036:         if ((argstck[++arg] = a) >= s) {
                   1037:             
                   1038:             char   *bak;
                   1039:             bak = partition;
                   1040:             
                   1041:             if (getpmore () == 0) {
                   1042:                 merr_raise (STKOV);
                   1043:                 return;
                   1044:             }
                   1045: 
                   1046:             a = a - bak + partition;
                   1047: 
                   1048:         }
                   1049: 
                   1050:         b = a;
                   1051: 
                   1052: p_entry:           /* entry point if first character was a point */
                   1053:         
                   1054:         for (;;) {
                   1055: 
                   1056:             if (ch < '0') {
                   1057: 
                   1058:                 if (ch != '.' || i || j) break;
                   1059:             
                   1060:                 i++;
                   1061: 
                   1062:             } 
                   1063:             else if (ch > '9') {
                   1064: 
                   1065:                 if (j) break;
                   1066:                 if (ch != 'E' && (lowerflag == FALSE || ch != 'e')) break;
                   1067:                 
                   1068:                 if (ch == 'E') {
                   1069:                     if ((*(codptr + 1) == 'U') && (*(codptr + 2) == 'R')) break;
                   1070:                     if ((*(codptr + 1) == 'S') && (*(codptr + 2) == 'P')) break;
                   1071:                 }
                   1072: 
                   1073:                 j++;
                   1074:                 
                   1075:                 do {
                   1076: 
                   1077:                     *b++ = ch;
                   1078:                     ch = *++codptr;
                   1079: 
                   1080:                 } while (ch == '+' || ch == '-');
                   1081: 
                   1082:             }
                   1083: 
                   1084:             *b++ = ch;
                   1085:             ch = *++codptr;
                   1086: 
                   1087:         }
                   1088: 
                   1089: #ifdef EUR2DEM
                   1090: 
                   1091:         switch (ch) {
                   1092: 
                   1093:             case 'E':
                   1094:                 
                   1095:                 if ((*(codptr + 1) == 'U') && (*(codptr + 2) == 'R')) {
                   1096:                     *b++ = ch;
                   1097:                     *b++ = *++codptr;
                   1098:                     *b++ = *++codptr;
                   1099:                     ch = *++codptr;
                   1100:                     j = 1;
                   1101:                     
                   1102:                     break;
                   1103:                 }
                   1104: 
                   1105:                 if ((*(codptr + 1) == 'S') && (*(codptr + 2) == 'P')) {
                   1106:                     *b++ = ch;
                   1107:                     *b++ = *++codptr;
                   1108:                     *b++ = *++codptr;
                   1109:                     ch = *++codptr;
                   1110:                     j = 1;
                   1111:                 }
                   1112: 
                   1113:                 break;
                   1114: 
                   1115: 
                   1116:             case 'D':
                   1117: 
                   1118:                 if (*(codptr + 1) == 'M') {
                   1119:                     *b++ = ch;
                   1120:                     *b++ = *++codptr;
                   1121:                     ch = *++codptr;
                   1122:                     j = 1;
                   1123: 
                   1124:                     break;
                   1125:                 }
                   1126: 
                   1127:                 if (*(codptr + 1) == 'E' && *(codptr + 2) == 'M') {
                   1128:                     *b++ = ch;
                   1129:                     *b++ = *++codptr;
                   1130:                     *b++ = *++codptr;
                   1131:                     ch = *++codptr;
                   1132:                     j = 1;
                   1133:                 }
                   1134: 
                   1135:                 break;
                   1136:             
                   1137: 
                   1138:             case 'A':
                   1139: 
                   1140:                 if (*(codptr + 1) == 'T' && *(codptr + 2) == 'S') {
                   1141:                     *b++ = ch;
                   1142:                     *b++ = *++codptr;
                   1143:                     *b++ = *++codptr;
                   1144:                     ch = *++codptr;
                   1145:                     j = 1;
                   1146:                 }
                   1147: 
                   1148:                 break;
                   1149:             
                   1150: 
                   1151:             case 'B':
                   1152:                 
                   1153:                 if (*(codptr + 1) == 'F' && *(codptr + 2) == 'R') {
                   1154:                     *b++ = ch;
                   1155:                     *b++ = *++codptr;
                   1156:                     *b++ = *++codptr;
                   1157:                     ch = *++codptr;
                   1158:                     j = 1;
                   1159:                 }
                   1160:                 
                   1161:                 break;
                   1162: 
                   1163: 
                   1164:             case 'F':
                   1165: 
                   1166:                 if (*(codptr + 1) == 'F') {
                   1167:                     *b++ = ch;
                   1168:                     *b++ = *++codptr;
                   1169:                     ch = *++codptr;
                   1170:                     j = 1;
                   1171: 
                   1172:                     break;
                   1173:                 }
                   1174: 
                   1175:                 if (*(codptr + 1) == 'M' && *(codptr + 2) == 'K') {
                   1176:                     *b++ = ch;
                   1177:                     *b++ = *++codptr;
                   1178:                     *b++ = *++codptr;
                   1179:                     ch = *++codptr;
                   1180:                     j = 1;
                   1181:                     
                   1182:                     break;
                   1183:                 }
                   1184: 
                   1185:                 if (*(codptr + 1) == 'R' && *(codptr + 2) == 'F') {
                   1186:                     *b++ = ch;
                   1187:                     *b++ = *++codptr;
                   1188:                     *b++ = *++codptr;
                   1189:                     ch = *++codptr;
                   1190:                     j = 1;
                   1191:                 }
                   1192: 
                   1193:                 break;
                   1194:             
                   1195: 
                   1196:             case 'I':
                   1197: 
                   1198:                 if (*(codptr + 1) == 'E' && *(codptr + 2) == 'P') {
                   1199:                     *b++ = ch;
                   1200:                     *b++ = *++codptr;
                   1201:                     *b++ = *++codptr;
                   1202:                     ch = *++codptr;
                   1203:                     j = 1;
                   1204: 
                   1205:                     break;
                   1206:                 }
                   1207: 
                   1208:                 if (*(codptr + 1) == 'T' && *(codptr + 2) == 'L') {
                   1209:                     *b++ = ch;
                   1210:                     *b++ = *++codptr;
                   1211:                     *b++ = *++codptr;
                   1212:                     ch = *++codptr;
                   1213:                     j = 1;
                   1214:                 }
                   1215: 
                   1216:                 break;
                   1217:             
                   1218: 
                   1219:             case 'N':
                   1220:                 
                   1221:                 if (*(codptr + 1) == 'L' && *(codptr + 2) == 'G') {
                   1222:                     *b++ = ch;
                   1223:                     *b++ = *++codptr;
                   1224:                     *b++ = *++codptr;
                   1225:                     ch = *++codptr;
                   1226:                     j = 1;
                   1227:                 }
                   1228: 
                   1229:                 break;
                   1230:             
                   1231: 
                   1232:             case 'P':
                   1233: 
                   1234:                 if (*(codptr + 1) == 'T' && *(codptr + 2) == 'E') {
                   1235:                     *b++ = ch;
                   1236:                     *b++ = *++codptr;
                   1237:                     *b++ = *++codptr;
                   1238:                     ch = *++codptr;
                   1239:                     j = 1;
                   1240:                 }
                   1241: 
                   1242: 
                   1243:         }
                   1244: 
                   1245: #endif /* EUR2DEM */
                   1246: 
                   1247:         *b = EOL;
                   1248: 
                   1249:         if (j || f == '0' || (i && ((*(b - 1)) < '1'))) {   /* <'1' eqiv. to '.' || '0' */
                   1250:             atyp = numlit (a);
                   1251:             if (atyp) stcat (a, WHR[atyp]);
                   1252:         }
                   1253: 
                   1254:         
                   1255:         if (spx) {
                   1256:             codptr--;
                   1257:             goto exec;
                   1258:         }
                   1259: 
                   1260:         if (ch == EOL || ch == SP || ch == ',' || ch == ':' || (ch == '^' && extyp == OFFSET)) return;
                   1261:         
                   1262:         spx = 1;
                   1263:         op_stck[1] = OPERAND;
                   1264: 
                   1265:     }
                   1266: 
                   1267:     if (ch != '"') goto next10;
                   1268: 
                   1269:     /* scan string */
                   1270:     if ((argstck[++arg] = a) >= s) {
                   1271: 
                   1272:         char *bak;
                   1273: 
                   1274:         bak = partition;
                   1275:         
                   1276:         if (getpmore () == 0) {
                   1277:             merr_raise (STKOV);
                   1278:             return;
                   1279:         }
                   1280: 
                   1281:         a = a - bak + partition;
                   1282:         b = b - bak + partition;
                   1283: 
                   1284:     }
                   1285: 
                   1286:     i = 0;
                   1287: 
                   1288:     for (;;) {
                   1289: 
                   1290:         while ((ch = *++codptr) > '"') {
                   1291:             a[i++] = ch;
                   1292:         }
                   1293:         
                   1294:         /* we make use of the fact that */
                   1295:         /* EOL < "any ASCII character" */
                   1296:         if (ch == '"' && (ch = *++codptr) != '"') {
                   1297: 
                   1298:             if (ch == '_' && *(codptr + 1) == '"') {
                   1299:                 codptr++;
                   1300:                 continue;
                   1301:             }
                   1302:             
                   1303:             a[i] = EOL;
                   1304:             
                   1305:             if (spx) {
                   1306:                 codptr--;
                   1307:                 goto exec;
                   1308:             }
                   1309:             
                   1310:             if (ch == EOL || ch == SP || ch == ',' || ch == ':') return;
                   1311:             
                   1312:             spx = 1;
                   1313:             op_stck[1] = OPERAND;
                   1314:             
                   1315:             goto next10;
                   1316: 
                   1317:         }
                   1318: 
                   1319:         if (ch == EOL) {
                   1320:             merr_raise (QUOTER);
                   1321:             return;
                   1322:         }
                   1323: 
                   1324:         a[i++] = ch;
                   1325: 
                   1326:     }
                   1327: 
                   1328: next05:
                   1329:     
                   1330:     ch = *(++codptr);
                   1331: 
                   1332: next10:
                   1333: 
                   1334:     switch (ch) {
                   1335: 
                   1336:         
                   1337:         case EOL:
                   1338:         case SP:
                   1339: 
                   1340:             if (op_stck[1] == OPERAND && spx == 1) return;
                   1341:         
                   1342:             merr_raise (INVEXPR);
                   1343:             return;
                   1344: 
                   1345: 
                   1346:         case ',':
                   1347: 
                   1348:             if (spx == 0) {
                   1349:                 merr_raise (ARGER);
                   1350:                 return;
                   1351:             }
                   1352: 
                   1353: 
                   1354: comma:
                   1355: 
                   1356:             f = op_stck[spx - 1];
                   1357: 
                   1358:             /* f= (spx>0 ? op_stck[spx-1] : 0);
                   1359:             * if (f) */ 
                   1360:             switch (f) {
                   1361: 
                   1362:                 case '$':           /* first arg of $function */
                   1363:                     
                   1364:                     if (op_stck[spx - 2] == 's') {  /* we already have one valid arg */
                   1365:                         
                   1366:                         i = 0;          /* quote *//* and skip rest of select */
                   1367:                         j = 0;          /* bracket */
                   1368:                         
                   1369:                         for (;;) {
                   1370: 
                   1371:                             ch = *++codptr;
                   1372:                             
                   1373:                             if (ch == '"') {
                   1374:                                 toggle (i);
                   1375:                                 continue;
                   1376:                             }
                   1377: 
                   1378:                             if (i) {
                   1379:                                 if (ch != EOL) continue;
                   1380:                                 
                   1381:                                 merr_raise (QUOTER);
                   1382:                                 return;
                   1383:                             }
                   1384: 
                   1385:                             if (ch == ')') {
                   1386:                                 
                   1387:                                 if (j--) continue;
                   1388:                                 
                   1389:                                 spx -= 3;
                   1390:                                 
                   1391:                                 goto nxt_operator;
                   1392:                             }
                   1393: 
                   1394:                             if (ch == '(') {
                   1395:                                 j++;
                   1396:                                 continue;
                   1397:                             }
                   1398: 
                   1399:                             if (ch == EOL) {
                   1400:                                 merr_raise (SELER);
                   1401:                                 return;
                   1402:                             }
                   1403:                         }
                   1404: 
                   1405:                     }
                   1406: 
                   1407:                     /* function argument */
                   1408:                     /* put comma on the stack */
                   1409:                     if (++spx > PARDEPTH) {
                   1410:                         merr_raise (STKOV);
                   1411:                         return;
                   1412:                     }
                   1413: 
                   1414:                     op_stck[spx] = f;       /* '$' */
                   1415: 
                   1416:                     /*       a+=stlen(a)+1; */ 
                   1417:                     
                   1418:                     while (*a++ != EOL);
                   1419: 
                   1420:                     codptr++;
                   1421:                     
                   1422:                     goto nextchr;
                   1423: 
                   1424: 
                   1425:                 case ARRAY:         /* array subscript */
                   1426: 
                   1427:                     *(a - 1) = DELIM;
                   1428:                     arg--;
                   1429:                     spx--;
                   1430: 
                   1431:                     while (*a++ != EOL) ;
                   1432: 
                   1433:                     codptr++;
                   1434: 
                   1435:                     goto nextchr;
                   1436: 
                   1437: 
                   1438:                 default:
                   1439: 
                   1440:                     if ((extyp == NAME) || (spx > 1)) {
                   1441:                         merr_raise (INVEXPR);
                   1442:                         return;
                   1443:                     }
                   1444:                 
                   1445:                     return;
                   1446: 
                   1447:             }
                   1448: 
                   1449:         case '^':
                   1450: 
                   1451:             if (extyp == LABEL || extyp == OFFSET) break;
                   1452:             
                   1453: uparrow:
                   1454:         
                   1455:             if (spx >= 5) {         /* take care of $TEXT with three args */
                   1456:                 
                   1457:                 if (op_stck[spx - 4] == 't' && op_stck[spx - 3] == '$' && op_stck[spx - 1] == '$') {
                   1458: 
                   1459:                     if (++spx > PARDEPTH) {
                   1460:                         merr_raise (STKOV);
                   1461:                         return;
                   1462:                     }
                   1463: 
                   1464:                     op_stck[spx] = '$';
                   1465:                     
                   1466:                     while (*a++ != EOL);
                   1467:                     
                   1468:                     if (*(codptr+1)=='@') goto next05;
                   1469: 
                   1470:                 }
                   1471: 
                   1472:             }
                   1473: 
                   1474:             goto scan_name;
                   1475:     
                   1476: 
                   1477:         case '.':
                   1478: 
                   1479:             if ((ch = *++codptr) < '0' || ch > '9') {
                   1480:                 merr_raise (INVEXPR);
                   1481:                 return;
                   1482:             }
                   1483: 
                   1484:             if ((argstck[++arg] = a) >= s) {
                   1485:                 
                   1486:                 char   *bak;
                   1487:                 bak = partition;
                   1488:                 
                   1489:                 if (getpmore () == 0) {
                   1490:                     merr_raise (STKOV);
                   1491:                     return;
                   1492:                 }
                   1493: 
                   1494:                 a = a - bak + partition;
                   1495:                 b = b - bak + partition;
                   1496: 
                   1497:             }
                   1498:             
                   1499:             i = 1;              /* point flag */
                   1500:             j = 0;              /* exp flag */
                   1501:             f = '.';            /* first character */
                   1502:             b = a;
                   1503:             *b++ = f;
                   1504:             
                   1505:             goto p_entry;
                   1506: 
                   1507: 
                   1508:         case ')':
                   1509: 
                   1510:             if (spx <= 1) {
                   1511: 
                   1512:                 if (setpiece) return;
                   1513: 
                   1514:                 if (spx == 0) {
                   1515:                     merr_raise (BRAER);
                   1516:                     return;
                   1517:                 }
                   1518: 
                   1519:             }
                   1520: 
                   1521:             if (op_stck[spx] != OPERAND) {
                   1522:                 merr_raise (INVEXPR);
                   1523:                 return;
                   1524:             }
                   1525: 
                   1526:             if ((f = op_stck[spx - 1]) == ARRAY) {  /* array return */
                   1527:                 
                   1528:                 *--a = DELIM;
                   1529:                 stcpy (varnam, a = argstck[--arg]);
                   1530:             
                   1531:                 if ((spx -= 2) <= 0 && extyp != STRING && extyp != ARGIND) return;
                   1532:                 
                   1533:                 goto var1;
                   1534:             
                   1535:             }
                   1536:             
                   1537:             /* precedence close parenthesis */
                   1538:             if (f == '(') {
                   1539:                 spx -= 2;
                   1540:                 goto nxt_operator;
                   1541:             }
                   1542: 
                   1543:             if (spx <= 2) {
                   1544:                 merr_raise (BRAER);
                   1545:                 return;
                   1546:             }               /* unmatched ')' */
                   1547: 
                   1548: 
                   1549:             /**
                   1550:             * *********** function evaluation ******************************************
                   1551:             * 
                   1552:             * Note: Input for function() is found in 'partition':
                   1553:             * There are 'f' arguments to be found at 'a'
                   1554:             * The arguments are separated by an EOL character.
                   1555:             * There is a list of the addresses of the arguments
                   1556:             * in 'a==argstck[arg], argstck[arg+1], argstck[arg+f-1]'
                   1557:             * Result is returned at a==argstck[arg]
                   1558:             * 
                   1559:             */
                   1560:             f = 1;              /* f == number of arguments */
                   1561:             if (op_stck[spx -= 2] == OPERAND) {
                   1562: 
                   1563:                 do {
                   1564:                     f++;
                   1565:                     arg--;
                   1566:                 } while (op_stck[spx -= 2] == OPERAND);
                   1567:                 
                   1568:                 a = argstck[arg];
                   1569: 
                   1570:             }
                   1571: 
                   1572:             i = op_stck[spx--];
                   1573:         
                   1574:             switch (i) {            /* function select */
                   1575:                 
                   1576: 
                   1577:                 case 'e':           /* $EXTRACT */
                   1578: 
                   1579:                     switch (f) {
                   1580: 
                   1581: 
                   1582:                         case 1:
                   1583:                         
                   1584:                             a[1] = EOL;
                   1585:                             goto nxt_operator;
                   1586:                         
                   1587: 
                   1588:                         case 2:
                   1589:                         
                   1590:                             b = argstck[arg + 1];
                   1591:                             i = intexpr (b) - 1;    /* numeric value of 2nd argument */
                   1592: 
                   1593:                             /*set_io (UNIX);
                   1594:                             printf ("i = %d a = '%s'\n", i, a[i]);
                   1595:                             set_io (MUMPS);*/
                   1596:                             
                   1597:                             if (merr () == MXNUM) {
                   1598:                                 merr_raise (OK);
                   1599:                                 if (i >= 0) i = 256;
                   1600:                             }
                   1601: 
                   1602:                             f = b - a - 1;      /* length of first argument */
                   1603:                             
                   1604:                             if (i > f || i < 0) {
                   1605:                                 if (i > f) {
                   1606:                                     a[0] = EOL;
                   1607:                                     goto nxt_operator;
                   1608:                                 }
                   1609:                                 if (i < 0) {
                   1610:                                     if (en_revstrf && !standard) {
                   1611:                                         a[0] = a[f - (abs(i) - 1)];
                   1612:                                         a[1] = EOL;
                   1613:                                     }
                   1614:                                     else {
                   1615:                                         a[0] = EOL;
                   1616:                                     }
                   1617:                                 }
                   1618:                             }
                   1619:                             else {
                   1620:                                 /* out of range */
                   1621:                                 a[0] = a[i];
                   1622:                                 a[1] = EOL;
                   1623:                             }           /* get character */
                   1624:                             
                   1625:                             goto nxt_operator;
                   1626: 
                   1627: 
                   1628:                         case 3:
                   1629: 
                   1630:                         {
                   1631:                             char tstr[STRLEN];
                   1632:                             long int e_length;
                   1633:                             long int e_start;
                   1634:                             long int e_end;
                   1635: 
                   1636:                             stcpy (tstr, a);
                   1637: 
                   1638:                             e_start = intexpr (argstck[arg + 1]) - 1;
                   1639:                             e_end = intexpr (argstck[arg + 2]);
                   1640:                             e_length = stlen(tstr);
                   1641: 
                   1642:                             if (e_start < 0) {
                   1643: 
                   1644:                                 if (en_revstrf && !standard) {
                   1645:                                     e_start = e_length - abs(e_start) + 1;
                   1646:                                 }
                   1647:                                 else {
                   1648:                                     a[0] = EOL;
                   1649:                                     goto nxt_operator;
                   1650:                                 }
                   1651: 
                   1652:                             }
                   1653:                             
                   1654:                             if (e_end < 0) {
                   1655: 
                   1656:                                 if (en_revstrf && !standard) {
                   1657:                                     e_end = e_length - abs(e_end) + 1;
                   1658:                                 }
                   1659:                                 else {
                   1660:                                     a[0] = EOL;
                   1661:                                     goto nxt_operator;
                   1662:                                 }
                   1663: 
                   1664:                             }
                   1665: 
                   1666:                             tstr[e_end] = EOL;
                   1667:                             stcpy (a, &(tstr[e_start]));
                   1668: 
                   1669:                             goto nxt_operator;
                   1670:                             
                   1671:                         }
                   1672:                             
                   1673:                         default:
                   1674:                             merr_raise (FUNARG); 
                   1675:                                 
                   1676:                             {
                   1677:                                 return;
                   1678:                             }
                   1679: 
                   1680:                     }
                   1681: 
                   1682:                 case 'a':           /* $ASCII */
                   1683: 
                   1684:                     if (f == 1) {
                   1685:                         intstr (a, (*a != EOL ? UNSIGN ((int) *a) : -1));
                   1686:                         goto nxt_operator;
                   1687:                     }
                   1688: 
                   1689:                     if (f > 2) {
                   1690:                         merr_raise (FUNARG);
                   1691:                         return;
                   1692:                     }
                   1693: 
                   1694:                     b = argstck[arg + 1];
                   1695:                     i = intexpr (b);
                   1696: 
                   1697:                     /* ascii number of selected character or -1 if out of range */
                   1698:                     intstr (a, (i >= (b - a)) || i <= 0 ? -1 : UNSIGN ((int) a[i - 1]));
                   1699:                     
                   1700:                     goto nxt_operator;
                   1701: 
                   1702: 
                   1703:                 case 'c':           /* $CHARACTER */
                   1704: 
1.11      snw      1705:                     {                        
1.1       snw      1706:                         short l, l1, m, n;
                   1707: 
                   1708:                         l1 = f;
                   1709:                         i = 0;
                   1710:                         f = 0;
                   1711:                         j = 0;
                   1712:                         m = 0;
                   1713:                         n = 1;
                   1714:                         l = 0;
                   1715: 
1.11      snw      1716:                         
1.1       snw      1717:                         for (;;) {
                   1718:                             
                   1719:                             if ((ch = a[i++]) == EOL) {
                   1720: 
                   1721:                                 if (m == 0) {
                   1722: 
                   1723:                                     if (j > DEL) {
                   1724:                                     
                   1725:                                         if (standard) {
                   1726:                                             merr_raise (NOSTAND);
                   1727:                                             return;
                   1728:                                         }
                   1729:                                     
                   1730:                                         if (eightbit) {
                   1731:                                             j &= 0377;
                   1732:                                             if ((((char) j) == EOL) || (((char) j) == DELIM)) j = NUL;
                   1733:                                         } 
                   1734:                                         else {
                   1735:                                             j &= 0177;
                   1736:                                         }
                   1737: 
                   1738:                                     }
                   1739: 
                   1740:                                     if (f >= STRLEN) {
                   1741:                                         a[f] = EOL;
                   1742:                                         merr_raise (M75);
                   1743:                                     
                   1744:                                         return;
                   1745:                                     }
                   1746: 
                   1747:                                     a[f++] = j;
                   1748: 
                   1749:                                 }
                   1750: 
                   1751:                                 if (++l >= l1) break;
                   1752: 
                   1753:                                 j = 0;
                   1754:                                 m = 0;
                   1755:                                 n = 1;
                   1756:                                 
                   1757:                                 continue;
                   1758: 
                   1759:                             }
                   1760: 
                   1761:                             if (n == 0) continue;
                   1762:                             
                   1763:                             if (ch >= '0' && ch <= '9') {
                   1764:                                 j *= 10;
                   1765:                                 j += ch - '0';
                   1766:                             
                   1767:                                 continue;
                   1768:                             }
                   1769: 
                   1770:                             if (ch == '-') {
                   1771:                                 m |= 01;
                   1772:                                 continue;
                   1773:                             }
                   1774: 
                   1775:                             if (ch != '+') n = 0;
                   1776: 
                   1777:                         }
                   1778: 
                   1779:                         a[f] = EOL;
                   1780: 
                   1781:                     }
                   1782:                     
                   1783:                     goto nxt_operator;
                   1784: 
                   1785: 
                   1786:                 case 'p':           /* $PIECE */
                   1787: 
                   1788:                     {
                   1789:                         long l, l1, m, n;
                   1790: 
                   1791:                         b = argstck[arg + 1];
                   1792:                         l1 = b - a - 1;     /* length of 1st argument */
                   1793: 
                   1794:                         switch (f) {
                   1795: 
                   1796: 
                   1797:                             case 2:
                   1798: 
                   1799:                                 f = 1;
                   1800:                                 l = 1;
                   1801: 
                   1802:                                 break;
                   1803:                             
                   1804: 
                   1805:                             case 3:
                   1806: 
                   1807:                                 f = intexpr (argstck[arg + 2]);
                   1808:                                 
                   1809:                                 if (merr () == MXNUM) {
                   1810:                                     merr_raise (OK);
                   1811:                                     if (j >= 0) f = 256;
                   1812:                                 }
                   1813: 
                   1814:                                 if (f <= 0) {
                   1815:                                     a[0] = EOL;
                   1816:                                     goto nxt_operator;
                   1817:                                 }
                   1818: 
                   1819:                                 l = f;
                   1820:                                 
                   1821:                                 break;
                   1822:                             
                   1823: 
                   1824:                             case 4:
                   1825: 
                   1826:                                 l = intexpr (argstck[arg + 3]);
                   1827:                                 
                   1828:                                 if (merr () == MXNUM) {
                   1829:                                     merr_raise (OK);
                   1830:                                     if (l >= 0) l = 256;
                   1831:                                 }
                   1832: 
                   1833:                                 if ((f = intexpr (argstck[arg + 2])) <= 0) f = 1;
                   1834: 
                   1835:                                 if (merr () == MXNUM) {
                   1836:                                     merr_raise (OK);
                   1837:                                     if (f >= 0) f = 256;
                   1838:                                 }
                   1839: 
                   1840:                                 if (f > l) {
                   1841:                                     a[0] = EOL;
                   1842:                                     goto nxt_operator;
                   1843:                                 }
                   1844: 
                   1845:                                 break;
                   1846:                             
                   1847: 
                   1848:                             default:
                   1849: 
                   1850:                                 merr_raise (FUNARG);
                   1851:                                 return;
                   1852:                         }
                   1853: 
                   1854:                         i = 0;
                   1855:                         m = 0;
                   1856:                         ch = 0;
                   1857:                         
                   1858:                         while (b[ch] != EOL) ch++;       /* $l of 2nd arg */
                   1859: 
                   1860:                         if (ch == 1) {
                   1861: 
                   1862:                             ch = b[0];
                   1863:                             j = 1;
                   1864:                             
                   1865:                             if (f > 1) {
                   1866: 
                   1867:                                 while (i < l1) {    /* scan 1st string ... */
                   1868:                                 
                   1869:                                     if (a[i++] != ch) continue;   /* ... for occurence of 2nd */
                   1870:                                 
                   1871:                                     if (++j == f) {
                   1872:                                         m = i;
                   1873:                                         goto p10;
                   1874:                                     }
                   1875: 
                   1876:                                 }
                   1877: 
                   1878:                                 a[0] = EOL;
                   1879:                                 goto nxt_operator;
                   1880:                             
                   1881:                             }
                   1882:                             
                   1883: p10:
                   1884:                             for (; i < l1; i++) {
                   1885: 
                   1886:                                 if (a[i] != ch) continue;
                   1887:                                 
                   1888:                                 if (j == l) {
                   1889:                                     a[i] = EOL;
                   1890:                                     break;
                   1891:                                 }
                   1892: 
                   1893:                                 j++;
                   1894: 
                   1895:                             }
                   1896: 
                   1897:                             if (m > 0) stcpy (a, &a[m]);
                   1898: 
                   1899:                             goto nxt_operator;
                   1900: 
                   1901:                         }
                   1902:                         
                   1903:                         if (ch == 0) {
                   1904:                             a[0] = EOL;
                   1905:                             goto nxt_operator;
                   1906:                         }           /* 2nd arg is empty */
                   1907:                         
                   1908:                         /* else (ch>1) */
                   1909:                         n = 1;
                   1910:                         
                   1911:                         if (f > 1) {
                   1912: 
                   1913:                             while (i < l1) {    /* scan 1st string ... */
                   1914:                                 j = 0;
                   1915:                                 
                   1916: p20:
                   1917: 
                   1918:                                 if (a[i + j] != b[j]) {
                   1919:                                     i++;
                   1920:                                     continue;
                   1921:                                 }       /* ... for occurence of 2nd */
                   1922:                                 
                   1923:                                 if (++j < ch) goto p20;
                   1924: 
                   1925:                                 i += ch;    /* skip delimiter */
                   1926:                                 
                   1927:                                 if (++n == f) {
                   1928:                                     m = i;
                   1929:                                     goto p30;
                   1930:                                 }
                   1931:                             }
                   1932:                             
                   1933:                             a[0] = EOL;
                   1934:                             
                   1935:                             goto nxt_operator;
                   1936:                         
                   1937:                         }
                   1938: p30:                    
                   1939:                         while (i < l1) {
                   1940:                             j = 0;
                   1941:                             
                   1942: p40:
                   1943: 
                   1944:                             if (a[i + j] != b[j]) {
                   1945:                                 i++;
                   1946:                                 continue;
                   1947:                             }
                   1948: 
                   1949:                             if (++j < ch) goto p40;
                   1950:                             
                   1951:                             if (n == l) {
                   1952:                                 a[i] = EOL;
                   1953:                                 break;
                   1954:                             }           /* last $piece: done! */
                   1955:                             
                   1956:                             i += ch;
                   1957:                             n++;
                   1958: 
                   1959:                         }
                   1960: 
                   1961:                         if (m > 0) stcpy (a, &a[m]);
                   1962:                         
                   1963:                         goto nxt_operator;
                   1964:                     
                   1965:                     }
                   1966: 
                   1967:                 case 'l':           /* $LENGTH */
                   1968: 
                   1969:                     if (f == 1) {
                   1970:                         lintstr (a, stlen (a));
                   1971:                         goto nxt_operator;
                   1972:                     }
                   1973: 
                   1974:                     if (f > 2) {
                   1975:                         merr_raise (FUNARG);
                   1976:                         return;
                   1977:                     }
                   1978: 
                   1979:                     i = 0;
                   1980:                     j = 0;
                   1981:                     ch = 0;
                   1982:                     b = argstck[arg + 1];
                   1983:                     
                   1984:                     if ((f = stlen (b))) {
                   1985: 
                   1986:                         f--;
                   1987:                         
                   1988:                         while ((i = find (&a[ch], b)) > 0) {
                   1989:                         j++;
                   1990:                         ch += i + f;
                   1991:                         }
                   1992:                         
                   1993:                         j++;
                   1994: 
                   1995:                     }
                   1996: 
                   1997:                     intstr (a, j);
                   1998: 
                   1999:                     goto nxt_operator;
                   2000: 
                   2001:                 case 'f':           /* $FIND */
                   2002: 
                   2003:                     {
                   2004:                         short l1;
                   2005: 
                   2006:                         if (f < 2 || f > 3) {
                   2007:                             merr_raise (FUNARG);
                   2008:                             return;
                   2009:                         }
                   2010: 
                   2011:                         if (f == 3) {
                   2012: 
                   2013:                             i = intexpr (argstck[arg + 2]);
                   2014:                             
                   2015:                             if (merr () == MXNUM) {
                   2016:                                 
                   2017:                                 if (i > 0) i = 256;
                   2018:                                 
                   2019:                                 merr_raise (OK);
                   2020:                                 
                   2021:                                 /* important special case:
                   2022:                                 * $FIND("","",number) ::= $S(number<1:1,1:integer(number))
                   2023:                                 * needs special treatment so that it does not yield wrong
                   2024:                                 * results on large values of number.
                   2025:                                 */
                   2026:                                 if ((argstck[arg + 1][0] == EOL) && (i > 0)) {
                   2027: 
                   2028:                                     numlit (argstck[arg + 2]);
                   2029:                                     
                   2030:                                     i = 0;
                   2031:                                     
                   2032:                                     while ((a[i] = argstck[arg + 2][i]) != EOL) {
                   2033: 
                   2034:                                         if (a[i] == '.') {
                   2035:                                             a[i] = EOL;
                   2036:                                             break;
                   2037:                                         }
                   2038: 
                   2039:                                         i++;
                   2040: 
                   2041:                                     }
                   2042: 
                   2043:                                     goto nxt_operator;
                   2044: 
                   2045:                                 }
                   2046:                             }
                   2047: 
                   2048:                             i--;
                   2049:                             
                   2050:                             if (i < 0) i = 0;
                   2051: 
                   2052:                         } 
                   2053:                         else {
                   2054:                             i = 0;
                   2055:                         }
                   2056: 
                   2057:                         b = argstck[arg + 1];
                   2058:                         j = b - a - 1;      /* length of first argument */
                   2059:                         
                   2060:                         if ((l1 = stlen (b)) == 0) {
                   2061:                             i++;
                   2062:                             goto f20;
                   2063:                         }
                   2064: 
                   2065:                         for (f = i; f < j; f++) {
                   2066:                             
                   2067:                             for (ch = 0; ch < l1; ch++) {
                   2068:                                 if (a[f + ch] != b[ch]) goto f10;
                   2069:                             }
                   2070: 
                   2071:                             i = (++f) + l1;
                   2072:                             
                   2073:                             goto f20;
                   2074: 
                   2075: f10:
                   2076:                             ; /* null statement to avoid compiler error
                   2077:                                  due to having a label at the end of a
                   2078:                                  block */
                   2079: 
                   2080:                         }
                   2081: 
                   2082:                         i = 0;
                   2083:                         
                   2084: f20:
                   2085: 
                   2086:                         lintstr (a, i);
                   2087: 
                   2088:                     }
                   2089: 
                   2090:                     goto nxt_operator;
                   2091: 
                   2092: 
                   2093:                 case 'j':           /* $JUSTIFY */
                   2094: 
                   2095:                     if (f < 2 || f > 3) {
                   2096:                         merr_raise (FUNARG);
                   2097:                         return;
                   2098:                     } 
                   2099: 
                   2100:                     {
                   2101:                         long l, l1;
                   2102: 
                   2103:                         l = intexpr (b = argstck[arg + 1]); /* 2nd arg */
                   2104:                         if (merr () == MXNUM) return; /* $J() arg number overflow */
                   2105:                         
                   2106:                         if (l > STRLEN) {
                   2107:                             /* $J() width string too long   */
                   2108:                             merr_raise (M75);
                   2109:                             return;
                   2110:                         }
                   2111: 
                   2112:                         if (f == 2) {
                   2113:                             f = b - a - 1;
                   2114:                         } 
                   2115:                         else {
                   2116: 
                   2117:                             f = intexpr (argstck[arg + 2]); /* 3rd arg */
                   2118: 
                   2119:                             if (merr () == MXNUM) return;  /* $J() arg number overflow */
                   2120: 
                   2121:                             if (f > (STRLEN - 2)) {
                   2122:                                 /* $J() .precision too long */
                   2123:                                 merr_raise (M75);
                   2124:                                 return;
                   2125:                             }
                   2126: 
                   2127:                             numlit (a);
                   2128:                             
                   2129:                             if (f < 0) {
                   2130:                                 merr_raise (ARGER);
                   2131:                                 return;
                   2132:                             }
                   2133: 
                   2134:                             /* s j=$l(a),i=$f(a,".")-1 */
                   2135:                             j = (a[0] == '-');
                   2136:                             
                   2137:                             if (a[j] == '.') {  /* insert leading zero */
                   2138:                                 
                   2139:                                 i = j;
                   2140:                                 
                   2141:                                 while (a[i++] != EOL);
                   2142:                                 
                   2143:                                 while (i > j) {
                   2144:                                     a[i] = a[i - 1];
                   2145:                                     i--;
                   2146:                                 }
                   2147: 
                   2148:                                 a[j] = '0';
                   2149: 
                   2150:                             }
                   2151: 
                   2152:                             i = (-1);
                   2153:                             j = 0;
                   2154:                             
                   2155:                             while (a[j] != EOL) {
                   2156:                                 if (a[j] == '.') i = j;
                   2157:                                 j++;
                   2158:                             }
                   2159: 
                   2160:                             if (i < 0) {
                   2161:                                 a[i = j] = '.';
                   2162:                                 a[j + 1] = EOL;
                   2163:                             } 
                   2164:                             else {
                   2165:                                 j--;
                   2166:                             }
                   2167:                             
                   2168:                             if (j - i > f) {    /* rounding required */
                   2169:                                 
                   2170:                                 if ((l1 = f + i + 1) > STRLEN) {
                   2171:                                     merr_raise (M75);
                   2172:                                     return;
                   2173:                                 }
                   2174:                                 
                   2175:                                 if (a[l1] > '4') {
                   2176: 
                   2177:                                     do {
                   2178:                                         
                   2179:                                         if (a[--l1] == '.') l1--;
                   2180: 
                   2181:                                         if (l1 < (a[0] == '-')) {
                   2182: 
                   2183:                                             for (l1 = f + i + 1; l1 > 0; l1--) a[l1] = a[l1 - 1];
                   2184:                                             
                   2185:                                             a[a[0] == '-'] = '1';
                   2186:                                             i++;
                   2187:                                             
                   2188:                                             break;
                   2189:                                         
                   2190:                                         }
                   2191:                                         
                   2192:                                         a[l1]++;
                   2193:                                         
                   2194:                                         if (a[l1] == ':') a[l1] = '0';
                   2195: 
                   2196:                                     } while (a[l1] == '0');
                   2197: 
                   2198:                                 }
                   2199: 
                   2200:                                 a[f + i + 1] = EOL;
                   2201:                                 
                   2202:                                 if (a[0] == '-' && a[1] == '0') {
                   2203:                                     
                   2204:                                     l1 = 2;
                   2205:                                     
                   2206:                                     while (a[l1] != EOL) {
                   2207:                                         
                   2208:                                         if (a[l1] >= '1' && a[l1] <= '9') {
                   2209:                                             l1 = 0;
                   2210:                                             break;
                   2211:                                         }
                   2212:                                         
                   2213:                                         l1++;
                   2214: 
                   2215:                                     }
                   2216: 
                   2217:                                     if (l1) {
                   2218: 
                   2219:                                         i--;
                   2220:                                         l1 = 0;
                   2221:                                         
                   2222:                                         while ((a[l1] = a[l1 + 1]) != EOL) l1++;
                   2223: 
                   2224:                                     }
                   2225:                                 }
                   2226: 
                   2227:                             }
                   2228:                             else { /* rounding not required */
                   2229: 
                   2230:                                 if (f + i + 1 > STRLEN) {
                   2231:                                     merr_raise (M75);
                   2232:                                     return;
                   2233:                                 }
                   2234: 
                   2235:                                 while (j < f + i) a[++j] = '0';
                   2236: 
                   2237:                                 a[++j] = EOL;
                   2238:                             
                   2239:                             }
                   2240:                             
                   2241:                             if (f == 0) a[i] = EOL;
                   2242: 
                   2243:                         }           /* end of 3 arg-form */
                   2244:                         
                   2245:                         if (f < l) {
                   2246: 
                   2247:                             i = stlen (a) + 1;
                   2248:                             
                   2249:                             if (++l <= i) goto nxt_operator;
                   2250: 
                   2251:                             while (i >= 0) a[l--] = a[i--];
                   2252:                             while (l >= 0) a[l--] = SP;
                   2253: 
                   2254:                         }
                   2255: 
                   2256:                     }
                   2257:                     
                   2258:                     goto nxt_operator;
                   2259:                 
                   2260: 
                   2261:                 /* case 'd': *//* $DATA */
                   2262:                 /* case 'g': *//* $GET */
                   2263:                 /* case 'i': *//* $INCREMENT */
                   2264:                 /* case 'n': *//* $NEXT */
                   2265:                 /* case ZNEXT: *//* $ZNEXT */
                   2266:                 /* case ZPREVIOUS: *//* $ZPREVIOUS */
                   2267:                 case 'o':           /* $ORDER */
                   2268: 
                   2269:                     if (f > 2) {
                   2270:                         merr_raise (FUNARG);
                   2271:                         return;
                   2272:                     }
                   2273:                     
                   2274:                     stcpy (varnam, argstck[arg]);
                   2275:                     ordercnt = intexpr (argstck[arg + 1]);
                   2276:                     ordercounter = 0;
                   2277:                     
                   2278:                     if (varnam[0] != '^') {
                   2279:                         symtab (fra_order, varnam, a);
                   2280:                     }
                   2281:                     else if (varnam[1] != '$') {
                   2282:                         global  (fra_order, varnam, a);
                   2283:                     }
                   2284:                     else {
                   2285:                         ssvn (fra_order, varnam, a);
                   2286:                     }
                   2287:                     
                   2288:                     goto nxt_operator;
                   2289: 
                   2290: 
                   2291:                 case 'q':           /* $QUERY */
                   2292:                     
                   2293:                     if (f > 2) {
                   2294:                         merr_raise (FUNARG);
                   2295:                         return;
                   2296:                     }
                   2297: 
                   2298:                     stcpy (varnam, argstck[arg]);
                   2299:                     ordercnt = intexpr (argstck[arg + 1]);
                   2300: 
                   2301:                     if (varnam[0] == '^' && varnam[1] == '$') {
                   2302:                         ssvn (fra_query, varnam, a);
                   2303:                     }
                   2304:                     else if (ordercnt == 1) {
                   2305:                         if (varnam[0] != '^') {
                   2306:                             symtab (fra_query, varnam, a);
                   2307:                         }
                   2308:                         else {
                   2309:                             global (fra_query, varnam, a);
                   2310:                         }
                   2311:                     }
                   2312:                     else {
                   2313:                         char qryarg_ext[256];
                   2314: 
                   2315:                         freem_ref_t *revq_ref = (freem_ref_t *) malloc (sizeof (freem_ref_t));
                   2316: 
                   2317:                         /* convert the $QUERY argument from internal to external format */
                   2318:                         mref_init (revq_ref, MREF_RT_GLOBAL, "scratch");
                   2319:                         internal_to_mref (revq_ref, varnam);
                   2320:                         mref_to_external (revq_ref, qryarg_ext);
                   2321: 
                   2322:                         stcnv_c2m (qryarg_ext);
                   2323: 
                   2324:                         /* put the $QUERY argument into the local variable %INT.REVQ */
1.7       snw      2325:                         symtab (set_sym, "%INTREVQ\201\201", qryarg_ext);
1.1       snw      2326: 
                   2327:                         /* set up for calling into polyfill wrapper */
                   2328:                         code[0] = '\201';
1.19    ! snw      2329:                         stcpy (code, "$%ZREVQRY^%ZREVQRY\201");
1.1       snw      2330: 
                   2331:                         codptr = code;
                   2332: 
                   2333:                         f = '$';
                   2334: 
                   2335:                         zexflag = TRUE;
                   2336: 
                   2337:                         /* run the polyfill wrapper */
                   2338:                         goto extra_fun;
                   2339:                     }
                   2340: 
                   2341:                     goto nxt_operator;
                   2342: 
                   2343: 
                   2344:                 case 'N':           /* $NAME */
                   2345: 
                   2346:                     if (f > 2) {
                   2347:                         merr_raise (FUNARG);
                   2348:                         return;
                   2349:                     }
                   2350: 
                   2351:                     f = intexpr (argstck[arg + 1]);
                   2352:                     
                   2353:                     if (f < 0) {
                   2354:                         merr_raise (ARGER);
                   2355:                         return;
                   2356:                     }
                   2357: 
                   2358:                     i = 0;
                   2359:                     
                   2360:                     while (a[++i] != EOL) {
                   2361:                         if (a[i] == DELIM && --f < 0) {
                   2362:                             break;
                   2363:                         }
                   2364:                     }
                   2365:                     
                   2366:                     a[i] = EOL;
                   2367: 
                   2368:                     stcpy (varnam, a);
                   2369:                     zname (a, varnam);
                   2370: 
                   2371:                     goto nxt_operator;
                   2372: 
                   2373: 
                   2374:                 case QLENGTH:           /* $QLENGTH */
                   2375: 
                   2376:                     if (f != 1) {
                   2377:                         merr_raise (FUNARG);
                   2378:                         return;
                   2379:                     }
                   2380: 
                   2381:                     f = 0;
                   2382:                     i = 0;
                   2383:                     
                   2384:                     {
                   2385:                         int ch, quote;
                   2386: 
                   2387:                         quote = 0;
                   2388:                         
                   2389:                         while ((ch = a[i++]) != EOL) {
                   2390: 
                   2391:                             if (ch == '"') quote = !quote;
                   2392:                             if (quote) continue;
                   2393:                             if (ch == '(' && f == 0) f = 1;
                   2394:                             if (ch == ',') f++;
                   2395:                         
                   2396:                         }
                   2397:                     
                   2398:                     }
                   2399:                     
                   2400:                     intstr (a, f);
                   2401:                     
                   2402:                     goto nxt_operator;
                   2403: 
                   2404: 
                   2405:                 case QSUBSCRIPT: /* $QSUBSCRIPT */
                   2406: 
                   2407:                     if (f != 2) {
                   2408:                         merr_raise (FUNARG);
                   2409:                         return;
                   2410:                     }
                   2411: 
                   2412:                     if ((f = intexpr (argstck[arg+1])) < -1) {
                   2413:                         merr_raise (ARGER);
                   2414:                         return;
                   2415:                     }
                   2416: 
                   2417:                     { 
                   2418:                         int ch, env, quote, count, startsub;
                   2419:                         
                   2420:                         if (f == -1) { /* get environment */
                   2421:                             
                   2422:                             quote = 0; 
                   2423:                             env = FALSE; 
                   2424:                             count = 0; 
                   2425:                             startsub = 0; 
                   2426:                             i = 0;
                   2427: 
                   2428:                             while ((ch = a[i++]) != EOL) {
                   2429: 
                   2430:                                 if (ch == '"') quote= !quote;
                   2431:                                 if (quote) continue;
                   2432: 
                   2433:                                 if (ch == '|') {
                   2434:                                     
                   2435:                                     if (env) {
                   2436:                                         a[i-1] = EOL;
                   2437:                                         stcpy (a, &a[startsub]);
                   2438:                                     
                   2439:                                         break;
                   2440:                                     
                   2441:                                     }
                   2442:                                     else {
                   2443:                                         startsub = i;
                   2444:                                         env = TRUE;
                   2445:                                     }
                   2446: 
                   2447:                                 }
                   2448: 
                   2449:                             }
                   2450: 
                   2451:                             if (!env) *a= EOL;
                   2452: 
                   2453:                         }
                   2454:                         else {
                   2455: 
                   2456:                             quote = 0; 
                   2457:                             env = FALSE; 
                   2458:                             count = 0; 
                   2459:                             startsub = 0; 
                   2460:                             i = 0;
                   2461: 
                   2462:                             while ((ch=a[i++])!=EOL) {
                   2463: 
                   2464:                                 if (ch == '"') quote = !quote;
                   2465:                                 if (quote) continue;
                   2466: 
                   2467:                                 if (ch == '|' && count == 0) {
                   2468:                                 
                   2469:                                     if (env) {
                   2470: 
                   2471:                                         if (*a == '^') a[--i] = '^';
                   2472:                                         
                   2473:                                         startsub = i;
                   2474: 
                   2475:                                     }
                   2476:                                     else {  
                   2477:                                         env = TRUE;
                   2478:                                     }
                   2479: 
                   2480:                                 }
                   2481:                                 
                   2482:                                 if (ch == '(' || ch == ',' || ch == ')') {
                   2483:                                     
                   2484:                                     if (count == f) { 
                   2485:                                         a[i-1] = EOL; 
                   2486:                                         break; 
                   2487:                                     }
                   2488:                                     
                   2489:                                     count++; 
                   2490:                                     startsub = i;
                   2491: 
                   2492:                                 }
                   2493: 
                   2494:                             }
                   2495:                             
                   2496:                             if (startsub) stcpy (a, &a[startsub]);
                   2497:                             
                   2498:                             if (count < f) *a = EOL;
                   2499: 
                   2500:                         }
                   2501:                         if (a[0] == '"') { /* un-quote */
                   2502: 
                   2503:                             quote = 1; 
                   2504:                             i = 1; 
                   2505:                             f = 0;
                   2506:                             
                   2507:                             while ((ch = a[i++]) != EOL) {
                   2508: 
                   2509:                                 if (ch == '"') quote = !quote;
                   2510:                                 
                   2511:                                 if (quote) a[f++] = ch;
                   2512: 
                   2513:                             }
                   2514: 
                   2515:                             a[f] = EOL;
                   2516: 
                   2517:                         }
                   2518: 
                   2519:                     }
                   2520: 
                   2521:                 /* goto nxt_operator; */
                   2522: 
                   2523: 
                   2524:                 case 's':           /* $SELECT */
                   2525:                 
                   2526:                     goto nxt_operator;
                   2527: 
                   2528:                     
                   2529:                 case SVNstack:          /* $STACK() */
                   2530: 
                   2531:                     if (f > 2) {
                   2532:                         merr_raise (FUNARG);
                   2533:                         return;
                   2534:                     }
                   2535: 
                   2536:                     if (f == 1) {
                   2537: 
                   2538:                         char iex_buf[256];
                   2539:                         int iexp;
                   2540:                         
                   2541:                         stcpy (iex_buf, argstck[arg]);
                   2542:                         iexp = atoi (iex_buf);
                   2543: 
                   2544:                         /*set_io (UNIX);
                   2545:                         printf ("iexp = %d\n", iexp);
                   2546:                         set_io (MUMPS);
                   2547:                         */
                   2548:                         
                   2549:                         if (iexp == -1) {                            
                   2550:                             intstr (a, merr_topstk);
                   2551:                         }
                   2552:                         else if (iexp == 0) {
                   2553:                             stcpy (a, stack0);
                   2554:                         }
                   2555:                         else if (iexp > 0 && iexp <= merr_topstk) {
                   2556: 
                   2557:                             if (merr_topstk > nstx) {
                   2558:                                 stcpy (a, merr_stack[merr_topstk].ECODE);
                   2559:                             }
                   2560:                             else {
                   2561:                                 if (nestc[iexp] == '$') {
                   2562:                                     stcpy (a, "$$\201");
                   2563:                                 }
                   2564:                                 else {
                   2565:                                     if ((mtok_token_to_command (a, nestc[iexp])) != 1) {
                   2566:                                         stcpy (a, "???");
                   2567:                                     }
                   2568:                                 }
                   2569:                             }
                   2570:                             
                   2571:                         }
                   2572:                         else {
                   2573:                             merr_raise (FUNARG);
                   2574:                             return;
                   2575:                         }
                   2576: 
                   2577:                     }                
                   2578: 
                   2579:                     if (f == 2) {
                   2580: 
                   2581:                         int stkidx;
                   2582:                         char sub[255];
                   2583:                         char indst[255];
                   2584:                         stcpy (indst, argstck[arg]);
                   2585:                         stcnv_m2c (indst);
                   2586: 
                   2587:                         stkidx = atoi (indst);
                   2588: 
                   2589:                         if (stkidx > NESTLEVLS || stkidx < 0) {
                   2590:                             merr_raise (FUNARG);
                   2591:                             return;
                   2592:                         }
                   2593: 
                   2594:                         stcpy (sub, argstck[2]);
                   2595:                         stcnv_m2c (sub);
                   2596: 
                   2597:                         if (strcmp (sub, "MCODE") == 0) {
                   2598:                             strcpy (a, merr_stack[stkidx].MCODE);
                   2599:                         }
                   2600:                         else if (strcmp (sub, "ECODE") == 0) {
                   2601:                             strcpy (a, merr_stack[stkidx].ECODE);
                   2602:                         }
                   2603:                         else if (strcmp (sub, "PLACE") == 0) {
                   2604:                             strcpy (a, merr_stack[stkidx].PLACE);
                   2605:                         }
                   2606:                         else {
                   2607:                             merr_raise (SYNTERR);
                   2608:                             return;
                   2609:                         }
                   2610: 
                   2611:                         stcnv_c2m (a);
                   2612: 
                   2613:                     }
                   2614: 
                   2615:         
                   2616:                     goto nxt_operator;
                   2617: 
                   2618: 
                   2619:                 case FNUMBER:           /* $FNUMBER */
                   2620: 
                   2621:                     if (f < 2 || f > 3) {
                   2622:                         merr_raise (FUNARG);
                   2623:                         return;
                   2624:                     } 
                   2625: 
                   2626:                     {
                   2627: 
                   2628:                         short l1;
                   2629:                         short Pflag;
                   2630:                         short Tflag;
                   2631:                         short commaflag;
                   2632:                         short plusflag;
                   2633:                         short minusflag;
                   2634:                         short EuroFlag;
                   2635:                         short IsZero;
                   2636:                         
                   2637:                         Pflag = FALSE,
                   2638:                         Tflag = FALSE,
                   2639:                         commaflag = FALSE,
                   2640:                         plusflag = FALSE,
                   2641:                         minusflag = FALSE,
                   2642:                         EuroFlag = FALSE,
                   2643:                         IsZero = FALSE;
                   2644: 
                   2645:                         b = argstck[arg + 1];
                   2646: 
                   2647:                         while ((i = *b++) != EOL) { /* evaluate options */
                   2648: 
                   2649:                             switch (i) {
                   2650:                         
                   2651: 
                   2652:                                 case 'P':
                   2653: 
                   2654:                                     Pflag = TRUE;
                   2655:                                     continue;
                   2656:                         
                   2657: 
                   2658:                                 case 'p':
                   2659: 
                   2660:                                     if (lowerflag) Pflag = TRUE;
                   2661:                                     continue;
                   2662:                         
                   2663: 
                   2664:                                 case 'T':
                   2665: 
                   2666:                                     Tflag = TRUE;
                   2667:                                     continue;
                   2668:                         
                   2669: 
                   2670:                                 case 't':
                   2671: 
                   2672:                                     if (lowerflag) Tflag = TRUE;
                   2673:                                     continue;
                   2674:                         
                   2675: 
                   2676:                                 case ',':
                   2677: 
                   2678:                                     commaflag = TRUE;
                   2679:                                     continue;
                   2680:                             
                   2681: 
                   2682:                                 case '.':
                   2683: 
                   2684:                                     EuroFlag = TRUE;
                   2685:                                     continue;
                   2686:                         
                   2687: 
                   2688:                                 case '+':
                   2689: 
                   2690:                                     plusflag = TRUE;
                   2691:                                     continue;
                   2692:                         
                   2693: 
                   2694:                                 case '-':
                   2695: 
                   2696:                                     minusflag = TRUE;
                   2697: 
                   2698: 
                   2699:                             }
                   2700:                         }
                   2701: 
                   2702:                         if (Pflag && (Tflag || plusflag || minusflag)) {
                   2703:                             merr_raise (ARGER);
                   2704:                             return;
                   2705:                         }
                   2706: 
                   2707:                         if (f == 3) j = intexpr (argstck[arg + 2]); /* 3rd arg */
                   2708:                         
                   2709:                         if (merr () == MXNUM) {
                   2710:                         
                   2711:                             if (j >= 0) j = 256;
                   2712:                         
                   2713:                             merr_raise (OK);
                   2714:                         
                   2715:                         }
                   2716: 
                   2717:                         numlit (a);
                   2718:                         IsZero = (a[0] == '0');
                   2719: 
                   2720:                         if (f == 3) {
                   2721: 
                   2722:                             f = j;
                   2723:                             
                   2724:                             if (f < 0) {
                   2725:                                 merr_raise (ARGER);
                   2726:                                 return;
                   2727:                             }
                   2728: 
                   2729:                             if (f > STRLEN) {
                   2730:                                 merr_raise (M75);
                   2731:                                 return;
                   2732:                             }
                   2733: 
                   2734:                             /* s j=$l(a),i=$f(a,".")-1 */
                   2735:                             j = (a[0] == '-');
                   2736:                             
                   2737:                             if (a[j] == '.') {  /* insert leading zero */
                   2738: 
                   2739:                                 i = j;
                   2740:                             
                   2741:                                 while (a[i++] != EOL);
                   2742: 
                   2743:                                 while (i > j) {
                   2744:                                     a[i] = a[i - 1];
                   2745:                                     i--;
                   2746:                                 }
                   2747: 
                   2748:                                 a[j] = '0';
                   2749: 
                   2750:                             }
                   2751: 
                   2752:                             i = (-1);
                   2753:                             j = 0;
                   2754: 
                   2755:                             while (a[j] != EOL) {
                   2756: 
                   2757:                                 if (a[j] == '.') i = j;
                   2758:                                 
                   2759:                                 j++;
                   2760:                             
                   2761:                             }
                   2762: 
                   2763:                             if (i < 0) {
                   2764:                                 a[i = j] = '.';
                   2765:                                 a[j + 1] = EOL;
                   2766:                             } 
                   2767:                             else {
                   2768:                                 j--;
                   2769:                             }
                   2770: 
                   2771:                             if (j - i > f) {    /* rounding required */
                   2772: 
                   2773:                                 l1 = f + i + 1;
                   2774: 
                   2775:                                 if (a[l1] > '4') {
                   2776: 
                   2777:                                     do {
                   2778: 
                   2779:                                         if (a[--l1] == '.') l1--;
                   2780: 
                   2781:                                         if (l1 < 0) {
                   2782: 
                   2783:                                             for (l1 = f + i + 1; l1 > 0; l1--) {
                   2784:                                                 a[l1] = a[l1 - 1];
                   2785:                                             }
                   2786:                                             
                   2787:                                             a[0] = '1';
                   2788:                                             i++;
                   2789:                                             
                   2790:                                             break;
                   2791: 
                   2792:                                         }
                   2793: 
                   2794:                                         a[l1]++;
                   2795: 
                   2796:                                         if (a[l1] == ':') a[l1] = '0';
                   2797: 
                   2798:                                     } while (a[l1] == '0');
                   2799: 
                   2800:                                 }
                   2801: 
                   2802:                                 a[f + i + 1] = EOL;
                   2803:                                 
                   2804:                                 if (a[0] == '-' && a[1] == '0') {
                   2805: 
                   2806:                                     l1 = 2;
                   2807:                                     
                   2808:                                     while (a[l1] != EOL) {
                   2809: 
                   2810:                                         if (a[l1] >= '1' && a[l1] <= '9') {
                   2811:                                             l1 = 0;
                   2812:                                             break;
                   2813:                                         }
                   2814: 
                   2815:                                         l1++;
                   2816: 
                   2817:                                     }
                   2818: 
                   2819:                                     if (l1) {
                   2820: 
                   2821:                                         i--;
                   2822:                                         l1 = 0;
                   2823:                                         
                   2824:                                         while ((a[l1] = a[l1 + 1]) != EOL) l1++;
                   2825: 
                   2826:                                     }
                   2827: 
                   2828:                                 }
                   2829: 
                   2830:                             } 
                   2831:                             else {
                   2832:                             
                   2833:                                 if (f + i > STRLEN) {
                   2834:                                     merr_raise (M75);
                   2835:                                     return;
                   2836:                                 }
                   2837: 
                   2838:                                 while (j < f + i) a[++j] = '0';
                   2839: 
                   2840:                                 a[++j] = EOL;
                   2841:                             }
                   2842:                                 
                   2843:                             if (f == 0) a[i] = EOL;
                   2844: 
                   2845:                         }           /* end of 3 arg-form */
                   2846:                         
                   2847:                         if (commaflag) {
                   2848: 
                   2849:                             i = 0;
                   2850:                             
                   2851:                             while ((f = a[i]) != '.' && f != EOL) i++;
                   2852:                             
                   2853:                             if (a[0] == '-') {
                   2854: 
                   2855:                                 f = (i + 1) % 3;
                   2856:                                 j = 1;
                   2857:                                 i = 1;
                   2858:                                 tmp[0] = '-';
                   2859: 
                   2860:                             } 
                   2861:                             else {
                   2862: 
                   2863:                                 f = (i + 2) % 3;
                   2864:                                 j = 0;
                   2865:                                 i = 0;
                   2866: 
                   2867:                             }
                   2868: 
                   2869:                             while ((tmp[j++] = a[i]) != EOL) {
                   2870: 
                   2871:                                 if (j >= STRLEN) {
                   2872:                                     merr_raise (M75);
                   2873:                                     return;
                   2874:                                 }
                   2875:                                 
                   2876:                                 if (a[i++] == '.') f = -1; /* do not insert comma after point */
                   2877: 
                   2878:                                 if (f-- == 0 && a[i] != EOL && a[i] != '.') {
                   2879:                                     f = 2;
                   2880:                                     tmp[j++] = ',';
                   2881:                                 }
                   2882: 
                   2883:                             }
                   2884: 
                   2885:                             stcpy (a, tmp);
                   2886: 
                   2887:                         }
                   2888: 
                   2889:                         if (EuroFlag && !standard) {    /* exchange point and comma */
                   2890:                             
                   2891:                             i = 0;
                   2892:                             
                   2893:                             while ((f = a[i]) != EOL) {
                   2894: 
                   2895:                                 if (f == '.') a[i] = ',';
                   2896:                                 if (f == ',') a[i] = '.';
                   2897: 
                   2898:                                 i++;
                   2899: 
                   2900:                             }
                   2901: 
                   2902:                         }
                   2903: 
                   2904:                         if (Tflag) {
                   2905: 
                   2906:                             i = stcpy (tmp, a);
                   2907:                             
                   2908:                             if (plusflag && tmp[0] != '-' && !IsZero) {
                   2909:                             
                   2910:                                 tmp[i] = '+';
                   2911:                                 tmp[++i] = EOL;
                   2912:                                 stcpy (a, tmp);
                   2913:                             
                   2914:                             } 
                   2915:                             else if (tmp[0] == '-') {
                   2916:                             
                   2917:                                 tmp[i] = minusflag ? SP : '-';
                   2918:                                 tmp[++i] = EOL;
                   2919:                                 stcpy (a, &tmp[1]);
                   2920:                             
                   2921:                             } 
                   2922:                             else {
                   2923:                             
                   2924:                                 tmp[i] = SP;
                   2925:                                 tmp[++i] = EOL;
                   2926:                                 stcpy (a, tmp);
                   2927:                             
                   2928:                             }
                   2929: 
                   2930:                             goto nxt_operator;
                   2931: 
                   2932:                         }
                   2933: 
                   2934:                         if (Pflag) {
                   2935: 
                   2936:                             i = stcpy (&tmp[1], a);
                   2937:                             
                   2938:                             if (a[0] == '-') {
                   2939:                             
                   2940:                                 a[0] = '(';
                   2941:                                 a[i] = ')';
                   2942:                                 a[++i] = EOL;
                   2943:                             
                   2944:                             } 
                   2945:                             else {
                   2946:                             
                   2947:                                 tmp[0] = SP;
                   2948:                                 tmp[++i] = SP;
                   2949:                                 tmp[++i] = EOL;
                   2950: 
                   2951:                                 stcpy (a, tmp);
                   2952:                             }
                   2953: 
                   2954:                             goto nxt_operator;
                   2955: 
                   2956:                         }
                   2957: 
                   2958:                         if (plusflag && a[0] != '-' && !IsZero) {
                   2959:                             stcpy (tmp, a);
                   2960:                             a[0] = '+';
                   2961:                             stcpy (&a[1], tmp);
                   2962:                         }
                   2963: 
                   2964:                         if (minusflag && a[0] == '-') {
                   2965:                             stcpy (tmp, &a[1]);
                   2966:                             stcpy (a, tmp);
                   2967:                         }
                   2968: 
                   2969:                     }
                   2970: 
                   2971:                     goto nxt_operator;
                   2972: 
                   2973: 
                   2974:                 case REVERSE:           /* $REVERSE */
                   2975: 
                   2976:                     if (f != 1) {
                   2977:                         merr_raise (FUNARG);
                   2978:                         return;
                   2979:                     }
                   2980: 
                   2981:                     i = stlen (a) - 1;
                   2982:                     j = i / 2;
                   2983:                     i = i - j;
                   2984:                     
                   2985:                     while (j >= 0) {
                   2986:                         f = a[j];
                   2987:                         a[j--] = a[i];
                   2988:                         a[i++] = f;
                   2989:                     }
                   2990: 
                   2991:                     goto nxt_operator;
                   2992: 
                   2993: 
                   2994:                 case 't':           /* $TEXT */
                   2995: 
                   2996:                     {
                   2997:                         long l1, rouoldc;
                   2998:                         short reload = FALSE;
1.16      snw      2999: 
                   3000:                         /*
1.17      snw      3001:                         printf ("a = %s f = %d arg = %d\r\n", a, f, arg);
1.16      snw      3002:                         for (i = arg; i < arg + f; i++) {
                   3003:                             printf ("argstck[%d] = '%s'\r\n", i, argstck[i]);
                   3004:                         }
1.17      snw      3005: 
                   3006:                         for (i = 0; i < strlen (a); i++) 
                   3007:                             printf ("%c = %d\r\n", a[i], (unsigned char) a[i]);
1.16      snw      3008:                         */
1.15      snw      3009:                         
1.1       snw      3010:                         if (f > 3) {
                   3011:                             merr_raise (FUNARG);
                   3012:                             return;
                   3013:                         }
                   3014: 
                   3015:                         i = 0;
                   3016:                         
                   3017:                         if (f > 1) {
                   3018:                             stcpy (tmp, argstck[arg + 1]);
                   3019:                             i = intexpr (tmp);
                   3020:                         }
                   3021: 
                   3022:                         if (a[0] == EOL) {
                   3023: 
                   3024:                             if (i < 0) {
                   3025:                                 merr_raise (ARGER);
                   3026:                                 return;
                   3027:                             }
                   3028: 
                   3029:                             /* $T(+0) returns routine name */
                   3030:                             if (i == 0) {
                   3031: 
                   3032:                                 if (f != 3) {
                   3033:                                     stcpy (a, rou_name);
                   3034:                                 } 
                   3035:                                 else {
                   3036:                                     stcpy (a, argstck[arg + 2]);
                   3037:                                 }                                
                   3038: 
                   3039:                                 goto nxt_operator;
                   3040: 
                   3041:                             }
                   3042: 
                   3043:                         }
                   3044: 
                   3045:                         if (f == 3) {
                   3046: 
                   3047:                             reload = TRUE;  /* load routine; */
                   3048:                             f = mcmnd;
                   3049:                             mcmnd = 'd';    /* make load use standard-path */
                   3050:                             
                   3051:                             stcpy (tmp, argstck[arg + 2]);
                   3052:                             
                   3053:                             rouoldc = roucur - rouptr;
                   3054:                             
                   3055:                             zload (tmp);
                   3056:                             
                   3057:                             mcmnd = f;
                   3058:                             
                   3059:                             if (merr () > OK) {
                   3060: 
                   3061:                                 zload (rou_name);
                   3062:                                 
                   3063:                                 if (merr () == NOPGM) {
                   3064:                                     ierr -= NOPGM; /* smw 15 nov 2023 TODO HUH?? */
                   3065:                                     *a = EOL;
                   3066: 
                   3067:                                     goto nxt_operator;
                   3068:                                 }
                   3069: 
                   3070:                                 return;
                   3071: 
                   3072:                             }
                   3073: 
                   3074:                         }
                   3075: 
                   3076:                         j = 0;
                   3077:                         f = 1;
                   3078:                         
                   3079:                         if (a[0] != EOL) {  /* 1st arg == label */
                   3080: 
                   3081:                             for (;;) {
                   3082:                         
                   3083:                                 if (j >= (rouend - rouptr)) {
                   3084:                                     a[0] = EOL;
                   3085:                                     goto t_end;
                   3086:                                 }
                   3087: 
                   3088:                                 l1 = j;
                   3089:                                 f = 0;
                   3090:                                 
                   3091:                                 while (*(rouptr + (++l1)) == a[f++]);
                   3092:                                 
                   3093:                                 if (a[--f] == EOL && (*(rouptr + l1) == TAB || *(rouptr + l1) == SP || *(rouptr + l1) == '(')) break;
                   3094: 
                   3095:                                 j += (UNSIGN (*(rouptr + j)) + 2);  /* skip line */
                   3096: 
                   3097:                             }
                   3098: 
                   3099:                             f = 0;
                   3100: 
                   3101:                         }
                   3102: 
                   3103:                         if (i > 0) {
                   3104: 
                   3105:                             while (f < i) {
                   3106: 
                   3107:                                 if ((j = j + (UNSIGN (*(rouptr + j))) + 2) >= (rouend - rouptr)) {
                   3108:                                     a[0] = EOL;
                   3109:                                     goto t_end;
                   3110:                                 }
                   3111:                                 
                   3112:                                 f++;
                   3113: 
                   3114:                             }
                   3115: 
                   3116:                         }
                   3117: 
                   3118:                         if (i < 0) {
                   3119: 
                   3120:                             j--;
                   3121:                             
                   3122:                             while (f != i) {
                   3123: 
                   3124:                                 while (*(rouptr + (--j)) != EOL && j >= 0);
                   3125:                                 
                   3126:                                 if (--f != i && j < 1) {
                   3127:                                     a[0] = EOL;
                   3128:                                     goto t_end;
                   3129:                                 }
                   3130: 
                   3131:                             }
                   3132: 
                   3133:                             j++;
                   3134: 
                   3135:                         }
                   3136: 
                   3137:                         f = (-1);
                   3138:                         j++;
                   3139: 
                   3140:                         while ((a[++f] = (*(rouptr + (j++)))) != EOL) {
                   3141:                             if (a[f] == TAB || a[f] == SP)
                   3142:                             break;
                   3143:                         }
                   3144: 
                   3145:                         if (j >= (rouend - rouptr - 1)) {
                   3146:                             a[0] = EOL;
                   3147:                         } 
                   3148:                         else {
                   3149: 
                   3150:                             a[f] = SP;
                   3151:                             
                   3152:                             while ((*(rouptr + j)) == TAB || (*(rouptr + j)) == SP) {
                   3153:                                 j++;
                   3154:                                 a[++f] = SP;
                   3155:                             }
                   3156: 
                   3157:                             stcpy (&a[++f], rouptr + j);
                   3158: 
                   3159:                         }
                   3160: 
                   3161: t_end:
                   3162:                         if (reload) {
                   3163:                             zload (rou_name);
                   3164:                             roucur = rouptr + rouoldc;
                   3165:                         }           /* reload routine; */
                   3166: 
                   3167:                     }
                   3168:                     
                   3169:                     goto nxt_operator;
                   3170: 
                   3171: 
                   3172:                 case TRANSLATE:     /* $TRANSLATE */
                   3173: 
                   3174:                     if (f > 3 || f < 2) {
                   3175:                         merr_raise (FUNARG);
                   3176:                         return;
                   3177:                     } 
                   3178: 
                   3179:                     {
                   3180:                         short   l1, m;
                   3181:                         char   *c;
                   3182: 
                   3183:                         b = argstck[arg + 1];
                   3184:                         c = argstck[arg + 2];
                   3185: 
                   3186:                         if (f == 2) {
                   3187:                             l1 = 0;
                   3188:                         }
                   3189:                         else {
                   3190:                             l1 = stlen (c); /* $l of 3rd arg */
                   3191:                         }
                   3192: 
                   3193:                         m = 0;
                   3194:                         f = 0;
                   3195:                         
                   3196:                         while ((ch = a[f++]) != EOL) {
                   3197: 
                   3198:                             j = 0;
                   3199:                             
                   3200:                             while (b[j] != EOL) {
                   3201: 
                   3202:                                 if (ch == b[j]) {
                   3203: 
                   3204:                                     if (j < l1) {
                   3205:                                         ch = c[j];
                   3206:                                     }
                   3207:                                     else {
                   3208:                                         ch = EOL;
                   3209:                                     }
                   3210: 
                   3211:                                     break;
                   3212: 
                   3213:                                 }
                   3214: 
                   3215:                                 j++;
                   3216: 
                   3217:                             }
                   3218: 
                   3219:                             if (ch != EOL) a[m++] = ch;
                   3220: 
                   3221:                         }
                   3222: 
                   3223:                         a[m] = EOL;
                   3224: 
                   3225:                     }
                   3226: 
                   3227:                     goto nxt_operator;
                   3228: 
                   3229:                 case TYPE:
                   3230:                 {
                   3231:                     char piv[255];
                   3232:                     
                   3233:                     if (f != 1) {
                   3234:                         merr_raise (FUNARG);
                   3235:                         return;
                   3236:                     }
                   3237: 
                   3238:                     stcpy (piv, argstck[arg]);
                   3239:                     stcnv_m2c (piv);
                   3240: 
                   3241:                     obj_get_attribute (piv, "CLASS", a);
                   3242:                     stcnv_c2m (a);
                   3243:                     
                   3244:                     goto nxt_operator;
                   3245:                 }
                   3246: 
                   3247:                 case INSTANCEOF:
                   3248:                 {
                   3249:                     char io_inst[255];
                   3250:                     char io_cls[255];
                   3251:                     short io_res;
                   3252:                     
                   3253:                     if (f != 2) {
                   3254:                         merr_raise (FUNARG);
                   3255:                         return;
                   3256:                     }
                   3257: 
                   3258:                     stcpy (io_inst, argstck[arg]);
                   3259:                     stcpy (io_cls, argstck[arg + 1]);
                   3260: 
                   3261:                     stcnv_m2c (io_inst);
                   3262:                     stcnv_m2c (io_cls);
                   3263: 
                   3264:                     io_res = obj_instance_of (io_inst, io_cls);
                   3265:                     
                   3266:                     intstr (a, (int) io_res);
                   3267:                     
                   3268:                     goto nxt_operator;
                   3269:                 }
                   3270:                 case 'r':           /* $RANDOM */
                   3271: 
                   3272:                     if (f != 1) {
                   3273:                         merr_raise (FUNARG);
                   3274:                         return;
                   3275:                     } 
                   3276: 
                   3277:                     {
                   3278:                         long ilong;
                   3279: 
                   3280:                         nrandom = (ran_a * nrandom + ran_b) % ran_c;
                   3281: 
                   3282:                         if ((i = intexpr (a)) < 1) {
                   3283:                             merr_raise (ARGER);
                   3284:                             return;
                   3285:                         }
                   3286: 
                   3287:                         ilong = (nrandom * i) / ran_c;
                   3288:                         
                   3289:                         if (ilong < 0) ilong += i;
                   3290: 
                   3291:                         lintstr (a, ilong);
                   3292: 
                   3293:                     }
                   3294: 
                   3295:                     goto nxt_operator;
                   3296: 
                   3297: 
                   3298:                 /* $VIEW */
                   3299:                 case 'v':
                   3300: 
                   3301:                     view_fun (f, a);
                   3302: 
                   3303:                     if (merr () > 0) return;
                   3304:                     
                   3305:                     goto nxt_operator;
                   3306: 
                   3307: 
                   3308:                 /* $ZBOOLEAN */
                   3309:                 case 'B':
                   3310: 
                   3311:                     if (f != 3) {
                   3312:                         merr_raise (FUNARG);
                   3313:                         return;
                   3314:                     }
                   3315: 
                   3316:                     i = 0;
                   3317:                     ch = intexpr (argstck[arg + 2]) % 16;
                   3318:                     b = argstck[arg + 1];
                   3319:                     
                   3320:                     if (*b == EOL) {
                   3321:                         *b = 0;
                   3322:                         b[1] = 0;
                   3323:                     }
                   3324: 
                   3325:                     f = 0;
                   3326:                     
                   3327:                     switch (ch) {
                   3328: 
                   3329:                         
                   3330:                         /* 1: A AND B */
                   3331:                         case 1:
                   3332:                         
                   3333:                             while (a[i] != EOL) {
                   3334: 
                   3335:                                 a[i] &= b[f];
                   3336:                                 i++;
                   3337: 
                   3338:                                 if (b[++f] == EOL) f = 0;
                   3339: 
                   3340:                             }
                   3341: 
                   3342:                             break;
                   3343: 
                   3344: 
                   3345:                         /* 7: A OR B */                    
                   3346:                         case 7:
                   3347:                         
                   3348:                             while (a[i] != EOL) {
                   3349: 
                   3350:                                 a[i] |= b[f];
                   3351:                                 i++;
                   3352:                                 
                   3353:                                 if (b[++f] == EOL) f = 0;
                   3354: 
                   3355:                             }
                   3356: 
                   3357:                             break;
                   3358:                         
                   3359: 
                   3360:                         /* 6: A XOR B */
                   3361:                         case 6:
                   3362:                         
                   3363:                             while (a[i] != EOL) {
                   3364:                                 
                   3365:                                 a[i] = (a[i] ^ b[f]) & (eightbit ? 0377 : 0177);
                   3366:                                 i++;
                   3367: 
                   3368:                                 if (b[++f] == EOL) f = 0;
                   3369: 
                   3370:                             }
                   3371: 
                   3372:                             break;
                   3373:                         
                   3374: 
                   3375:                         /* 14: A NAND B */
                   3376:                         case 14:
                   3377:                         
                   3378:                             while (a[i] != EOL) {
                   3379:                                 
                   3380:                                 a[i] = ~(a[i] & b[f]) & (eightbit ? 0377 : 0177);
                   3381:                                 i++;
                   3382: 
                   3383:                                 if (b[++f] == EOL) f = 0;
                   3384: 
                   3385:                             }
                   3386: 
                   3387:                             break;
                   3388:                         
                   3389: 
                   3390:                         /* 8: A NOR B */
                   3391:                         case 8:
                   3392:                         
                   3393:                             while (a[i] != EOL) {
                   3394: 
                   3395:                                 a[i] = ~(a[i] | b[f]) & (eightbit ? 0377 : 0177);
                   3396:                                 i++;
                   3397: 
                   3398:                                 if (b[++f] == EOL) f = 0;
                   3399: 
                   3400:                             }
                   3401: 
                   3402:                             break;
                   3403:                         
                   3404: 
                   3405:                         /* 9: A EQUALS B */
                   3406:                         case 9:
                   3407:                         
                   3408:                             while (a[i] != EOL) {
                   3409: 
                   3410:                                 a[i] = ~(a[i] ^ b[f]) & (eightbit ? 0377 : 0177);
                   3411:                                 i++;
                   3412: 
                   3413:                                 if (b[++f] == EOL) f = 0;
                   3414: 
                   3415:                             }
                   3416: 
                   3417:                             break;
                   3418:                         
                   3419: 
                   3420:                         /* 2: A AND NOT B */
                   3421:                         case 2:
                   3422:                         
                   3423:                             while (a[i] != EOL) {
                   3424: 
                   3425:                                 a[i] &= ~b[f];
                   3426:                                 i++;
                   3427:                                 
                   3428:                                 if (b[++f] == EOL) f = 0;
                   3429: 
                   3430:                             }
                   3431: 
                   3432:                             break;
                   3433:                         
                   3434: 
                   3435:                         /* 11: A OR NOT B */
                   3436:                         case 11:
                   3437:                         
                   3438:                             while (a[i] != EOL) {
                   3439:                                 
                   3440:                                 a[i] = (a[i] | ~b[f]) & (eightbit ? 0377 : 0177);
                   3441:                                 i++;
                   3442: 
                   3443:                                 if (b[++f] == EOL) f = 0;
                   3444:                             
                   3445:                             }
                   3446:                             
                   3447:                             break;
                   3448:                         
                   3449: 
                   3450:                         /* 13: NOT A OR B */
                   3451:                         case 13:
                   3452:                         
                   3453:                             while (a[i] != EOL) {
                   3454: 
                   3455:                                 a[i] = (~a[i] | b[f]) & (eightbit ? 0377 : 0177);
                   3456:                                 i++;
                   3457:                                 
                   3458:                                 if (b[++f] == EOL) f = 0;
                   3459:                             
                   3460:                             }
                   3461:                             
                   3462:                             break;
                   3463:                         
                   3464: 
                   3465:                         /* 4: NOT A AND B */
                   3466:                         case 4:
                   3467:                         
                   3468:                             while (a[i] != EOL) {
                   3469: 
                   3470:                                 a[i] = ~a[i] & b[f];
                   3471:                                 i++;
                   3472:                                 
                   3473:                                 if (b[++f] == EOL) f = 0;
                   3474: 
                   3475:                             }
                   3476: 
                   3477:                             break;
                   3478:                         
                   3479: 
                   3480:                         /* 5: B */
                   3481:                         case 5:
                   3482:                         
                   3483:                             while (a[i] != EOL) {
                   3484: 
                   3485:                                 a[i++] = b[f];
                   3486:                                 
                   3487:                                 if (b[++f] == EOL) f = 0;
                   3488:                             
                   3489:                             }
                   3490:                             
                   3491:                             break;
                   3492:                         
                   3493: 
                   3494:                         /* 10: NOT B */
                   3495:                         case 10:
                   3496:                         
                   3497:                             while (a[i] != EOL) {
                   3498:                                 
                   3499:                                 a[i++] = ~b[f] & 0177;
                   3500:                                 
                   3501:                                 if (b[++f] == EOL) f = 0;
                   3502:                             
                   3503:                             }
                   3504:                             
                   3505:                             break;
                   3506:                         
                   3507: 
                   3508:                         /* 12: NOT A */
                   3509:                         case 12:
                   3510:                         
                   3511:                             while (a[i] != EOL) {
                   3512: 
                   3513:                                 a[i] = ~a[i] & 0177;
                   3514:                                 i++;
                   3515: 
                   3516:                                 if (b[++f] == EOL) f = 0;
                   3517: 
                   3518:                             }
                   3519: 
                   3520:                             break;
                   3521: 
                   3522: 
                   3523:                         /* 0: always FALSE */
                   3524:                         case 0:
                   3525:                         
                   3526:                             while (a[i] != EOL)
                   3527:                             a[i++] = 0;
                   3528:                             break;
                   3529: 
                   3530: 
                   3531:                         /* 15: always TRUE */
                   3532:                         case 15:
                   3533:                         
                   3534:                             ch = (char) 0177;
                   3535:                             while (a[i] != EOL)
                   3536:                             a[i++] = ch;
                   3537:                             /* 3: A */
                   3538: 
                   3539:                     }
                   3540: 
                   3541:                     goto nxt_operator;
                   3542: 
                   3543: 
                   3544:                 /* ZCRC "cyclic redundancy check" check sums */
                   3545:                 case ZCRC:
                   3546: 
                   3547:                     if (f == 1) {
                   3548:                         f = 0;          /* missing 2nd arg defaults to "0" */
                   3549:                     }
                   3550:                     else {
                   3551: 
                   3552:                         if (f != 2) {
                   3553:                             merr_raise (FUNARG);
                   3554:                             return;
                   3555:                         }
                   3556:                         
                   3557:                         if ((f = intexpr (argstck[arg + 1])) != 0 && f != 1) {
                   3558:                             merr_raise (ARGER);
                   3559:                             return;
                   3560:                         }
                   3561: 
                   3562:                     }
                   3563: 
                   3564:                     i = 0;
                   3565:                     
                   3566:                     if (f == 0) {       /* XORing */
                   3567: 
                   3568:                         f = 0;
                   3569:                     
                   3570:                         while (a[i] != EOL) f ^= a[i++];
                   3571: 
                   3572:                         f = f & 0377;
                   3573: 
                   3574:                     } 
                   3575:                     else {            /* ASCII sum */
                   3576: 
                   3577:                         f = 0;
                   3578:                     
                   3579:                         while (a[i] != EOL) f += a[i++];
                   3580: 
                   3581:                     }
                   3582: 
                   3583:                     intstr (a, f);
                   3584:                     
                   3585:                     goto nxt_operator;
                   3586: 
                   3587: 
                   3588:                 /* $ZFUNCTIONKEY */
                   3589:                 case 'F':
                   3590: 
                   3591:                     if (f != 1) {
                   3592:                         merr_raise (FUNARG);
                   3593:                         return;
                   3594:                     }
                   3595:                     
                   3596:                     if ((i = intexpr (a)) < 1 || i > 44) {
                   3597:                         merr_raise (FUNARG);
                   3598:                         return;
                   3599:                     }
                   3600:                     
                   3601:                     stcpy (a, zfunkey[i - 1]);
                   3602:                     
                   3603:                     goto nxt_operator;
                   3604: 
                   3605: 
                   3606:                 case 'P':           /* $ZPIECE */
                   3607: 
                   3608:                     /* Similar to $PIECE                                    */
                   3609:                     /* The difference is, that stuff within quotes is not   */
                   3610:                     /* counted as delimiter. nor is stuff within brackets   */
                   3611: 
                   3612:                     {
                   3613:                         short l, l1, m, n;
                   3614:                         short quo = 0;    /* quotes */
                   3615:                         short bra = 0;    /* brackets */
                   3616:                         char ch0;
                   3617: 
                   3618:                         b = argstck[arg + 1];
                   3619:                         l1 = b - a - 1;     /* length of 1st argument */
                   3620: 
                   3621:                         switch (f) {
                   3622:                             
                   3623: 
                   3624:                             case 2:
                   3625: 
                   3626:                                 f = 1;
                   3627:                                 l = 1;
                   3628:                             
                   3629:                                 break;
                   3630:                             
                   3631: 
                   3632:                             case 3:
                   3633:                                 
                   3634:                                 if ((f = intexpr (argstck[arg + 2])) <= 0) {
                   3635:                                     a[0] = EOL;
                   3636:                                     goto nxt_operator;
                   3637:                                 }
                   3638: 
                   3639:                                 if (merr () == MXNUM) {
                   3640:                                     if (f >= 0) f = 256;
                   3641:                                     merr_raise (OK);
                   3642:                                 }
                   3643:                                 
                   3644:                                 l = f;
                   3645:                                 break;
                   3646:                             
                   3647: 
                   3648:                             case 4:
                   3649:                                 
                   3650:                                 l = intexpr (argstck[arg + 3]);
                   3651:                                 
                   3652:                                 if (merr () == MXNUM) {
                   3653:                                     
                   3654:                                     if (l >= 0) l = 256;
                   3655:                                 
                   3656:                                     merr_raise (OK);
                   3657:                                 
                   3658:                                 }
                   3659: 
                   3660:                                 if ((f = intexpr (argstck[arg + 2])) <= 0) f = 1;
                   3661: 
                   3662:                                 if (merr () == MXNUM) {
                   3663:                                     
                   3664:                                     if (f >= 0) f = 256;
                   3665:                                     
                   3666:                                     merr_raise (OK);
                   3667:                                 
                   3668:                                 }
                   3669:                                 
                   3670:                                 if (f > l) {
                   3671:                                     a[0] = EOL;
                   3672:                                     goto nxt_operator;
                   3673:                                 }
                   3674: 
                   3675:                                 break;
                   3676: 
                   3677: 
                   3678:                             default:
                   3679:                             
                   3680:                                 merr_raise (FUNARG);
                   3681:                                 return;
                   3682: 
                   3683:                         }
                   3684: 
                   3685:                         i = 0;
                   3686:                         m = 0;
                   3687:                         ch = 0;
                   3688: 
                   3689:                         while (b[ch] != EOL) ch++;       /* $l of 2nd arg */
                   3690: 
                   3691:                         if (ch == 1) {
                   3692: 
                   3693:                             ch = b[0];
                   3694:                             j = 1;
                   3695:                             
                   3696:                             if (f > 1) {
                   3697: 
                   3698:                                 while (i < l1) {    /* scan 1st string ... */
                   3699:                                     
                   3700:                                     ch0 = a[i++];
                   3701:                                     
                   3702:                                     if (ch != '"') {
                   3703: 
                   3704:                                         if (ch0 == '"') {
                   3705:                                             toggle (quo);
                   3706:                                             continue;
                   3707:                                         }
                   3708: 
                   3709:                                         if (quo) continue;
                   3710: 
                   3711:                                     }
                   3712: 
                   3713:                                     if (ch0 == '(') bra++;
                   3714:                                     if (ch0 == ')') bra--;
                   3715: 
                   3716:                                     if (ch0 != ch) continue;
                   3717:                                     if (bra > 1) continue;
                   3718:                                     if ((ch0 != '(') && bra) continue;
                   3719:                                     
                   3720:                                     if (++j == f) {
                   3721:                                         m = i;
                   3722:                                         goto zp10;
                   3723:                                     }
                   3724: 
                   3725:                                 }
                   3726: 
                   3727:                                 /* if(j<f) */ 
                   3728:                                 a[0] = EOL;
                   3729: 
                   3730:                                 goto nxt_operator;
                   3731: 
                   3732:                             }
                   3733: 
                   3734: zp10:
                   3735: 
                   3736:                             for (; i < l1; i++) {
                   3737: 
                   3738:                                 ch0 = a[i];
                   3739:                                 
                   3740:                                 if (ch != '"') {
                   3741: 
                   3742:                                     if (ch0 == '"') {
                   3743:                                         toggle (quo);
                   3744:                                         continue;
                   3745:                                     }
                   3746:                                     
                   3747:                                     if (quo) continue;
                   3748: 
                   3749:                                 }
                   3750: 
                   3751:                                 if (ch0 == '(') bra++;
                   3752:                                 if (ch0 == ')') bra--;
                   3753:                                 if (ch0 != ch) continue;
                   3754:                                 if (bra > 1) continue;
                   3755:                                 if ((ch0 != '(') && bra) continue;
                   3756: 
                   3757:                                 if (j == l) {
                   3758:                                     a[i] = EOL;
                   3759:                                     break;
                   3760:                                 }
                   3761: 
                   3762:                                 j++;
                   3763: 
                   3764:                             }
                   3765: 
                   3766:                             if (m > 0) stcpy (a, &a[m]);
                   3767: 
                   3768:                             goto nxt_operator;
                   3769: 
                   3770:                         }
                   3771: 
                   3772:                         if (ch == 0) {
                   3773:                             a[0] = EOL;
                   3774:                             goto nxt_operator;
                   3775:                         }           /* 2nd arg is empty */
                   3776: 
                   3777:                         /* else (ch>1) $Length of Delimiter>1 */
                   3778:                         n = 1;
                   3779: 
                   3780:                         if (f > 1) {
                   3781: 
                   3782:                             while (i < l1) {    /* scan 1st string ... */
                   3783: 
                   3784:                                 j = 0;
                   3785:                             
                   3786:                                 if ((ch0 = a[i]) == '"') {
                   3787:                                     toggle (quo);
                   3788:                                     i++;
                   3789:                             
                   3790:                                     continue;
                   3791:                                 }
                   3792:                             
                   3793:                                 if (quo) {
                   3794:                                     i++;
                   3795:                                     continue;
                   3796:                                 }
                   3797:                                 
                   3798:                                 if (ch0 == '(') {
                   3799:                                     bra++;
                   3800:                                     i++;
                   3801:                                 
                   3802:                                     continue;
                   3803:                                 }
                   3804:                                 
                   3805:                                 if (ch0 == ')') {
                   3806:                                     bra--;
                   3807:                                     i++;
                   3808:                                 
                   3809:                                     continue;
                   3810:                                 }
                   3811: 
                   3812:                                 if (bra) {
                   3813:                                     i++;
                   3814:                                     continue;
                   3815:                                 }
                   3816: 
                   3817: zp20:
                   3818:                                 if (a[i + j] != b[j]) {
                   3819:                                     i++;
                   3820:                                     continue;
                   3821:                                 }       /* ... for occurence of 2nd */
                   3822:                                 
                   3823:                                 if (++j < ch) goto zp20;
                   3824:                                 
                   3825:                                 i += ch;    /* skip delimiter */
                   3826:                                 
                   3827:                                 if (++n == f) {
                   3828:                                     m = i;
                   3829:                                     goto zp30;
                   3830:                                 }
                   3831:                             }
                   3832:                             
                   3833:                             /* if(n<f) */ a[0] = EOL;
                   3834:                             
                   3835:                             goto nxt_operator;
                   3836:                         }
                   3837: 
                   3838: zp30:
                   3839: 
                   3840:                         while (i < l1) {
                   3841:                             
                   3842:                             j = 0;
                   3843:                             
                   3844:                             if ((ch0 = a[i]) == '"') {
                   3845:                                 toggle (quo);
                   3846:                                 i++;
                   3847:                             
                   3848:                                 continue;
                   3849:                             }
                   3850:                             
                   3851:                             if (quo) {
                   3852:                                 i++;
                   3853:                                 continue;
                   3854:                             }
                   3855: 
                   3856:                             if (ch0 == '(') {
                   3857:                                 bra++;
                   3858:                                 i++;
                   3859:                             
                   3860:                                 continue;
                   3861:                             }
                   3862: 
                   3863:                             if (ch0 == ')') {
                   3864:                                 bra--;
                   3865:                                 i++;
                   3866:                             
                   3867:                                 continue;
                   3868:                             }
                   3869: 
                   3870:                             if (bra) {
                   3871:                                 i++;
                   3872:                                 continue;
                   3873:                             }
                   3874: 
                   3875: zp40:                       
                   3876:                             if (a[i + j] != b[j]) {
                   3877:                                 i++;
                   3878:                                 continue;
                   3879:                             }
                   3880:                             
                   3881:                             if (++j < ch) goto zp40;
                   3882:                                 
                   3883:                             if (n == l) {
                   3884:                                 a[i] = EOL;
                   3885:                                 break;
                   3886:                             }           /* last $zpiece: done! */
                   3887:                             
                   3888:                             i += ch;
                   3889:                             n++;
                   3890: 
                   3891:                         }
                   3892: 
                   3893:                         if (m > 0) stcpy (a, &a[m]);
                   3894: 
                   3895:                         goto nxt_operator;
                   3896:                     
                   3897:                     }
                   3898: 
                   3899:                 case 'L':           /* $ZLENGTH */
                   3900: 
                   3901:                     /* Similar to $LENGTH with two arguments                */
                   3902:                     /* The difference is, that stuff within quotes is not   */
                   3903:                     /* counted as delimiter. nor is stuff within brackets   */
                   3904: 
                   3905:                     if (f != 2) {
                   3906:                         merr_raise (FUNARG);
                   3907:                         return;
                   3908:                     }
                   3909: 
                   3910:                     i = 0;
                   3911:                     j = 0;
                   3912:                     
                   3913:                     b = argstck[arg + 1];
                   3914:                     
                   3915:                     if ((f = stlen (b))) {
                   3916:                         int     quo,
                   3917:                         bra,
                   3918:                         ch0;
                   3919: 
                   3920:                         quo = 0;
                   3921:                         bra = 0;
                   3922: 
                   3923:                         if (f == 1) {       /* length of delimiter =1 char */
                   3924: 
                   3925:                             ch = b[0];
                   3926:                             j = 0;
                   3927:                         
                   3928:                             for (;;) {
                   3929: 
                   3930:                                 ch0 = a[i++];
                   3931: 
                   3932:                                 if (ch0 == EOL) break;
                   3933:                                 
                   3934:                                 if (ch != '"') {
                   3935:                                     
                   3936:                                     if (ch0 == '"') {
                   3937:                                         toggle (quo);
                   3938:                                         continue;
                   3939:                                     }
                   3940: 
                   3941:                                     if (quo) continue;
                   3942: 
                   3943:                                 }
                   3944: 
                   3945:                                 if (ch0 == '(') bra++;
                   3946:                                 if (ch0 == ')') bra--;
                   3947:                                 if (ch0 != ch) continue;
                   3948:                                 if (bra > 1) continue;
                   3949:                                 if ((ch0 != '(') && bra) continue;
                   3950:                                 
                   3951:                                 j++;
                   3952:                             }
                   3953: 
                   3954:                             
                   3955:                             j++;
                   3956:                             
                   3957:                         } 
                   3958:                         else {
                   3959: 
                   3960:                             int n;
                   3961: 
                   3962:                             j = 1;
                   3963: 
                   3964:                             for (;;) {
                   3965: 
                   3966:                                 n = 0;
                   3967: 
                   3968:                                 if ((ch0 = a[i]) == '"') {                                
                   3969:                                     toggle (quo);
                   3970:                                     i++;
                   3971:                                     
                   3972:                                     continue;
                   3973:                                 }
                   3974: 
                   3975:                                 if (ch0 == EOL) break;
                   3976: 
                   3977:                                 if (quo) {
                   3978:                                     i++;
                   3979:                                     continue;
                   3980:                                 }
                   3981: 
                   3982:                                 if (ch0 == '(') {
                   3983:                                     bra++;
                   3984:                                     i++;
                   3985:                                 
                   3986:                                     continue;
                   3987:                                 }
                   3988: 
                   3989:                                 if (ch0 == ')') {
                   3990:                                     bra--;
                   3991:                                     i++;
                   3992:                                     
                   3993:                                     continue;
                   3994:                                 }
                   3995: 
                   3996:                                 if (bra) {
                   3997:                                     i++;
                   3998:                                     continue;
                   3999:                                 }
                   4000: 
                   4001: zl10:                           
                   4002: 
                   4003:                                 if (a[i + n] != b[n]) {
                   4004:                                     i++;
                   4005:                                     continue;
                   4006:                                 }
                   4007: 
                   4008:                                 if (++n < f) goto zl10;
                   4009:                                 
                   4010:                                 i += f;     /* skip delimiter */
                   4011:                                 j++;
                   4012:                             
                   4013:                             }
                   4014:                         }
                   4015:                     }
                   4016: 
                   4017:                     intstr (a, j);
                   4018:                     goto nxt_operator;
                   4019: 
                   4020:                 case ZLSD:          /* $ZLSD levenshtein function */
                   4021:                     
                   4022:                     if (f != 2) {
                   4023:                         merr_raise (FUNARG);
                   4024:                         return;
                   4025:                     }
                   4026: 
                   4027:                     f = levenshtein (a, argstck[arg + 1]);
                   4028:                     intstr (a, f);
                   4029:                     
                   4030:                     goto nxt_operator;
                   4031: 
                   4032: 
                   4033:                 /* $ZKEY */
                   4034:                 /* transform a string to be used as a key in an array so   */
                   4035:                 /* the result string will collate in the desired way       */
                   4036:                 /* according to the production rule specified by VIEW 93   */
                   4037:                 case 'K':
                   4038:                     
                   4039:                     if (f == 2) {
                   4040:                         zkey (a, intexpr (argstck[arg + 1]));
                   4041:                     }
                   4042:                     else if (f == 1) {
                   4043:                         zkey (a, v93);
                   4044:                     }
                   4045:                     else {
                   4046:                         merr_raise (FUNARG);
                   4047:                     }
                   4048:                     
                   4049:                     if (merr () > OK) return;
                   4050: 
                   4051:                     goto nxt_operator;
                   4052: 
                   4053: 
                   4054:                 /* $ZREPLACE */
                   4055:                 /* Replace in first argument non overlapping occurences    */
                   4056:                 /* of the second argument by the third argument.           */
                   4057:                 /* if the third argument is missing, assume it to be empty */
                   4058:                 case 'R':
                   4059:                     
                   4060:                     if (f == 3) {
                   4061:                         zreplace (a, argstck[arg + 1], argstck[arg + 2]);
                   4062:                     }
                   4063:                     else if (f == 2) {
                   4064:                         zreplace (a, argstck[arg + 1], "\201");
                   4065:                     }
                   4066:                     else {
                   4067:                         merr_raise (FUNARG);
                   4068:                     }
                   4069: 
                   4070:                     if (merr () > OK) return;
                   4071: 
                   4072:                     goto nxt_operator;
                   4073: 
                   4074: 
                   4075:                 /* $ZSYNTAX */
                   4076: 
                   4077:                 case 'S':
                   4078: 
                   4079:                     if (f != 1) {
                   4080:                         merr_raise (FUNARG);
                   4081:                         return;
                   4082:                     }
                   4083: 
                   4084:                     zsyntax (a);
                   4085:                     
                   4086:                     if (merr () > OK) return;
                   4087: 
                   4088:                     goto nxt_operator;
                   4089: 
                   4090: 
                   4091:                 /* $ZTIME()/$ZDATE() */
                   4092:                 case 'T':
                   4093:                 case 'D':
                   4094: 
                   4095:                     {
                   4096:                         time_t unix_epoch;
                   4097:                         char *horo_time = a;
                   4098:                         char fmt_string[120];
                   4099:                         struct tm *zdate_time;                        
                   4100:                         
                   4101:                         if (f > 2) {
                   4102:                             merr_raise (FUNARG);
                   4103:                             return;
                   4104:                         }
                   4105: 
                   4106:                         if (!is_horolog (horo_time)) {
                   4107:                             merr_raise (ZINVHORO);
                   4108:                             return;
                   4109:                         }
                   4110:                         
                   4111:                         if (f == 2) {
                   4112:                             stcpy (fmt_string, argstck[arg + 1]);
                   4113:                         }
                   4114:                         else if (f == 1) {
                   4115:                             char zdf_key[50];
                   4116: 
                   4117:                             switch (i) {
                   4118:                                 
                   4119:                                 case 'D':
                   4120:                                     sprintf (zdf_key, "^$JOB\202%d\202ZDATE_FORMAT\201", pid);
                   4121:                                     break;
                   4122: 
                   4123:                                 case 'T':
                   4124:                                     sprintf (zdf_key, "^$JOB\202%d\202ZTIME_FORMAT\201", pid);
                   4125:                                     break;
                   4126: 
                   4127:                             }
                   4128:                                                                 
                   4129:                             ssvn (get_sym, zdf_key, fmt_string);
                   4130:                         }
                   4131:                         
                   4132:                         stcnv_m2c (fmt_string);
                   4133:                                 
                   4134:                         unix_epoch = horolog_to_unix (horo_time);
                   4135:                         zdate_time = localtime (&unix_epoch);
                   4136: 
                   4137:                         strftime (a, 255, fmt_string, zdate_time);
                   4138:                         
                   4139:                         stcnv_c2m (a);
                   4140: 
                   4141:                         goto nxt_operator;
                   4142:                     }
                   4143:                     
                   4144: 
                   4145:                 /* $ZHOROLOG() */
                   4146:                 /* convert string date to $H format */
                   4147:                 case 'H':
                   4148:                     {
                   4149:                         char *time_str = a;
                   4150:                         char *fmt_string = argstck[arg + 1];
                   4151:                         struct tm zhoro_tm;
                   4152:                         unsigned long ilong;
                   4153:                         unsigned long ilong1;
                   4154:                         
                   4155:                         if (f != 2) {
                   4156:                             merr_raise (FUNARG);
                   4157:                             return;
                   4158:                         }
                   4159: 
                   4160:                         strptime (time_str, fmt_string, &zhoro_tm);
                   4161: 
                   4162:                         ilong1 = mktime (&zhoro_tm) + tzoffset;
                   4163:                         ilong = ilong1 / 86400;
                   4164: 
                   4165:                         lintstr (a, ilong + 47117);
                   4166:                         i = stlen (a);
                   4167: 
                   4168:                         a[i++] = ',';
                   4169:                         ilong = ilong1 - (ilong * 86400) + 43200;
                   4170: 
                   4171:                         lintstr (&a[i], ilong);                       
                   4172: 
                   4173:                         goto nxt_operator;
                   4174:                         
                   4175:                     }
                   4176:                     
                   4177:                     
                   4178:                 case GETX:          /* dummy function for implicit $GET */
                   4179: 
                   4180:                     /* un-stack $ZREFERENCE and $ZLOCAL */
                   4181:                     stcpy (zref, refsav[--refsx]);
                   4182:                     stcpy (zloc, refsav[refsx] + 256);
                   4183:                     
                   4184:                     free (refsav[refsx]);
                   4185:                 
                   4186:                 
                   4187:                 case GET:           /* dummy function for $GET with two args */
                   4188:                 
                   4189:                     goto nxt_operator;
                   4190: 
                   4191:                 
                   4192:                 case 'E':           /* ZEDIT */
                   4193:                 
                   4194:                     if (f > 4) {
                   4195:                         merr_raise (FUNARG);
                   4196:                         return;
                   4197:                     } 
                   4198: 
                   4199:                     {
                   4200: 
                   4201:                         int k, l, rev, esc;
                   4202: 
                   4203:                         if (f == 1) {
                   4204:                             rev = TRUE;
                   4205:                             goto reverse;
                   4206:                         }
                   4207: 
                   4208:                         j = (f == 4 ? intexpr (argstck[arg + 3]) : 1);  /* type of action */
                   4209:                         
                   4210:                         if ((rev = j < 0)) j = (-j);
                   4211:                         if ((esc = j / 10) == 1 || esc == 2) j = j % 10;
                   4212: 
                   4213:                         if (j < 1 || j > 3) {
                   4214:                             merr_raise (ARGER);
                   4215:                             return;
                   4216:                         }
                   4217: 
                   4218:                         f = (f >= 3 ? intexpr (argstck[arg + 2]) : 0);  /* target length */
                   4219:                         
                   4220:                         if (f > 255) merr_raise (ARGER);
                   4221:                         
                   4222:                         if (merr () > OK) return;
                   4223: 
                   4224:                         if (esc == 1) {     /* remove ESC-Sequences */
                   4225:                             
                   4226:                             stcpy (tmp, a);
                   4227:                             
                   4228:                             i = 0;
                   4229:                             k = 0;
                   4230:                             l = 1;
                   4231:                             esc = 0;
                   4232:                             
                   4233:                             while ((a[k] = tmp[i++]) != EOL) {
                   4234: 
                   4235:                                 if (l) {
                   4236:                                     if (a[k] != ESC) {
                   4237:                                         k++;
                   4238:                                         continue;
                   4239:                                     }
                   4240:                             
                   4241:                                     if ((a[k] = tmp[i++]) != '[') continue;
                   4242: 
                   4243:                                     l = 0;
                   4244:                                     
                   4245:                                     continue;
                   4246:                                 }
                   4247: 
                   4248:                                 if (a[k] >= '@') l = 1;
                   4249: 
                   4250:                             }
                   4251: 
                   4252:                         }
                   4253: 
                   4254:                         /* anything to be done ??? */
                   4255:                         if (argstck[arg + 1][0] == EOL) goto reverse;
                   4256:                         
                   4257:                         stcpy (tmp, argstck[arg + 1]);
                   4258:                         
                   4259:                         if (j != 1) {       /* remove leading characters */
                   4260:                             
                   4261:                             i = 0;
                   4262:                             k = 0;
                   4263:                             
                   4264:                             while (a[i] != EOL) {
                   4265: 
                   4266:                                 if (a[i] == tmp[k]) {
                   4267:                                     i++;
                   4268:                                     k = 0;
                   4269:                                 
                   4270:                                     continue;
                   4271:                                 }
                   4272:                                 
                   4273:                                 if (tmp[k++] == EOL) break;
                   4274:                             
                   4275:                             }
                   4276:                             
                   4277:                             if (i) stcpy (a, &a[i]);
                   4278: 
                   4279:                         }
                   4280: 
                   4281:                         if (j != 3) {       /* remove trailing characters */
                   4282: 
                   4283:                             i = stlen (a) - 1;
                   4284:                             k = 0;
                   4285:                         
                   4286:                             while (i >= 0) {
                   4287:                                 
                   4288:                                 if (a[i] == tmp[k]) {
                   4289:                                     i--;
                   4290:                                     k = 0;
                   4291: 
                   4292:                                     continue;
                   4293:                                 }
                   4294:                                 
                   4295:                                 if (tmp[k++] == EOL) break;
                   4296: 
                   4297:                             }
                   4298: 
                   4299:                             a[i + 1] = EOL;
                   4300: 
                   4301:                         }
                   4302: 
                   4303:                         i = stlen (a);
                   4304:                         
                   4305:                         if ((f -= i) > 0) { /* characters to append */
                   4306:                             
                   4307:                             if (esc == 2) { /* ignore ESC-Sequences */
                   4308:                                 
                   4309:                                 k = 0;
                   4310:                                 l = 1;
                   4311: 
                   4312:                                 while (a[k] != EOL) {
                   4313: 
                   4314:                                     if (l) {
                   4315: 
                   4316:                                         if (a[k++] == ESC) {
                   4317:                                         
                   4318:                                             f += 2;
                   4319:                                             
                   4320:                                             if (a[k++] == '[') l = 0;
                   4321:                                         
                   4322:                                         }
                   4323:                                     } 
                   4324:                                     else {
                   4325:                                     
                   4326:                                         f++;
                   4327:                                     
                   4328:                                         if (a[k++] >= '@') l = 1;
                   4329: 
                   4330:                                     }
                   4331: 
                   4332:                                 }
                   4333: 
                   4334:                             }
                   4335: 
                   4336:                             k = 0;
                   4337:                             
                   4338:                             if (j == 1) {
                   4339:                                 k = f;
                   4340:                                 f = 0;
                   4341:                             }
                   4342: 
                   4343:                             if (j == 2) {
                   4344:                                 k = f - f / 2;
                   4345:                                 f -= k;
                   4346:                             }
                   4347: 
                   4348:                             l = stlen (tmp);
                   4349:                             
                   4350:                             if (k) {        /* append on right side */
                   4351:                                 
                   4352:                                 a[k += i] = EOL;
                   4353:                                 j = l;
                   4354:                                 
                   4355:                                 while (--k >= i) {
                   4356: 
                   4357:                                     a[k] = tmp[--j];
                   4358:                                     
                   4359:                                     if (j <= 0) j = l;
                   4360: 
                   4361:                                 }
                   4362: 
                   4363:                             }
                   4364: 
                   4365:                             if (f) {        /* append on left side */
                   4366:                                 
                   4367:                                 i = 0;
                   4368:                                 
                   4369:                                 while (l < f) tmp[l++] = tmp[i++];
                   4370: 
                   4371:                                 stcpy (&tmp[l], a);
                   4372:                                 stcpy (a, tmp);
                   4373: 
                   4374:                             }
                   4375: 
                   4376:                         }
                   4377: 
                   4378: reverse: 
                   4379:                         
                   4380:                         if (rev) {
                   4381:                             
                   4382:                             i = stlen (a) - 1;
                   4383:                             j = 0;
                   4384:                             f = i / 2;
                   4385:                         
                   4386:                             while (j <= f) {
                   4387:                                 k = a[j];
                   4388:                                 a[j++] = a[i];
                   4389:                                 a[i--] = k;
                   4390:                             }
                   4391: 
                   4392:                         }
                   4393: 
                   4394:                     }
                   4395: 
                   4396:                     goto nxt_operator;
                   4397: 
                   4398:                 default:
                   4399:                     merr_raise (ILLFUN);
                   4400:                     return;
                   4401: 
                   4402: 
                   4403:             }
                   4404: 
                   4405:             /* end of function evaluation section */
                   4406: 
                   4407: nxt_operator:
                   4408: 
                   4409:             if (spx > 0 && (f = op_stck[spx]) != ARRAY && f != '(') {
                   4410:                 goto nxt_expr;
                   4411:             }
                   4412:             /* push answer */
                   4413: 
                   4414:             op_stck[++spx] = OPERAND;
                   4415:             codptr++;
                   4416:             
                   4417:             goto nextchr;
                   4418: 
                   4419: 
                   4420:     case '$':               /* scan function name convert upper to lower */
                   4421: 
                   4422:         if (op_stck[spx] == OPERAND) goto m_operator;
                   4423:         if ((f = *++codptr) >= 'A' && f <= 'Z') f += 32;
                   4424: 
                   4425:         if (f == 'z' && standard) {
                   4426:             merr_raise (NOSTAND);
                   4427:             return;
                   4428:         }
                   4429: 
                   4430:         if (f == '$' || f == '%') {         /* extrinsic function/extrinsic variable */
                   4431:             
                   4432:             zexflag = FALSE;
                   4433: 
                   4434: extra_fun:
                   4435: 
                   4436: 
                   4437:             {
                   4438:                 short   savmcmnd, savsetp;    /* stuff to be saved */
                   4439:                 char    savarnam[256];
                   4440:                 char   *savdofr;
                   4441:                 long    savlen;
                   4442:                 short   savtest;
                   4443:                 short   savop;
                   4444:                 char   *savargs = NULL;
                   4445:                 int     savarg;
                   4446:                 char   *savastck;
                   4447:                 char   *savpart;
                   4448:                 char   *b;
                   4449:                 char   *namold;
                   4450:                 long    rouoldc;
                   4451:                 char    label[255],
                   4452:                 routine[255];
                   4453:                 short   errex;      /* FLAG: error exit */
                   4454:                 short   libcall;
                   4455:                 libcall = FALSE;
                   4456: 
                   4457:                 for (i = 0; i < 255; i++) {
                   4458:                     routine[i] = '\201';
                   4459:                 }
                   4460:                 
                   4461:                 if (f == '%') libcall = TRUE;
                   4462:                 
                   4463:                 savmcmnd = mcmnd;
                   4464:                 savsetp = setpiece;
                   4465:                 savop = setop;
                   4466:                 savtest = test;
                   4467:                 stcpy (savarnam, varnam);
                   4468:                 savdofr = dofram0;
                   4469:                 errex = FALSE;
                   4470:                 
                   4471:                 if ((argstck[++arg] = a) >= s) {
                   4472:                     
                   4473:                     char   *bak;
                   4474:                     bak = partition;
                   4475:                     
                   4476:                     if (getpmore () == 0) {
                   4477:                         merr_raise (STKOV);
                   4478:                         return;
                   4479:                     }
                   4480: 
                   4481:                     a = a - bak + partition;
                   4482:                     b = b - bak + partition;
                   4483: 
                   4484:                 }
                   4485: 
                   4486:                 savlen = a - argptr;
                   4487:                 savpart = partition;
                   4488:                 
                   4489:                 if (spx > 0) {
                   4490: 
                   4491:                     if ((savargs = calloc ((unsigned) (savlen + 256L), 1)) == NULL) {
                   4492:                         merr_raise (STKOV);
                   4493:                         return;
                   4494:                     }           /* could not allocate stuff...     */
                   4495:                     
                   4496:                     stcpy0 (savargs, argptr, savlen + 256L);
                   4497:                     argptr = partition;
                   4498: 
                   4499:                 }
                   4500: 
                   4501:                 savarg = arg;
                   4502: 
                   4503:                 if ((savastck = calloc ((unsigned) (arg + 1), sizeof (char *))) == NULL) {
                   4504:                     merr_raise (STKOV);
                   4505:                     return;
                   4506:                 }           /* could not allocate stuff...     */
                   4507: 
                   4508:                 stcpy0 (savastck, (char *) argstck, (long) ((arg + 1) * sizeof (char *)));
                   4509: 
                   4510:                 b = label;      /* parse label */
                   4511:                 
                   4512:                 if ((ch = *++codptr) == '%') {
                   4513:                     *b++ = ch;
                   4514:                     codptr++;
                   4515:                 }
                   4516: 
                   4517:                 while (((ch = *codptr) >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) {
                   4518:                     *b++ = ch;
                   4519:                     codptr++;
                   4520:                 }
                   4521: 
                   4522:                 *b = EOL;
                   4523:                 b = routine;               
                   4524: 
                   4525:                 
                   4526:                 if (obj_field) {                    
                   4527:                     strcpy (b, &(object_class[1]));
                   4528:                     stcnv_c2m (b);
                   4529:                     b += strlen (object_class) - 1;
                   4530:                     *++b = EOL;
                   4531:                 }
                   4532:                 
                   4533:                 
                   4534: 
                   4535:                 if (ch == '^') {    /* parse routine name */
                   4536: 
                   4537: 
                   4538:                     
                   4539:                     if (((ch = *++codptr) >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '%') {
                   4540:                         *b++ = ch;
                   4541:                     }
                   4542:                     
                   4543:                     while (((ch = *++codptr) >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) {
                   4544:                         *b++ = ch;
                   4545:                     }
                   4546: 
                   4547:                     if (libcall) {
                   4548:                         char newnam[255];
                   4549:                         
                   4550:                         for (i = 0; i < stlen (routine); i++) {
                   4551:                             routine[i] = tolower (routine[i]);
                   4552:                         }
                   4553: 
                   4554:                         newnam[0] = '%';
                   4555:                         newnam[1] = 'u';
                   4556:                         newnam[2] = 'l';
                   4557:                         newnam[3] = '\201';
                   4558: 
                   4559:                         stcat (newnam, routine);
                   4560:                         
                   4561:                         routine[0] = EOL;
                   4562:                         stcpy (routine, newnam);
                   4563: 
                   4564:                         b = b + 3;                        
                   4565:                     }
                   4566: 
                   4567:                     
                   4568:                     if (routine[0] == EOL) {
                   4569:                         merr_raise (ILLFUN);
                   4570:                         errex = TRUE;
                   4571:                         
                   4572:                         goto errexfun;
                   4573:                     }
                   4574: 
                   4575:                 }
                   4576: 
                   4577:                 
                   4578:                 
                   4579:                 {
                   4580:                     char nrou[255];
                   4581:                     char ntag[255];
                   4582:                     char nbuf[255];
                   4583: 
                   4584:                     stcpy (nrou, routine);
                   4585:                     stcpy (ntag, label);
                   4586: 
                   4587:                     stcnv_m2c (nrou);
                   4588:                     stcnv_m2c (ntag);
                   4589:                     
                   4590: 
                   4591:                     if (rtn_resolve (nrou, ntag, nbuf) != NULL) {
                   4592:                         strcpy (routine, nbuf);
                   4593:                         stcnv_c2m (routine);
                   4594:                     }
                   4595:                     else {
                   4596:                         merr_raise (LBLUNDEF);
                   4597:                         return;
                   4598:                     }
                   4599:                 }
                   4600:                 
                   4601:                 
                   4602:                 *b = EOL;
                   4603:                 
                   4604:                 /* something must be specified */
                   4605:                 if (label[0] == EOL && routine[0] == EOL) {
                   4606:                     merr_raise (ILLFUN);
                   4607:                     errex = TRUE;
                   4608:                     
                   4609:                     goto errexfun;
                   4610:                 }
                   4611: 
                   4612:                 
                   4613:                 if (obj_field) {
1.13      snw      4614:                     char t_objf[STRLEN];
1.1       snw      4615: 
1.13      snw      4616:                     snprintf (t_objf, STRLEN - 1, "%s\201", object_instance);
1.1       snw      4617:                     
                   4618:                     dofram0 = dofrmptr;
                   4619:                     *dofrmptr++ = DELIM;
                   4620:                     dofrmptr += stcpy (dofrmptr, t_objf) + 1;
                   4621:                 }
                   4622:                 
                   4623:                 
                   4624:                 if (*codptr == '(' && *(codptr + 1) != ')') {
                   4625: 
                   4626:                     
                   4627:                     if (!obj_field) dofram0 = dofrmptr;
                   4628:                     obj_field = FALSE;
                   4629:                     
                   4630: 
1.12      snw      4631:                     /* dofram0 = dofrmptr; */
1.1       snw      4632:                     
                   4633:                     i = 0;
                   4634:                     codptr++;
                   4635:                     
                   4636:                     for (;;) {
                   4637: 
                   4638:                         setpiece = TRUE;    /* to avoid error on closing bracket */
                   4639:                         
                   4640:                         if (*codptr == '.' && (*(codptr + 1) < '0' || *(codptr + 1) > '9')) {
                   4641:                             
                   4642:                             codptr++;
                   4643:                             
                   4644:                             expr (NAME);
                   4645:                             codptr++;
                   4646:                             *dofrmptr++ = DELIM;    /* to indicate call by name */
                   4647:                             dofrmptr += stcpy (dofrmptr, varnam) + 1;
                   4648:                         
                   4649:                         } 
                   4650:                         else {
                   4651:                             expr (STRING);
                   4652:                             dofrmptr += stcpy (dofrmptr, argptr) + 1;
                   4653:                         }
                   4654: 
                   4655:                         setpiece = FALSE;
                   4656:                         i++;
                   4657:                         
                   4658:                         if (merr () > OK) {
                   4659:                             dofrmptr = dofram0;
                   4660:                             errex = TRUE;
                   4661:                             
                   4662:                             goto errexfun;
                   4663:                         }
                   4664: 
                   4665:                         ch = *codptr++;
                   4666:                         
                   4667:                         if (ch == ',') continue;
                   4668: 
                   4669:                         if (ch != ')') {
                   4670:                             merr_raise (COMMAER);
                   4671:                             dofrmptr = dofram0;
                   4672:                             errex = TRUE;
                   4673: 
                   4674:                             goto errexfun;
                   4675:                         }
                   4676: 
                   4677:                         ch = *codptr;
                   4678:                         
                   4679:                         break;
                   4680: 
                   4681:                     }
                   4682: 
                   4683:                 } 
                   4684:                 else {
                   4685: 
                   4686:                     
                   4687:                     if (!obj_field) {
                   4688:                         dofram0 = 0;                    
                   4689:                     }
                   4690: 
                   4691:                     obj_field = FALSE;
                   4692:                     
1.12      snw      4693:                     /* dofram0 = 0; */
1.1       snw      4694:                     if (*codptr == '(') codptr += 2;
                   4695:                 
                   4696:                 }
                   4697: 
                   4698:                 rouoldc = roucur - rouptr;
                   4699:                 namold = 0;
                   4700: 
                   4701:                 if (routine[0] != EOL) {    /* load routine */                    
                   4702:                     
                   4703:                     dosave[0] = EOL;
                   4704:                     loadsw = TRUE;
                   4705:                     
                   4706:                     while ((*(namptr++)) != EOL);
                   4707:                     
                   4708:                     namold = namptr;
                   4709:                     
                   4710:                     stcpy (namptr, rou_name);
                   4711:                     zload (routine);
                   4712:                     
                   4713:                     if (merr () > OK) {
                   4714:                         errex = TRUE;
                   4715:                         goto errexfun;
                   4716:                     }
                   4717: 
                   4718:                 } 
                   4719: 
                   4720:                 {
                   4721: 
                   4722:                     char *reg, *reg1;
                   4723: 
                   4724:                     reg1 = rouptr;
                   4725:                     reg = reg1;
                   4726:                     
                   4727:                     if (label[0] != EOL) {
                   4728: 
                   4729:                         while (reg < rouend) {
                   4730:                         
                   4731:                             reg++;
                   4732:                             j = 0;
                   4733:                         
                   4734:                             while (*reg == label[j]) {
                   4735:                                 reg++;
                   4736:                                 j++;
                   4737:                             }
                   4738:                         
                   4739:                             if (label[j] == EOL) {
                   4740: 
                   4741:                                 if (*reg == ':') {
                   4742:                                     char return_type[255];
                   4743:                                     short ret_type;
                   4744:                                     register int typei;
                   4745: 
                   4746:                                     /* we got a return type. parse it. */
                   4747:                                     reg++; /* skip over the colon */
                   4748: 
                   4749:                                     typei = 0;
                   4750:                                     
                   4751:                                     while (isalpha ((ch = *reg++))) {
                   4752:                                         return_type[typei++] = toupper (ch);
                   4753:                                     }
                   4754:                                     
                   4755:                                     reg--; /* back up to the previous char so that parsing of the entry point can resume later */
                   4756:                                     return_type[typei] = '\0';
                   4757: 
                   4758:                                     ret_type = dt_get_type (return_type);
                   4759:                                     if (ret_type == DT_INVALID) {
                   4760:                                         merr_raise (INVTYPE);
                   4761:                                         errex = TRUE;
                   4762: 
                   4763:                                         goto errexfun;
                   4764:                                     }
                   4765: 
                   4766:                                     /* save off the return type to be checked by QUIT code */
                   4767:                                     extr_types[nstx + 1] = ret_type; 
                   4768:                                     
1.12      snw      4769:                                     /* printf ("return_type = '%s' *reg = '%c'\r\n", return_type, *reg); */
1.1       snw      4770:                                 }
                   4771:                                 
                   4772:                                 if (*reg == TAB || *reg == SP) goto off;
                   4773:                                 /* call of procedure without specifying a parameter list */
                   4774: 
                   4775:                                 if (*reg == '(') {
                   4776: 
                   4777:                                     if (dofram0 == 0) dofram0 = dofrmptr;
                   4778:                                 
                   4779:                                     goto off;
                   4780: 
                   4781:                                 }
                   4782: 
                   4783:                             }
                   4784: 
                   4785:                             reg = (reg1 = reg1 + UNSIGN (*reg1) + 2);
                   4786: 
                   4787:                         }
                   4788: 
                   4789:                         {
                   4790: 
                   4791:                             merr_raise (LBLUNDEF);
                   4792:                             stcpy (varerr, label);  /* to be included in error message */
                   4793: 
                   4794:                             if (dofram0) dofrmptr = dofram0; /* reset frame pointer */
                   4795: 
                   4796:                             zload (rou_name);
                   4797:                             
                   4798:                             errex = TRUE;
                   4799:                             
                   4800:                             goto errexfun;
                   4801: 
                   4802:                         }
                   4803:                     }
                   4804: 
                   4805: off:
                   4806:                     
                   4807:                     roucu0 = reg1;
                   4808:                 
                   4809:                 }
                   4810:                 
                   4811:                 if (roucu0 >= rouend) {
                   4812: 
                   4813:                     merr_raise (LBLUNDEF);
                   4814:                     stcpy (varerr, label);  /* to be included in error message */
                   4815:                     
                   4816:                     if (dofram0) dofrmptr = dofram0; /* reset frame pointer */
                   4817:                     
                   4818:                     zload (rou_name);
                   4819:                     errex = TRUE;
                   4820: 
                   4821:                     goto errexfun;
                   4822: 
                   4823:                 }
                   4824: 
                   4825:                 if (routine[0] != EOL) stcpy (rou_name, routine);
                   4826: 
                   4827:                 roucu0++;
                   4828:                 forsw = FALSE;
                   4829: 
                   4830: #ifdef DEBUG_NEWSTACK
                   4831:                 printf("Stack PUSH in expr.c!\r\n");
                   4832: #endif
                   4833: 
                   4834:                 if (++nstx > NESTLEVLS) {
                   4835:                     nstx--;
                   4836:                     merr_raise (STKOV);
                   4837:                     errex = TRUE;
                   4838: 
                   4839:                     goto errexfun;
                   4840:                 }
                   4841:                 else {
                   4842:                     estack++;
                   4843:                 }
                   4844: 
                   4845:                 nestc[nstx] = '$';
                   4846: 
                   4847: #ifdef DEBUG_NEWSTACK
                   4848:                 if(!cmdptr) printf("CMDPTR is ZERO!\r\n");
                   4849: #endif
                   4850: 
                   4851:                 nestp[nstx] = cmdptr;
                   4852:                 nestn[nstx] = namold;
                   4853:                 nestr[nstx] = rouoldc;
                   4854:                 nestnew[nstx] = 0;
                   4855:                 nestlt[nstx] = level;
                   4856:                 level = 0;      /* push level ; clr level */
                   4857:                 ztrap[nstx][0] = EOL;
                   4858: 
                   4859:                 cmdptr += stcpy (cmdptr, codptr - 1) + 1;
                   4860:                 roucur = roucu0;
                   4861: 
                   4862:                 if (dofram0) {
                   4863:                     
                   4864:                     char *reg, *reg1;
                   4865: 
                   4866:                     reg = roucu0;
                   4867:                     reg1 = dofram0;
                   4868: 
                   4869:                     while ((ch = (*reg++)) != '(') {
                   4870: 
                   4871:                         if (ch == SP || ch == TAB || ch == EOL) {
                   4872:                             break;
                   4873:                         }
                   4874: 
                   4875:                     }
                   4876:                     
                   4877:                     if (ch != '(') {
                   4878: 
                   4879:                         merr_raise (TOOPARA);
                   4880:                         dofrmptr = dofram0;
                   4881:                         errex = TRUE;
                   4882:                         
                   4883: #ifdef DEBUG_NEWSTACK
                   4884:                         printf("Cheesy Stack POP in expr.c\r\n");
                   4885: #endif
                   4886: 
                   4887: 
                   4888: 
                   4889:                         nstx--;
                   4890:                         estack--;
                   4891: 
                   4892:                         goto errexfun;
                   4893: 
                   4894:                     }
                   4895: 
                   4896:                     j = 0;
                   4897: 
                   4898:                     if (*reg == ')') {
                   4899:                         reg++;
                   4900:                     }
                   4901:                     else {
                   4902:                         /* PARSE FORMALLIST */
                   4903:                         short fl_type;
1.12      snw      4904:                         /* re-enable following 3 later */
                   4905:                         /*short fl_mandatory;*/
                   4906:                         /*short fl_byref;*/
                   4907:                         /*short lastparm;*/                        
1.1       snw      4908:                         char fl_typestr[255];
                   4909:                         char fl_mand;
                   4910:                         short dtcheck_result;                        
                   4911:                         register short typei;
                   4912:                         short gotparm;
                   4913:                         int paramct;
                   4914:                         
                   4915:                         fl_type = DT_AUTO;
1.12      snw      4916:                         /* re-enable following 3 later */
                   4917:                         /*fl_mandatory = TRUE;*/
                   4918:                         /*fl_byref = FALSE;*/
                   4919:                         /*lastparm = FALSE;*/                        
1.1       snw      4920:                         dtcheck_result = FALSE;
                   4921:                         gotparm = FALSE;
                   4922:                         paramct = 0;
                   4923:                         
                   4924:                         while ((ch = (*reg++)) != EOL) {
                   4925:                             
                   4926:                             gotparm = FALSE;
                   4927:                             
                   4928:                             if ((ch == ':') && j) {
                   4929:                                 
                   4930:                                 /* we have a type specification */
                   4931:                                 typei = 0;
                   4932: 
                   4933:                                 while ((ch = (*reg++)) != EOL) {
                   4934:                                     /* parse it */
                   4935:                                     if (isalpha (ch)) {
                   4936:                                         fl_typestr[typei++] = ch;
                   4937:                                     }
                   4938:                                     else if (ch == ':') {
                   4939:                                         /* we have an "optional" part */
                   4940:                                         fl_typestr[typei] = '\0';
                   4941:                                         fl_mand = *(reg + 1);
                   4942: 
1.12      snw      4943:                                         /*
1.1       snw      4944:                                         if ((fl_mand == 'o') || (fl_mand == 'O')) {
                   4945:                                             fl_mandatory = FALSE;
                   4946:                                         }
                   4947:                                         else {
                   4948:                                             merr_raise (INVLIBOPT);
                   4949:                                             dofrmptr = dofram0;
                   4950: 
                   4951:                                             errex = TRUE;
                   4952: 
                   4953:                                             nstx--;
                   4954:                                             estack--;
                   4955: 
                   4956:                                             goto errexfun;
                   4957:                                         }
1.12      snw      4958:                                         */
                   4959: 
                   4960:                                         if ((fl_mand != 'o') && (fl_mand != 'O')) {
                   4961:                                             merr_raise (INVLIBOPT);
                   4962:                                             dofrmptr = dofram0;
                   4963: 
                   4964:                                             errex = TRUE;
                   4965: 
                   4966:                                             nstx--;
                   4967:                                             estack--;
                   4968: 
                   4969:                                             goto errexfun;
                   4970:                                         }
                   4971:                                             
                   4972:                                         
1.1       snw      4973:                                     }
                   4974:                                     else if ((ch == ',') || (ch == ')')) {
                   4975: 
1.12      snw      4976:                                         /* re-enable later
1.1       snw      4977:                                         if (ch == ')') {
                   4978:                                             lastparm = TRUE;
                   4979:                                         }
1.12      snw      4980:                                         */
1.1       snw      4981: 
                   4982:                                         gotparm = TRUE;
                   4983:                                         paramct++;
                   4984:                                         
                   4985:                                         fl_typestr[typei] = '\0';
                   4986:                                         fl_type = dt_get_type (fl_typestr);
                   4987: 
                   4988:                                         if (fl_type == DT_INVALID) {
                   4989: 
                   4990:                                             merr_raise (INVTYPE);
                   4991:                                             dofrmptr = dofram0;     /* reset frame pointer */
                   4992:                                             errex = TRUE;
                   4993:                                             
                   4994:                                             nstx--;
                   4995:                                             estack--;
                   4996: 
                   4997:                                             goto errexfun;
                   4998: 
                   4999:                                         }
                   5000:                                         
                   5001:                                         break;
                   5002:                                     }
                   5003:                                 }                                
                   5004:                             }
                   5005:                             
                   5006:                             if (gotparm == TRUE) {
                   5007: 
                   5008:                                 if (reg1[0] == DELIM) {
                   5009:                                     dtcheck_result = dt_check (fl_type, reg1 + 1, paramct);
                   5010:                                 }
                   5011:                                 else {
                   5012:                                     dtcheck_result = dt_check (fl_type, reg1, paramct);
                   5013:                                 }
                   5014:                             
                   5015:                                 if (dtcheck_result == FALSE) {
                   5016:                                     merr_raise (TYPMISMATCH);
1.12      snw      5017:                                     dofrmptr = dofram0;     /* reset frame pointer */
1.1       snw      5018: 
                   5019:                                     errex = TRUE;
                   5020: 
                   5021:                                     nstx--;
                   5022:                                     estack--;
                   5023: 
                   5024:                                     goto errexfun;
                   5025:                                 }
                   5026:                             }
                   5027:                             
                   5028:                             if ((ch == ',' || ch == ')') && j) {
                   5029:                             
                   5030:                                 varnam[j] = EOL;
                   5031: 
                   5032: #if 0
                   5033:                     printf("01 [nstx] nstx is (%d) in expr.c\r\n",nstx);
                   5034:                     printf("[nestnew[nstx]] is (%d) in expr.c\r\n",nestnew[nstx]);
                   5035:                     printf("[newptr] newptr is [");
                   5036:                     for(loop=0; loop<50; loop++) 
                   5037:                     printf("%c", (newptr[loop] == EOL) ? '!' : newptr[loop]);
                   5038:                     printf("] in expr.c\r\n");
                   5039: #endif
                   5040: 
                   5041:                                 if (nestnew[nstx] == 0) nestnew[nstx] = newptr;
                   5042: 
                   5043:                                 if (reg1 < dofrmptr) {
                   5044: 
                   5045:                                     if (*reg1 == DELIM) {   /* call by reference */
                   5046: 
                   5047:                                         if (stcmp (reg1 + 1, varnam)) {     /* are they different?? */
                   5048:                                             symtab (new_sym, varnam, "");
                   5049:                                             symtab (m_alias, varnam, reg1 + 1);
                   5050:                                         }
                   5051: 
                   5052:                                     } 
                   5053:                                     else {
                   5054:                                         symtab (new_sym, varnam, "");   /* call by value */
                   5055:                                         symtab (set_sym, varnam, reg1);
                   5056:                                     }
                   5057: 
                   5058:                                     reg1 += stlen (reg1) + 1;
                   5059: 
                   5060:                                 } 
                   5061:                                 else {
                   5062:                                     symtab (new_sym, varnam, "");
                   5063:                                 }
                   5064:                                 
                   5065:                                 if (ch == ')') break;
                   5066:                                 
                   5067:                                 j = 0;
                   5068:                                 continue;
                   5069:                             }
                   5070: 
                   5071:                             if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9' && j) || (ch == '%' && j == 0)) {
                   5072:                                 varnam[j++] = ch;
                   5073:                                 continue;
                   5074:                             }
                   5075:                             
                   5076:                             merr_raise (ARGLIST);
                   5077:                             dofrmptr = dofram0;     /* reset frame pointer */
                   5078:                             errex = TRUE;
                   5079: 
                   5080:                             nstx--;
                   5081:                             estack--;
                   5082: 
                   5083:                             goto errexfun;
                   5084: 
                   5085:                         }
                   5086: 
                   5087:                     }
                   5088: 
                   5089:                     if (reg1 < dofrmptr) {
                   5090:                         merr_raise (TOOPARA);
                   5091:                         dofrmptr = dofram0; /* reset frame pointer */
                   5092:                         errex = TRUE;
                   5093:                         nstx--;
                   5094:                         estack--;                    
                   5095: 
                   5096:                         goto errexfun;
                   5097:                     }
                   5098: 
                   5099:                     dofrmptr = dofram0;
                   5100:                 
                   5101:                 }
                   5102: 
                   5103:                 xecline (0);
                   5104: 
                   5105:                 if (repQUIT) {      /* repeat QUIT */
                   5106: 
                   5107:                     stcpy (code, " V 26:\201");
                   5108: 
                   5109: #ifdef DEBUG_NEWSTACK
                   5110:                     printf("Trying to get at nstx in expr.c (2)\r\n");
                   5111: #endif
                   5112: 
                   5113:                     intstr (&code[6], nstx - repQUIT);
                   5114:                     repQUIT = 0;
                   5115:                     codptr = code;
                   5116: 
                   5117:                     return;
                   5118: 
                   5119:                 }
                   5120: 
                   5121:                 stcpy (tmp, argptr);
                   5122: 
                   5123: errexfun:
                   5124: 
                   5125:                 mcmnd = savmcmnd;
                   5126:                 setpiece = savsetp;
                   5127:                 setop = savop;
                   5128:                 test = savtest;
                   5129:                 
                   5130:                 stcpy (varnam, savarnam);
                   5131:                 
                   5132:                 dofram0 = savdofr;
                   5133:                 argptr = partition;
                   5134:                 a = argptr;
                   5135:                 
                   5136:                 if (spx > 0) {
                   5137:                     stcpy0 (argptr, savargs, savlen + 256L);
                   5138:                     free (savargs);
                   5139:                 }
                   5140:                 
                   5141:                 arg = savarg;
                   5142:                 stcpy0 ((char *) argstck, savastck, (long) ((arg + 1) * sizeof (char *)));
                   5143: 
                   5144:                 free (savastck);
                   5145:                 a = savlen + argptr;
                   5146:                 
                   5147:                 if (savpart != partition) { /* autoadjust may have changed that */
                   5148:                     
                   5149:                     f = 0;
                   5150: 
                   5151:                     while (f <= arg) {
                   5152: 
                   5153:                         if (argstck[f]) argstck[f] = argstck[f] - savpart + partition;
                   5154:                     
                   5155:                         f++;
                   5156: 
                   5157:                     }
                   5158: 
                   5159:                 }
                   5160: 
                   5161:                 if (errex) {
                   5162: 
                   5163:                     if (zexflag && (merr () == NOPGM || merr () == LBLUNDEF)) merr_raise (ILLFUN);
                   5164:                     return;
                   5165:                 
                   5166:                 }
                   5167: 
                   5168:                 if (merr () != OK) return;
                   5169: /*                if (ierr != OK && ierr != (OK - CTRLB)) return;*/
                   5170: 
                   5171:                 stcpy (a, tmp);
                   5172:                 
                   5173:                 goto exec;
                   5174:             
                   5175:             }               /* end of extrinsic function/variable section */
                   5176:         
                   5177:         } 
                   5178:         else if (((ch = *++codptr) >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
                   5179: 
                   5180:             if (ch < 'a') ch += 32;
                   5181: 
                   5182:             tmp[0] = SP;
                   5183:             tmp[1] = f;
                   5184:             tmp[2] = ch;
                   5185:             b = &tmp[3];
                   5186:             
                   5187:             while (((ch = *++codptr) >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) *b++ = ch | 0140;
                   5188: 
                   5189:             *b++ = SP;
                   5190:             *b = EOL;
                   5191:             
                   5192:             if (ch == '(') {        /* function */
                   5193: 
                   5194:                 if (f != 'z') {     /* standard instrinsic functions */
                   5195: 
                   5196:                     if (find (" ascii char data extract find fn fnumber get increment ins instanceof justify length na name next order piece \
                   5197:                     query qlength ql qsubscript qs random re reverse select st stack text tr translate ty type view ", tmp) == FALSE) {
                   5198:                         merr_raise (ILLFUN);
                   5199:                         return;
                   5200:                     }
                   5201: 
                   5202:                     if (f == 'f' && tmp[2] == 'n') f = FNUMBER;
                   5203:                     else if (f == 'q' && tmp[2] == 'l') f = QLENGTH;
                   5204:                     else if (f == 'q' && tmp[2] == 's') f = QSUBSCRIPT;
                   5205:                     else if (f == 'r' && tmp[2] == 'e') f = REVERSE;
                   5206:                     else if (f == 's' && tmp[2] == 't') f = SVNstack;
                   5207:                     else if (f == 't' && tmp[2] == 'r') f = TRANSLATE;
                   5208:                     else if (f == 'n' && tmp[2] == 'a') f = 'N';
                   5209:                     else if (f == 't' && tmp[2] == 'y') f = TYPE;
                   5210:                     else if (f == 'i' && tmp[3] == 's') f = INSTANCEOF;                   
                   5211: 
                   5212:                 } 
                   5213:                 else {
                   5214: 
                   5215:                     /* userdefined intrinsic: process as extrinsic */
                   5216:                     if ((find (zfunctions, tmp) == FALSE) && (tmp[2] != 'f' || tmp[3] != SP)) {
                   5217:                         
                   5218:                         f = stlen (tmp) - 1;
                   5219:                         stcpy (&tmp[f], codptr);
                   5220:                         
                   5221:                         code[0] = '$';
                   5222:                         code[1] = '^';
                   5223:                         code[2] = '%';
                   5224:                         code[3] = 'Z';
                   5225:                         
                   5226:                         stcpy (&code[4], &tmp[2]);
                   5227:                         
                   5228:                         codptr = code;
                   5229:                         f = '$';
                   5230:                         zexflag = TRUE;
                   5231:                         
                   5232:                         goto extra_fun;
                   5233: 
                   5234:                     }
                   5235: 
                   5236:                     f = tmp[2] - 32;
                   5237: 
                   5238:                     if (tmp[3] == SP) {
                   5239: 
                   5240:                         if (f == 'S' && s_fun_flag == FALSE) f = 'o';    /* ZSORT(=$ORDER) instead of ZSYNTAX */
                   5241:                         if (f == 'P' && p_fun_flag == FALSE) f = ZPREVIOUS;  /* ZPREVIOUS instead of ZPIECE */
                   5242:                         if (f == 'D' && d_fun_flag == FALSE) f = ZDATA;  /* ZDATA instead of ZDATE */
                   5243:                         if (f == 'N' && n_fun_flag == FALSE) f = ZNEXT;  /* ZNEXT instead of ZNAME */
                   5244:                         
                   5245:                     } 
                   5246:                     else {
                   5247: 
                   5248:                         switch (f) {
                   5249: 
                   5250: 
                   5251:                             case 'C':
                   5252:                                 if ((stcmp (" zcrc \201", tmp) == 0) ||
                   5253:                                 (stcmp (" zcr \201", tmp) == 0))
                   5254:                                 f = ZCRC;
                   5255:                                 break;
                   5256: 
                   5257: 
                   5258:                             case 'D':
                   5259:                                 if (stcmp (" zdata \201", tmp) == 0)
                   5260:                                 f = ZDATA;
                   5261:                                 break;
                   5262: 
                   5263: 
                   5264:                             case 'L':
                   5265:                                 if (stcmp (" zlsd \201", tmp) == 0)
                   5266:                                 f = ZLSD;
                   5267:                                 break;
                   5268: 
                   5269: 
                   5270:                             case 'N':
                   5271:                                 if (stcmp (" znext \201", tmp) == 0)
                   5272:                                 f = ZNEXT;
                   5273:                                 break;
                   5274: 
                   5275: 
                   5276:                             case 'P':
                   5277:                                 if (stcmp (" zprevious \201", tmp) == 0)
                   5278:                                 f = ZPREVIOUS;
                   5279:                                 break;
                   5280: 
                   5281:                             case 'S':
                   5282:                                 if (stcmp (" zsort \201", tmp) == 0)
                   5283:                                 f = 'o';    /* process $ZSORT as $ORDER */
                   5284:                                 break;
                   5285:                                                         
                   5286: 
                   5287:                         }
                   5288: 
                   5289:                     }
                   5290:                 }
                   5291:             } 
                   5292:             else {            /* special variable */
                   5293: 
                   5294:                 if (f != 'z') {
                   5295:                     
                   5296:                     if (find (" di dialect ec ecode es estack et etrap device horolog io job key pd pdisplay principal quit reference st stack storage sy system test ti timezone tl tlevel tr trollback wi with ", tmp) == FALSE) {
                   5297:                         merr_raise (ILLFUN);
                   5298:                         return;
                   5299:                     }
                   5300: 
                   5301:                     if (f == 's') {
                   5302: 
                   5303:                         if (tmp[2] == 'y') f = SVNsystem;
                   5304:                         if (tmp[2] == 't') f = SVNstack;
                   5305: 
                   5306:                     }
                   5307: 
                   5308:                     if (f == 'd') {
                   5309:                         f = SVNdialect;
                   5310:                     }
                   5311:                     
                   5312:                     if (f == 'e') {
                   5313:                         
                   5314:                         if (tmp[2] == 'c') f = SVNecode;
                   5315:                         if (tmp[2] == 's') f = SVNestack;
                   5316:                         if (tmp[2] == 't') f = SVNetrap;
                   5317: 
                   5318:                     }
                   5319: 
                   5320:                     if (f == 'p' && tmp[2] == 'd') f = SVNpdisplay;                        
                   5321: 
                   5322:                     if (f == 't') {
                   5323:                         
                   5324:                         if (tmp[2] == 'i') f = SVNtimezone;
                   5325:                         if (tmp[2] == 'l') f = SVNtlevel;
                   5326:                         if (tmp[2] == 'r') f = SVNtrollback;
                   5327: 
                   5328:                     }
                   5329: 
                   5330:                 } 
                   5331:                 else {
                   5332: 
                   5333:                     if (find (zsvn, tmp) == FALSE) {
                   5334:                         *(--b) = EOL;   /* there's a SPace we don't need */
                   5335:                         f = ' ';    /* user defined svn */
                   5336:                     } 
                   5337:                     else {
                   5338: 
                   5339:                         f = tmp[2] - 32;
                   5340: 
                   5341:                         if (f == 'T' && tmp[3] == 'r' && (tmp[4] == SP || (stcmp (" ztrap \201", tmp) == 0))) f = ZTRAP;
                   5342: 
                   5343:                         if (f == 'M') { /* loadable match */
                   5344: 
                   5345:                             if ((f = tmp[3]) >= 'a' && f <= 'z') f -= 32;
                   5346: 
                   5347:                             f -= 64;
                   5348: 
                   5349:                         }
                   5350: 
                   5351:                         if (f == 'U' && tmp[3] == 't') f = SVNzut;
                   5352:                             
                   5353:                     }
                   5354:                 }
                   5355:             }
                   5356:         }
                   5357: 
                   5358:         if (ch != '(') {        /* 'special variable' */
                   5359:         
                   5360:             codptr--;
                   5361:         
                   5362:             if (extyp != STRING && extyp != ARGIND && spx == 0) {
                   5363:                 return;
                   5364:             }
                   5365: 
                   5366:             if ((argstck[++arg] = a) >= s) {
                   5367: 
                   5368:                 char   *bak;
                   5369:                 bak = partition;
                   5370: 
                   5371:                 if (getpmore () == 0) {
                   5372:                     merr_raise (STKOV);
                   5373:                     return;
                   5374:                 }
                   5375: 
                   5376:                 a = a - bak + partition;
                   5377:                 b = b - bak + partition;
                   5378: 
                   5379:             }
                   5380: 
                   5381:             /************* special variable evaluation ************************************/
                   5382:             switch (f) {
                   5383: 
                   5384: 
                   5385:                 /* $ZUUID */
                   5386:                 case 'U':
                   5387: 
                   5388:                     uuid_v4 (a);
                   5389:                     stcnv_c2m (a);
                   5390:                     
                   5391:                     goto exec;
                   5392: 
                   5393: #if !defined(__osf__)
                   5394:                 case SVNzut:
                   5395:                 {
                   5396:                     unsigned long long res;
                   5397:                     
                   5398:                     struct timeval tv;
                   5399:                     gettimeofday(&tv, NULL);
                   5400: 
                   5401:                     res = tv.tv_sec * 1000000 + tv.tv_usec;
                   5402: 
                   5403:                     sprintf (a, "%llu\201", res);
                   5404: 
                   5405:                     goto exec;
                   5406:                 }
                   5407: #endif
                   5408:                 
                   5409:                 /* $JOB */
                   5410:                 case 'j':
                   5411: 
                   5412:                     lintstr (a, pid);
                   5413: 
                   5414:                     goto exec;
                   5415: 
                   5416: 
                   5417:                 /* $IO */
                   5418:                 case 'i':
                   5419: 
                   5420:                     intstr (a, io);
                   5421:                     i = stlen (a);
                   5422:                     a[i++] = ':';
                   5423:                     a[i++] = '"';
                   5424:                     i += stcpy (&a[i], dev[io]);
                   5425:                     a[i++] = '"';
                   5426:                     a[i] = EOL;
                   5427: 
                   5428:                     goto exec;
                   5429:                     
                   5430:                 case SVNdialect:
                   5431:                 {
                   5432:                     short rb_slot;
                   5433:                     rb_slot = rbuf_slot_from_name (rou_name);
                   5434: 
                   5435:                     switch (rbuf_flags[rb_slot].dialect) {
                   5436: 
                   5437:                         case D_FREEM:
                   5438:                             sprintf (a, "FREEM\201");
                   5439:                             break;
                   5440:                             
                   5441:                         case D_MDS:
                   5442:                             sprintf (a, "MDS\201");
                   5443:                             break;
                   5444: 
                   5445:                         case D_M77:
                   5446:                             sprintf (a, "M77\201");
                   5447:                             break;
                   5448: 
                   5449:                         case D_M84:
                   5450:                             sprintf (a, "M84\201");
                   5451:                             break;
                   5452: 
                   5453:                         case D_M90:
                   5454:                             sprintf (a, "M90\201");
                   5455:                             break;
                   5456: 
                   5457:                         case D_M95:
                   5458:                             sprintf (a, "M95\201");
                   5459:                             break;
                   5460: 
                   5461:                         case D_M5:
                   5462:                             sprintf (a, "M5\201");
                   5463:                             break;
                   5464:                     }
                   5465: 
                   5466:                     goto exec;
                   5467:                             
                   5468:                 }
                   5469: 
                   5470:                 /* $PDISPLAY */
                   5471:                 case SVNpdisplay:
                   5472: 
                   5473:                     if (getenv ("DISPLAY") != NULL) {
                   5474:                         char *mwapi_display;
                   5475:                         char disp_temp[255];
                   5476: 
                   5477:                         mwapi_display = getenv ("DISPLAY");
                   5478:                         strncpy (disp_temp, mwapi_display, 255);
                   5479:                         stcnv_c2m (disp_temp);
                   5480:                         stcpy (a, disp_temp);
                   5481:                     }
                   5482:                     else {
                   5483:                         intstr (a, 0);
                   5484:                     }
                   5485:                     goto exec;
                   5486: 
                   5487:                 /* $PRINCIPAL */
                   5488:                 case 'p':
                   5489: 
                   5490:                     a[0] = '0';
                   5491:                     a[1] = ':';
                   5492:                     a[2] = '"';
                   5493:                     i = 3 + stcpy (&a[3], dev[HOME]);
                   5494:                     a[i++] = '"';
                   5495:                     a[i] = EOL;
                   5496: 
                   5497:                     goto exec;
                   5498: 
                   5499: 
                   5500:                 /* $QUIT */
                   5501:                 case 'q':
                   5502: 
                   5503:                     a[0] = '0' | (nestc[nstx] == '$');
                   5504: 
                   5505: 
                   5506: 
                   5507:                     a[1] = EOL;
                   5508: 
                   5509:                     goto exec;
                   5510: 
                   5511: 
                   5512:                 /* $TEST */
                   5513:                 case 't':
                   5514:                     
                   5515:                     a[0] = '0' | test;
                   5516:                     a[1] = EOL;
                   5517: 
                   5518:                     goto exec;
                   5519: 
                   5520: 
                   5521:                 /* $HOROLOG */
                   5522:                 case 'h':
                   5523: 
                   5524:                     {
                   5525: 
                   5526:                         unsigned long ilong, ilong1;
                   5527: 
                   5528:                         ilong1 = time (0L) + tzoffset;  /* make $H local time */
                   5529:                         ilong = ilong1 / 86400;
                   5530:                         
                   5531:                         lintstr (a, ilong + 47117);
                   5532:                         i = stlen (a);
                   5533:                         
                   5534:                         a[i++] = ',';
                   5535:                         ilong = ilong1 - (ilong * 86400);
                   5536:                         
                   5537:                         lintstr (&a[i], ilong);
                   5538:                         
                   5539:                         goto exec;
                   5540: 
                   5541:                     }
                   5542: 
                   5543: 
                   5544:                 /* $ZHOROLOG() */
                   5545:                 case 'H':
                   5546:                     {
                   5547: 
                   5548:                         unsigned long ilong, ilong1;
                   5549:                     
                   5550: #if defined(USE_GETTIMEOFDAY) && !defined(__osf__)
                   5551:                     
                   5552:                         struct timeval timebuffer;
                   5553:                         gettimeofday (&timebuffer, NULL);
                   5554:                         
                   5555:                         ilong1 = timebuffer.tv_sec + tzoffset;  /* make $ZH local time */
                   5556:                     
                   5557: #else
                   5558: 
                   5559:                         struct timeb timebuffer;
                   5560:                         ftime (&timebuffer);
                   5561:                         ilong1 = timebuffer.time + tzoffset;    /* make $ZH local time */
                   5562:                     
                   5563: #endif
                   5564:                     
                   5565:                         ilong = ilong1 / 86400;
                   5566:                         lintstr (a, ilong + 47117);
                   5567:                         i = stlen (a);
                   5568:                         a[i++] = ',';
                   5569:                         ilong = ilong1 - (ilong * 86400);
                   5570:                         lintstr (&a[i], ilong);
                   5571: 
                   5572: #if defined(USE_GETTIMEOFDAY) && !defined(__osf__)
                   5573:                         if ((ilong = timebuffer.tv_usec)) 
                   5574: #else
                   5575:                         if ((ilong = timebuffer.millitm)) 
                   5576: #endif
                   5577:                         {
                   5578:                             char doggie_bag[50];
                   5579: 
1.13      snw      5580:                             snprintf (doggie_bag, sizeof (doggie_bag) - 1, ".%ld\201", ilong);
1.1       snw      5581:                             stcat (a, doggie_bag);
                   5582:                         }
                   5583:                     }
                   5584:                     goto exec;
                   5585: 
                   5586: 
                   5587:                 case SVNsystem:
                   5588: 
1.13      snw      5589:                     sprintf (a, "%d,\"%s\"\201", MDC_VENDOR_ID, jour_hostid); 
1.1       snw      5590:                     goto exec;
                   5591: 
                   5592: 
                   5593:                 case SVNtimezone:
                   5594: 
                   5595:                     lintstr (a, tzoffset);
                   5596:                     goto exec;
                   5597: 
                   5598: 
                   5599:                 case SVNtlevel:
                   5600: 
1.13      snw      5601:                     sprintf (a, "%d\201", tp_level);
1.1       snw      5602:                     goto exec;
                   5603: 
                   5604: 
                   5605:                 case SVNtrollback:
                   5606: 
                   5607:                     a[0] = '0';
                   5608:                     a[1] = EOL;
                   5609:                     goto exec;
                   5610: 
                   5611: 
                   5612:                 case SVNecode:    
                   5613: 
1.12      snw      5614:                     /* write_m ("in SVNecode\r\n\201"); */
1.1       snw      5615: 
                   5616:                     if (stlen (user_ecode)) {
                   5617:                         stcpy (a, user_ecode);
                   5618:                     }
                   5619:                     else {
                   5620:                         stcpy (a, ecode);
                   5621:                     }
                   5622:                     
                   5623:                     goto exec;
                   5624: 
                   5625: 
                   5626:                 case SVNestack:
                   5627:                     {
                   5628:                         char esbuf[256];
1.13      snw      5629:                         sprintf (esbuf, "%d\201", estack);
1.1       snw      5630: 
                   5631:                         stcpy (a, esbuf);
                   5632:                         goto exec;
                   5633: 
                   5634:                     }
                   5635: 
                   5636: 
                   5637:                 case SVNetrap:
1.12      snw      5638: /*                    write_m ("in SVNetrap\r\n\201"); */
1.1       snw      5639:                     stcpy (a, etrap);
                   5640:                     goto exec;
                   5641: 
                   5642: 
                   5643:                 case SVNstack:
                   5644:                     
                   5645:                     intstr (a, nstx);
                   5646: 
                   5647:                     goto exec;
                   5648: 
                   5649:                    
                   5650:                 /* $KEY */
                   5651:                 case 'k':
                   5652: 
                   5653:                    stcpy (a, zb);
                   5654:                    if (*a >= SP && *a < DEL) *a = EOL;
                   5655: 
                   5656:                    goto exec;
                   5657: 
                   5658:                    
                   5659:                 /* $DEVICE */
                   5660:                 case 'd':
                   5661:                     if (devstat[io].mdc_err == 0) {
1.13      snw      5662:                         sprintf (a, "0\201\0");                  
1.1       snw      5663:                     }
                   5664:                     else {
1.13      snw      5665:                         sprintf (a, "%d,%d,%s\201\0", devstat[io].mdc_err, devstat[io].frm_err, devstat[io].err_txt);
1.1       snw      5666:                     }
                   5667: 
                   5668:                     goto exec;
                   5669:                    
                   5670:                 /* $STORAGE */
                   5671:                 case 's':
1.13      snw      5672:                    sprintf (a, "%ld\201", DEFPSIZE);
1.1       snw      5673:                    goto exec;
                   5674: 
                   5675:                /* $WITH */
                   5676:                case 'w':
                   5677:                    stcpy (a, i_with);
                   5678:                    goto exec;
                   5679:                    
                   5680:                 /* $X */
                   5681:                 case 'x':
                   5682: 
                   5683:                    intstr (a, xpos[io]);
                   5684:                    goto exec;
                   5685: 
                   5686:                    
                   5687:                 /* $Y */
                   5688:                 case 'y':
                   5689: 
                   5690:                    intstr (a, ypos[io]);
                   5691:                    goto exec;
                   5692: 
                   5693:                    
                   5694:                 /* non-standard special variables */
                   5695: 
                   5696:                 /* $ZA - on HOME device dummy, else byte offset to begin of file */
                   5697:                 case 'A':
                   5698:                    if (io == HOME) {
                   5699:                        a[0] = '0';
                   5700:                        a[1] = EOL;
                   5701:                    }
                   5702:                    else {
                   5703:                        lintstr (a, ftell (opnfile[io]));
                   5704:                    }
                   5705:                    goto exec;
                   5706: 
                   5707:                    
                   5708:                 /* $ZB - last keystroke */
                   5709:                 case 'B':
                   5710:                    stcpy (a, zb);
                   5711:                    goto exec;
                   5712: 
                   5713:                    
                   5714:                 /* $ZCONTROLC flag */
                   5715:                 case 'C':
                   5716:                    a[0] = '0' | zcc;
                   5717:                    zcc = FALSE;
                   5718:                    a[1] = EOL;
                   5719:                    goto exec;
                   5720: 
                   5721: 
1.12      snw      5722:                 /* $ZX (number of columns) */
                   5723:                 case 'X':
                   5724:                     intstr (a, n_columns);
                   5725:                     goto exec;
                   5726: 
                   5727:                 /* $ZY (number of rows) */
                   5728:                 case 'Y':
                   5729:                     intstr (a, n_lines);
                   5730:                     goto exec;
1.1       snw      5731: 
                   5732:                 /* $ZERROR */
                   5733:                 case 'E':
                   5734:                    stcpy (a, zerror);
                   5735:                    goto exec;
                   5736: 
                   5737:                    
                   5738:                 /* $ZTRAP */
                   5739:                 case ZTRAP:
                   5740: 
                   5741:                    stcpy (a, ztrap[nstx]);
                   5742: 
                   5743:                    goto exec;
                   5744: 
                   5745:                    
                   5746:                 /* $ZPRECISION */
                   5747:                 case 'P':
                   5748:                    intstr (a, zprecise);
                   5749:                    goto exec;
                   5750: 
                   5751:                    
                   5752:                 /* $ZSYSTEM */
                   5753:                 case 'S':
                   5754:                    intstr (a, zsystem);
                   5755:                    goto exec;
                   5756: 
                   5757:                    
                   5758:                 /* $ZVERSION */
                   5759:                 case 'V':
                   5760:                    stcpy (&a[stcpy (a, "FreeM \201")], FREEM_VERSION_STR);
                   5761:                    goto exec;
                   5762: 
                   5763:                    
                   5764:                 /* $ZNAME */
                   5765:                 case 'N':
                   5766:                     /*
                   5767:                    i = 0;
                   5768:                    while ((a[i] = rou_name[i]) != EOL) {
                   5769:                        if (rou_name[i] == '.') break;
                   5770:                        i++;
                   5771:                    }
                   5772:                    a[i] = EOL;
                   5773:                     */
                   5774:                     stcpy (a, rou_name);
                   5775:                    goto exec;
                   5776: 
                   5777:                    
                   5778:                 /* $ZI, INTERRUPT ENABLE/DISABLE */
                   5779:                 case 'I':
                   5780:                    a[0] = '0' | breakon;
                   5781:                    a[1] = EOL;
                   5782:                    goto exec;
                   5783: 
                   5784:                    
                   5785:                 /* $ZDATE */                
                   5786:                 case 'D':
                   5787:                     {
                   5788:                        time_t ilong;
                   5789:                         struct tm *zdate_time;
                   5790:                         char zdf_key[50];
                   5791:                         char fmt_string[128];
                   5792: 
1.13      snw      5793:                         snprintf (zdf_key, sizeof (zdf_key) - 1, "^$JOB\202%d\202ZDATE_FORMAT\201", pid);
1.1       snw      5794:                         ssvn (get_sym, zdf_key, fmt_string);
                   5795:                         stcnv_c2m (fmt_string);
                   5796:                         
                   5797:                        ilong = time (0L);                      
                   5798: 
                   5799:                         zdate_time = localtime (&ilong);
                   5800: 
                   5801:                         strftime (a, 255, fmt_string, zdate_time);
                   5802:                         stcnv_c2m (a);                        
                   5803:                    }
                   5804:                    
                   5805:                    goto exec;
                   5806: 
                   5807:                    
                   5808:                 /* $ZTIME */
                   5809:                 case 'T':
                   5810:                     {
                   5811:                        time_t ilong;
                   5812:                         struct tm *zdate_time;
                   5813:                         
                   5814:                        ilong = time (0L);                      
                   5815: 
                   5816:                         zdate_time = localtime (&ilong);
                   5817: 
                   5818:                         strftime (a, 255, "%X", zdate_time);
                   5819:                         stcnv_c2m (a);                        
                   5820:                    }
                   5821:                    
                   5822:                    goto exec;
                   5823: 
                   5824:                    
                   5825:                 /* $ZJOB - value of JOB number (of father process) */
                   5826:                 case 'J':
                   5827:                    if (father) {
                   5828:                        lintstr (a, father);
                   5829:                    }
                   5830:                    else {
                   5831:                        stcpy (a, "\201");
                   5832:                    }
                   5833: 
                   5834:                    goto exec;
                   5835: 
                   5836:                    
                   5837:                 /* $ZORDER - value of physically next global reference @$ZO(@$ZR) */
                   5838:                 case 'O':
                   5839:                    global  (getnext, tmp, a);
                   5840: 
                   5841:                    if (merr () > 0) return;
                   5842: 
                   5843:                    goto exec;
                   5844: 
                   5845:                    
                   5846:                 /* $ZLOCAL - last local reference */
                   5847:                 case 'L':
                   5848:                    zname (a, zloc);
                   5849:                    if (merr () > OK) return;
                   5850: 
                   5851:                    goto exec;
                   5852: 
                   5853:                    
                   5854:                 /* $(Z)REFERENCE - last global reference */
                   5855:                 case 'r':
                   5856:                 case 'R':
                   5857:                    zname (a, zref);
                   5858:                    if (merr () > OK) return;
                   5859: 
                   5860:                    goto exec;
                   5861: 
                   5862:                    
                   5863:                 case 'C' - 64:
                   5864:                    stcpy (a, zmc);
                   5865:                    goto exec;      /* loadable match 'controls' */
                   5866: 
                   5867: 
                   5868:                case 'N' - 64:
                   5869:                    stcpy (a, zmn);
                   5870:                    goto exec;      /* loadable match 'numerics' */
                   5871: 
                   5872: 
                   5873:                case 'P' - 64:
                   5874:                    stcpy (a, zmp);
                   5875:                    goto exec;      /* loadable match 'punctuation' */
                   5876: 
                   5877: 
                   5878:                case 'A' - 64:
                   5879:                    stcpy (a, zmu);
                   5880:                    stcat (a, zml);
                   5881:                    goto exec;      /* loadable match 'alphabetic' */
                   5882: 
                   5883:                    
                   5884:                 case 'L' - 64:
                   5885:                    stcpy (a, zml);
                   5886:                    goto exec;      /* loadable match 'lowercase' */
                   5887: 
                   5888:                    
                   5889:                 case 'U' - 64:
                   5890:                    stcpy (a, zmu);
                   5891:                    goto exec;      /* loadable match 'uppercase' */
                   5892: 
                   5893:                    
                   5894:                 case 'E' - 64:
                   5895:                    for (i = NUL; i <= DEL; i++) a[i] = i;
                   5896:                    a[i] = EOL;
                   5897:                    goto exec;      /* 'loadable' match 'everything' */
                   5898: 
                   5899: 
                   5900:                case ' ':           /* user defined special variable */
                   5901: 
                   5902:                    udfsvn (get_sym, &tmp[2], a);
                   5903: 
                   5904:                    if (ierr <= OK) goto exec;
                   5905: 
                   5906:                    merr_raise (OK);
                   5907: 
                   5908:                     /* if not found in special variable table, process as extrinsic svn */
                   5909:                    /* $$^%Z... all uppercase */
                   5910: 
                   5911:                    f = 2;
                   5912: 
                   5913:                    while ((ch = tmp[f]) != EOL) {
                   5914: 
                   5915:                        if (ch >= 'a' && ch <= 'z') ch -= 32;
                   5916: 
                   5917:                        tmp[f++] = ch;
                   5918:                        
                   5919:                    }
                   5920:                    
                   5921:                    stcat (tmp, ++codptr);
                   5922: 
                   5923:                    code[0] = '$';
                   5924:                    code[1] = '^';
                   5925:                    code[2] = '%';
                   5926:                    code[3] = 'Z';
                   5927: 
                   5928:                    stcpy (&code[4], &tmp[2]);
                   5929: 
                   5930:                    codptr = code;
                   5931:                    f = '$';
                   5932:                    zexflag = TRUE;
                   5933:                    arg--;
                   5934: 
                   5935:                    goto extra_fun;
                   5936: 
                   5937:                 default:
                   5938:                    merr_raise (ILLFUN);
                   5939:                    return;
                   5940:                 }
                   5941:         /* end of specialvariable evaluation */
                   5942:         /******************************************************************************/
                   5943:        }
                   5944:        if (++spx >= PARDEPTH) {
                   5945:            merr_raise (STKOV);
                   5946:            return;
                   5947:        }
                   5948:        op_stck[spx] = f;
                   5949:        op_stck[++spx] = '$';
                   5950: 
                   5951:        
                   5952: text:
                   5953:        if (*(codptr + 1) != '@') {
                   5954:            f = op_stck[spx - 1];
                   5955:            /* f= (spx>0 ? op_stck[spx-1] : 0);
                   5956:             * if (f) */
                   5957: 
                   5958:            switch (f) {
                   5959:                case 't':           /* $TEXT is special */
                   5960: 
                   5961:                    if ((argstck[++arg] = a) >= s) {
                   5962:                        char   *bak;
                   5963: 
                   5964:                        bak = partition;
                   5965:                        if (getpmore () == 0) {
                   5966:                            merr_raise (STKOV);
                   5967:                            return;
                   5968:                        }
                   5969:                        
                   5970:                        a = a - bak + partition;
                   5971:                        b = b - bak + partition;
                   5972:                        
                   5973:                    }
                   5974:                    
                   5975:                    i = 0;
                   5976:                    
                   5977:                    while ((ch = *++codptr) != EOL) {
                   5978: 
                   5979:                        if (ch == ')') break;
                   5980: 
                   5981:                        if (ch == '+') {
                   5982: 
                   5983:                            a[i] = EOL;
                   5984: 
                   5985:                            if (++spx > PARDEPTH) {
                   5986:                                merr_raise (STKOV);
                   5987:                                return;
                   5988:                            }
                   5989:                            
                   5990:                            op_stck[spx] = OPERAND;
                   5991:                            goto comma;
                   5992: 
                   5993:                        }
                   5994: 
                   5995:                        if (ch == '^') {
                   5996:                            
                   5997:                            a[i] = EOL;
                   5998:                            
                   5999:                            if (++spx > PARDEPTH) {
                   6000:                                merr_raise (STKOV);
                   6001:                                return;
                   6002:                            }
                   6003:                            
                   6004:                            op_stck[spx] = OPERAND;
                   6005:                            a += i + 1;
                   6006:                            
                   6007:                            if (i == 0) {
                   6008:                                a[0] = '1';
                   6009:                                a[1] = EOL;
                   6010:                            }                       
                   6011:                            else {
                   6012:                                /* just routine name: */
                   6013:                                /* return first line  */
                   6014: 
                   6015:                                a[0] = EOL;
                   6016: 
                   6017:                            }
                   6018: 
                   6019:                            if ((argstck[++arg] = a) >= s) {
                   6020:                                char   *bak;
                   6021:                                
                   6022:                                bak = partition;
                   6023: 
                   6024:                                if (getpmore () == 0) {
                   6025:                                    merr_raise (STKOV);
                   6026:                                    return;
                   6027:                                }
                   6028:                                
                   6029:                                a = a - bak + partition;
                   6030:                                b = b - bak + partition;
                   6031:                                
                   6032:                            }
                   6033:                            
                   6034:                            if ((spx + 2) > PARDEPTH) {
                   6035:                                merr_raise (STKOV);
                   6036:                                return;
                   6037:                            }
                   6038:                            
                   6039:                            op_stck[++spx] = '$';
                   6040:                            op_stck[++spx] = OPERAND;
                   6041:                            
                   6042:                            goto uparrow;
                   6043:                        }
                   6044:                        
                   6045:                        if ((ch < '0' && ch != '%')     /* illegal character in $TEXT */
                   6046:                            ||ch > 'z' ||
                   6047:                            (ch < 'A' && ch > '9') ||
                   6048:                            (ch < 'a' && ch > 'Z')) {
                   6049: 
                   6050:                            merr_raise (INVREF);
                   6051:                            return;
                   6052:                            
                   6053:                        }
                   6054:                        
                   6055:                        a[i++] = ch;
                   6056: 
                   6057:                    }
                   6058:                    
                   6059:                    a[i] = EOL;
                   6060:                    codptr--;
                   6061:                    
                   6062:                    goto exec;
                   6063: 
                   6064:                case 'd':           /* $data() */
                   6065:                case 'o':           /* $order() */
                   6066:                case 'g':           /* $get() */
                   6067:                case 'n':           /* $next() */
                   6068:                case 'q':           /* $query() */
                   6069:                case 'O':           /* $zorder() */
                   6070:                case 'N':           /* $zname() */
                   6071:                case ZNEXT:     /* $znext() */
                   6072:                case ZPREVIOUS:     /* $zprevious() */
                   6073:                    {
                   6074: 
                   6075:                        if ((ch = *++codptr) >= 'A' && ch <= 'Z')
                   6076:                            goto scan_name;
                   6077: 
                   6078:                        if (ch >= 'a' && ch <= 'z')
                   6079:                            goto scan_name;
                   6080: 
                   6081:                        if (ch == '%' || ch == '^')
                   6082:                            goto scan_name;
                   6083:                        
                   6084:                        merr_raise (INVEXPR);
                   6085:                        
                   6086:                        return;
                   6087:                    }
                   6088:            }
                   6089:        }
                   6090:        
                   6091:        codptr++;
                   6092:        goto nextchr;
                   6093: 
                   6094:        
                   6095:        case ':':
                   6096:            /* colon: $select or delimiter */
                   6097:            if (spx < 2 || op_stck[spx - 2] != 's') {
                   6098:                
                   6099:                if (op_stck[1] == OPERAND && spx == 1)
                   6100:                    return;
                   6101: 
                   6102:                merr_raise (INVEXPR);
                   6103: 
                   6104:                return;
                   6105: 
                   6106:            }
                   6107:            
                   6108:            arg--;
                   6109:            spx--;
                   6110:            
                   6111:            if (tvexpr (a) == FALSE) {  /* skip next expr */
                   6112:                
                   6113:                i = 0;          /* quote */
                   6114:                j = 0;          /* bracket */
                   6115:                
                   6116:                for (;;) {
                   6117:                    
                   6118:                    ch = *++codptr;
                   6119:                    
                   6120:                    if (ch == '"') {
                   6121:                        toggle (i);
                   6122:                        continue;
                   6123:                    }
                   6124:                    
                   6125:                    if (i) {
                   6126:                        
                   6127:                        if (ch != EOL)
                   6128:                            continue;
                   6129: 
                   6130:                        merr_raise (QUOTER);
                   6131:                        return;
                   6132:                        
                   6133:                    }
                   6134:                    
                   6135:                    if (ch == ',' && !j) {
                   6136:                        codptr++;
                   6137:                        goto nextchr;
                   6138:                    }
                   6139:                    
                   6140:                    if (ch == '(') {
                   6141:                        j++;
                   6142:                        continue;
                   6143:                    }
                   6144:                    
                   6145:                    if (ch == ')') {
                   6146:                        
                   6147:                        if (j--)
                   6148:                            continue;
                   6149:                        
                   6150:                        merr_raise (SELER);
                   6151:                        return;
                   6152:                        
                   6153:                    }
                   6154:                    
                   6155:                    if (ch == EOL) {
                   6156:                        merr_raise (SELER);
                   6157:                        return;
                   6158:                    }
                   6159:                    
                   6160:                }
                   6161:            }
                   6162:            
                   6163:            codptr++;
                   6164:            goto nextchr;
                   6165: 
                   6166:     }
                   6167: 
                   6168: m_operator:
                   6169: 
                   6170:     if (extyp == ARGIND && spx == 1 /* && op_stck[2]!='(' */ )
                   6171:        return;
                   6172: 
                   6173:     f = op_stck[spx];
                   6174: 
                   6175:     if (++spx > PARDEPTH) {
                   6176:        merr_raise (STKOV);
                   6177:        return;
                   6178:     }
                   6179: 
                   6180:     
                   6181: op10:              /* entry for shortcut if first operator */
                   6182: 
                   6183:     /* check for NOT_OPERATOR */
                   6184:     if (ch == NOT) {
                   6185:        if (((ch = *++codptr) == '=' || ch == '<' || ch == '>' || ch == '?' || ch == '&' || ch == '!' || ch == '[' || ch == ']')) {
                   6186:            if (ch == ']' && *(codptr + 1) == ch) {
                   6187:                codptr++;
                   6188:                ch = SORTSAFTER;
                   6189:                if (*(codptr+1)=='=') { 
                   6190:                    codptr++; 
                   6191:                    ch=EQSORTS; 
                   6192:                }
                   6193:            }
                   6194:            if (ch == ']' && *(codptr + 1) == '=') {
                   6195:                codptr++;
                   6196:                ch = EQFOLLOWS;
                   6197:            }
                   6198:            if (ch == '!' && *(codptr + 1) == ch) {
                   6199:                codptr++;
                   6200:                ch = XOR;
                   6201:            }
                   6202:            
                   6203:            op_stck[spx] = SETBIT (ch);
                   6204:            if (ch == '?')
                   6205:                goto scan_pattern;
                   6206:            /*                     a+=stlen(a)+1; */
                   6207:            /* djw: does the while loop do the same as the commented out line above? */
                   6208:            /*      we should decide yes or no and get rid of the other code... */
                   6209: 
                   6210:            while (*a++ != EOL);
                   6211:            
                   6212:            codptr++;
                   6213:            goto nextchr;
                   6214:            
                   6215:        }
                   6216:        else {
                   6217:            op_stck[spx] = NOT;
                   6218:            goto nextchr;
                   6219:        }
                   6220:     }
                   6221: 
                   6222:     if (ch == '*' && *(codptr + 1) == ch) {
                   6223:        codptr++;
                   6224:        ch = POWER;
                   6225:     }
                   6226:     
                   6227:     if (ch == ']' && *(codptr + 1) == ch) {
                   6228:        codptr++;
                   6229:        ch = SORTSAFTER;
                   6230:     }
                   6231:     
                   6232:     if (ch == '<' && *(codptr + 1) == '=') {
                   6233:        codptr++;
                   6234:        ch = SETBIT ('>');
                   6235:     }
                   6236:     
                   6237:     if (ch == '>' && *(codptr + 1) == '=') {
                   6238:        codptr++;
                   6239:        ch = SETBIT ('<');
                   6240:     }
                   6241:     
                   6242:     if (ch == ']' && *(codptr + 1) == '=') {
                   6243:        codptr++;
                   6244:        ch = EQFOLLOWS;
                   6245:     }
                   6246:     
                   6247:     if (ch == SORTSAFTER && *(codptr + 1) == '=') {
                   6248:        codptr++;
                   6249:        ch = EQSORTS;
                   6250:     }
                   6251:     
                   6252:     if (ch == '$')
                   6253:        ch = MAXOP;
                   6254:     
                   6255:     if (ch == '^') {
                   6256:        codptr--;
                   6257:        return;
                   6258:     }
                   6259: 
                   6260:     if ((op_stck[spx] = ch) != PATTERN) {
                   6261: 
                   6262:        if (f == OPERAND) while (*a++ != EOL);       /* binary operator */
                   6263: 
                   6264:        codptr++;
                   6265:        goto nextchr;
                   6266:     }
                   6267:     
                   6268: scan_pattern:
                   6269:     if ((ch = *++codptr) == INDIRECT) { /*  a+=stlen(a)+1;  */
                   6270:        while (*a++ != EOL) ;
                   6271:        goto m_operator;
                   6272:     }
                   6273:     
                   6274:     if ((ch > '9' || ch < '0') && (ch != '.')) {
                   6275:        merr_raise (INVEXPR);
                   6276:        return;
                   6277:     }
                   6278:     
                   6279:     tmp[0] = ch;
                   6280:     i = 1;
                   6281:     f = '1';                /* 'previous' character */
                   6282:     j = 0;              /* point flag */
                   6283:     group = 0;              /* grouped pattern match */
                   6284: 
                   6285:     while ((ch = *++codptr) != EOL) {
                   6286: 
                   6287:        if ((ch >= '0') && (ch <= '9')) {
                   6288: 
                   6289:            tmp[i++] = ch;
                   6290:            f = '1';
                   6291: 
                   6292:            continue;
                   6293:            
                   6294:        }
                   6295:        
                   6296:     if (ch == '.') {
                   6297: 
                   6298:        if (j) {
                   6299:            merr_raise (INVEXPR);
                   6300:            return;
                   6301:        }
                   6302:        
                   6303:        j++;
                   6304:        tmp[i++] = ch;
                   6305:        f = '1';
                   6306:        
                   6307:        continue;
                   6308:     }
                   6309:     
                   6310:     j = 0;
                   6311:     if (ch == NOT) {        /* negation of pattern class ? */
                   6312: 
                   6313:        ch = *(codptr + 1);
                   6314: 
                   6315:        if ((ch == '"') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
                   6316:            tmp[i++] = NOT;
                   6317:        }
                   6318:        else {
                   6319:            ch = NOT;
                   6320:        }
                   6321: 
                   6322:     }
                   6323: 
                   6324:     if (ch == '"') {
                   6325: 
                   6326:        if (f != '1' && f != 'A') {
                   6327:            merr_raise (INVEXPR);
                   6328:            return;
                   6329:        }
                   6330:        
                   6331:        for (;;) {
                   6332:            
                   6333:            tmp[i++] = ch;
                   6334: 
                   6335:            if ((ch = *++codptr) == EOL) {
                   6336:                merr_raise (QUOTER);
                   6337:                return;
                   6338:            }
                   6339:            
                   6340:            if (ch == '"') {
                   6341:                
                   6342:                if ((f = *(codptr + 1)) != '"') {
                   6343:                    ch = DELIM;
                   6344:                    break;
                   6345:                }
                   6346:                
                   6347:                codptr++;
                   6348:            }
                   6349:        }
                   6350:        
                   6351:        tmp[i++] = ch;
                   6352:        f = '"';
                   6353:        
                   6354:        continue;
                   6355:        
                   6356:     }
                   6357:     
                   6358:     if (ch == '(') {
                   6359: 
                   6360:        if (f != '1') {
                   6361:            merr_raise (INVEXPR);
                   6362:            return;
                   6363:        }
                   6364:        
                   6365:        group++;
                   6366:        f = '(';
                   6367:        tmp[i++] = ch;
                   6368:        
                   6369:        continue;
                   6370:        
                   6371:     }
                   6372:     
                   6373:     if (group && (ch == ',' || ch == ')')) {
                   6374: 
                   6375:        if ((f == '1') || (f == '(')) {
                   6376:            merr_raise (INVEXPR);
                   6377:            return;
                   6378:        }
                   6379:        
                   6380:        if (ch == ',') {
                   6381: 
                   6382:            f = '(';
                   6383:            tmp[i++] = ch;
                   6384:            
                   6385:            continue;
                   6386: 
                   6387:        }
                   6388:        
                   6389:     if (ch == ')') {
                   6390:        group--;
                   6391:        tmp[i++] = ch;
                   6392: 
                   6393:        continue;
                   6394:     }
                   6395:     
                   6396:     } /* ??? formatting ??? */
                   6397:     
                   6398:     if (ch >= 'A' && ch <= 'Z') ch += 32;           /* lower case conversion */
                   6399: 
                   6400:     if (ch == 'z') {        /* loadable match, store as uppercase chars */
                   6401: 
                   6402:        if (standard) {
                   6403:            merr_raise (NOSTAND);
                   6404:            return;
                   6405:        }
                   6406:        
                   6407:        ch = *++codptr;
                   6408: 
                   6409:        if (ch == '"') {
                   6410:            
                   6411:            if (f != '1') {
                   6412:                merr_raise (INVEXPR);
                   6413:                return;
                   6414:            }
                   6415:            
                   6416:            codptr--;
                   6417:            tmp[i++] = 'z';
                   6418:            
                   6419:            continue;
                   6420:            
                   6421:        }
                   6422:        
                   6423:        if (ch == '(') {
                   6424: 
                   6425:            if (f != '1') {
                   6426:                merr_raise (INVEXPR);
                   6427:                return;
                   6428:            }
                   6429:            
                   6430:            codptr--;
                   6431:            continue;
                   6432:        }
                   6433:        
                   6434:        if (ch >= 'A' && ch <= 'Z') ch += 32;       /* lower case conversion */
                   6435: 
                   6436:        if (ch != 'e')
                   6437:            j = 1;          /* process 'ze' as 'e' */
                   6438:     }
                   6439: 
                   6440:     if (ch != 'c' && ch != 'n' &&  ch != 'p' && ch != 'a' && ch != 'l' && ch != 'u' && ch != 'e') break;
                   6441: 
                   6442:     if ((f != '1') && (f != 'A')) {
                   6443:        merr_raise (INVEXPR);
                   6444:        return;
                   6445:     }
                   6446:     
                   6447:     if (j) {
                   6448:        ch -= 32;
                   6449:        j = 0;
                   6450:     }
                   6451:     
                   6452:     tmp[i++] = ch;
                   6453:     f = 'A';
                   6454: 
                   6455:     }
                   6456: 
                   6457:     if ((f == '1') || group) {
                   6458:        merr_raise (INVEXPR);
                   6459:        return;
                   6460:     }
                   6461:     
                   6462:     tmp[i] = EOL;
                   6463: 
                   6464:     if ((*a = pattern (a, tmp)) > '1') {
                   6465:        merr_raise (INVEXPR);
                   6466:        return;
                   6467:     }
                   6468:     
                   6469:     if (UNSIGN (op_stck[spx--]) & 0200) toggle (*a);
                   6470:     
                   6471:     *(a + 1) = EOL;
                   6472: 
                   6473:     goto next10;
                   6474: 
                   6475:     /* process values on stack */
                   6476: 
                   6477:     
                   6478: exec:
                   6479: 
                   6480:     if (spx == 0) {
                   6481: 
                   6482:        if ((ch = *++codptr) == EOL || ch == SP || ch == ',' || ch == ':' || (ch == '^' && (extyp == LABEL || extyp == OFFSET))) return;
                   6483: 
                   6484:        op_stck[++spx] = OPERAND;
                   6485: 
                   6486:        goto next10;
                   6487: 
                   6488:     }
                   6489: 
                   6490:     f = op_stck[spx];
                   6491: 
                   6492:     if (f == ARRAY || f == '(') {
                   6493: 
                   6494:        if (++spx > PARDEPTH) {
                   6495:            merr_raise (STKOV);
                   6496:            return;
                   6497:        }
                   6498:        
                   6499:        op_stck[spx] = OPERAND;
                   6500:        codptr++;
                   6501:        
                   6502:        goto nextchr;
                   6503:        
                   6504:     }
                   6505:     
                   6506:     /* process operators */
                   6507: 
                   6508: nxt_expr:
                   6509: 
                   6510:     if (f == '$') {         /* push 'OPERAND' on stack */
                   6511:        
                   6512:        op_stck[++spx] = OPERAND;
                   6513:        codptr++;
                   6514: 
                   6515:        goto nextchr;
                   6516:        
                   6517:     }
                   6518:     
                   6519:     if (f == OPERAND) {
                   6520:        merr_raise (MISSOP);
                   6521:        return;
                   6522:     }
                   6523:     
                   6524:     if (op_stck[--spx] == OPERAND) {    /* binary operators */
                   6525: 
                   6526:        b = a;
                   6527:        a = argstck[--arg];
                   6528: 
                   6529:        switch (f & 0177) {     /* binary operators, NOT OMITTED */
                   6530: 
                   6531:            case PLUS:
                   6532: 
                   6533:                stcpy (tmp, b);
                   6534: 
                   6535: plus01:
                   6536: 
                   6537:                atyp = numlit (a);
                   6538:                btyp = numlit (tmp);
                   6539:                
                   6540: #ifdef EUR2DEM
                   6541:                
                   6542:                if (atyp != btyp) {
                   6543: 
                   6544:                    char    tmp2[256];
                   6545: 
                   6546:                    if ((atyp == 0) && (a[0] == '0')) atyp = btyp;    /* zero is any currency */
                   6547:                    if ((btyp == 0) && (tmp[0] == '0')) btyp = atyp;    /* zero is any currency */
                   6548: 
                   6549:                    if (atyp && btyp) {
                   6550:                        
                   6551:                        if (atyp > 1) {
                   6552:                            stcpy (tmp2, EUR2WHR[atyp]);
                   6553:                            mul (tmp, tmp2);
                   6554:                        }
                   6555:                        
                   6556:                        if (btyp > 1) {
                   6557:                            zprecise += 4;
                   6558:                            stcpy (tmp2, EUR2WHR[btyp]);
                   6559:                            mdiv (tmp, tmp2, '/');
                   6560:                            zprecise -= 4;
                   6561:                        }
                   6562:                        
                   6563:                    }
                   6564:                    else if (atyp != btyp && typemmflag) {
                   6565:                        merr_raise (TYPEMISMATCH);
                   6566:                        return;
                   6567:                    }
                   6568:                    
                   6569:                }
                   6570:                
                   6571: #endif /* EUR2DEM */
                   6572:                
                   6573:                add (a, tmp);
                   6574: plus02:
                   6575: 
                   6576: #ifdef EUR2DEM
                   6577: 
                   6578:                if (atyp == 0) goto next05;
                   6579:                if (atyp != btyp) cond_round (a, zprecise + 2);
                   6580:                
                   6581:                stcat (a, WHR[atyp]);
                   6582: 
                   6583: #endif /* EUR2EUR */
                   6584: 
                   6585:                goto next05;
                   6586: 
                   6587:                
                   6588:            case MINUS:
                   6589: 
                   6590:                tmp[0] = '-';
                   6591:                stcpy (&tmp[1], b);
                   6592:                goto plus01;
                   6593: 
                   6594:                
                   6595:            case MULTIPLY:
                   6596: 
                   6597:                stcpy (tmp, b);
                   6598:                atyp = numlit (a);
                   6599:                btyp = numlit (tmp);
                   6600: #ifdef EUR2DEM
                   6601:                if (btyp && (atyp == 0)) {
                   6602:                    atyp = btyp;
                   6603:                    btyp = 0;
                   6604:                }
                   6605:                
                   6606:                if (atyp && btyp) {
                   6607: 
                   6608:                    if (typemmflag) {
                   6609:                        merr_raise (TYPEMISMATCH);
                   6610:                        return;
                   6611:                    }
                   6612:                    
                   6613:                    atyp = btyp = 0;
                   6614:                    
                   6615:                }
                   6616:                
                   6617: #endif /* EUR2DEM */
                   6618: 
                   6619:                mul (a, tmp);
                   6620: 
                   6621: #ifdef EUR2DEM
                   6622:                
                   6623:                if (atyp == 0) goto next05;
                   6624: 
                   6625:                cond_round (a, zprecise + 2);
                   6626:                stcat (a, WHR[atyp]);
                   6627:                
                   6628: #endif /* EUR2DEM */
                   6629: 
                   6630:                goto next05;
                   6631: 
                   6632:                
                   6633:            case DIVIDE:
                   6634:            case INTDIVIDE:
                   6635:            case MODULO:
                   6636: 
                   6637:                stcpy (tmp, b);
                   6638:                atyp = numlit (a);
                   6639:                btyp = numlit (tmp);
                   6640: 
                   6641: #ifdef EUR2DEM
                   6642:                if (atyp != btyp) {
                   6643:                     char    tmp2[256];
                   6644: 
                   6645:                     if (atyp && btyp) {
                   6646:                         
                   6647:                         if (f == MODULO) {
                   6648: 
                   6649:                             if (atyp > 1) {
                   6650:                                 stcpy (tmp2, EUR2WHR[atyp]);
                   6651:                                 mul (tmp, tmp2);
                   6652:                             }
                   6653: 
                   6654:                             if (btyp > 1) {
                   6655:                                 stcpy (tmp2, EUR2WHR[btyp]);
                   6656:                                 mdiv (tmp, tmp2, '/');
                   6657:                             }
                   6658:                             
                   6659:                         }
                   6660:                         else {
                   6661:                             
                   6662:                             if (atyp > 1) {
                   6663:                                 stcpy (tmp2, EUR2WHR[atyp]);
                   6664:                                 mul (tmp, tmp2);
                   6665:                             }
                   6666: 
                   6667:                             if (btyp > 1) {
                   6668:                                 stcpy (tmp2, EUR2WHR[btyp]);
                   6669:                                 mul (a, tmp2);
                   6670:                             }
                   6671: 
                   6672:                             atyp = btyp = 0;
                   6673: 
                   6674:                         }
                   6675:                         
                   6676:                     } else if (btyp && typemmflag && (*a != '0' || f == MODULO)) {
                   6677:                         merr_raise (TYPEMISMATCH);                        
                   6678:                         return;
                   6679:                     }
                   6680:                 }
                   6681:                 else if (f != MODULO) {
                   6682:                     atyp = 0;
                   6683:                 }
                   6684:                 
                   6685: #endif /* EUR2DEM */
                   6686:                 
                   6687:                 if (tmp[0] == '0') {
                   6688:                     merr_raise (M9);
                   6689:                     return;
                   6690:                 }
                   6691:                 
                   6692:                 if (atyp != btyp) zprecise += 4;
                   6693:                 
                   6694:                 mdiv (a, tmp, f);
                   6695: 
                   6696:                 if (atyp != btyp) zprecise -= 4;
                   6697: 
                   6698:                 goto plus02;
                   6699: 
                   6700:                 
                   6701:             case CONCATENATE:
                   6702: 
                   6703:                 if (stcat (a, b)) goto next05;
                   6704:                 
                   6705:                 merr_raise (M75);
                   6706:                 return;
                   6707: 
                   6708:                 
                   6709:             case EQUAL:
                   6710: 
                   6711:                 if (stcmp (a, b)) {
                   6712:                     *a = '0';
                   6713:                 }
                   6714:                 else {
                   6715:                     *a = '1';
                   6716:                 }
                   6717:                 
                   6718:                 /* common entry point to reverse the logical value */
                   6719:                 /* of current expression               */
                   6720: 
                   6721: 
                   6722: notop:
                   6723:                 if (f & 0200) toggle (*a);        /* NOT_OPERAND */
                   6724: 
                   6725:                 a[1] = EOL;
                   6726:                 
                   6727:                 goto next05;
                   6728: 
                   6729:                 
                   6730:             case GREATER:
                   6731: 
                   6732:                 stcpy (tmp, b);
                   6733:                 atyp = numlit (a);
                   6734:                 btyp = numlit (tmp);
                   6735:                 
                   6736: #ifdef EUR2DEM
                   6737:                 if (atyp != btyp) {
                   6738:                     char tmp2[256];
                   6739: 
                   6740:                     if ((atyp == 0) && (a[0] == '0')) atyp = btyp;    /* zero is any currency */
                   6741:                     if ((btyp == 0) && (tmp[0] == '0')) btyp = atyp;    /* zero is any currency */
                   6742: 
                   6743:                     if (atyp && btyp) {
                   6744:                         
                   6745:                         if (atyp > 1) {
                   6746:                             stcpy (tmp2, EUR2WHR[atyp]);
                   6747:                             mul (tmp, tmp2);
                   6748:                         }
                   6749:                         
                   6750:                         if (btyp > 1) {
                   6751:                             stcpy (tmp2, EUR2WHR[btyp]);
                   6752:                             mul (a, tmp2);
                   6753:                         }
                   6754:                         
                   6755:                         cond_round (a, zprecise + 2);
                   6756:                         cond_round (tmp, zprecise + 2);
                   6757:                         
                   6758:                     }
                   6759:                     else if (atyp != btyp && typemmflag) {
                   6760:                         merr_raise (TYPEMISMATCH);
                   6761:                         return;
                   6762:                     }
                   6763:                 }
                   6764: #endif /* EUR2DEM */
                   6765:                 
                   6766:                 if (comp (tmp, a)) {
                   6767:                     *a = '1';
                   6768:                 }
                   6769:                 else {
                   6770:                     *a = '0';
                   6771:                 }
                   6772:                 
                   6773:                 goto notop;
                   6774: 
                   6775:                 
                   6776:             case LESS:
                   6777: 
                   6778:                 stcpy (tmp, b);
                   6779:                 atyp = numlit (a);
                   6780:                 btyp = numlit (tmp);
                   6781: 
                   6782: #ifdef EUR2DEM
                   6783:                 if (atyp != btyp) {
                   6784:                     char tmp2[256];
                   6785: 
                   6786:                     if ((atyp == 0) && (a[0] == '0')) atyp = btyp;    /* zero is any currency */
                   6787:                     if ((btyp == 0) && (tmp[0] == '0')) btyp = atyp;    /* zero is any currency */
                   6788: 
                   6789:                     if (atyp && btyp) {
                   6790: 
                   6791:                         if (atyp > 1) {
                   6792:                             stcpy (tmp2, EUR2WHR[atyp]);
                   6793:                             mul (tmp, tmp2);
                   6794:                         }
                   6795: 
                   6796:                         if (btyp > 1) {
                   6797:                             stcpy (tmp2, EUR2WHR[btyp]);
                   6798:                             mul (a, tmp2);
                   6799:                         }
                   6800: 
                   6801:                         cond_round (a, zprecise + 2);
                   6802:                         cond_round (tmp, zprecise + 2);
                   6803:                         
                   6804:                     }
                   6805:                     else if (atyp != btyp && typemmflag) {
                   6806:                         merr_raise (TYPEMISMATCH);
                   6807:                         return;
                   6808:                     }
                   6809:                     
                   6810:                 }
                   6811:                 
                   6812: #endif /* EUR2DEM */
                   6813:                 if (comp (a, tmp)) {
                   6814:                     *a = '1';
                   6815:                 }
                   6816:                 else {
                   6817:                     *a = '0';
                   6818:                 }
                   6819:                 
                   6820:                 goto notop;
                   6821: 
                   6822:                 
                   6823:             case AND:
                   6824: 
                   6825:                 if (tvexpr (a)) {
                   6826:                     tvexpr (b);
                   6827:                     *a = *b;
                   6828:                 }
                   6829:                 
                   6830:                 goto notop;
                   6831: 
                   6832:                 
                   6833:             case OR:
                   6834: 
                   6835:                 ch = tvexpr (b);        /* beware case of a="" */
                   6836:                 
                   6837:                 if (tvexpr (a) == FALSE && ch) *a = '1';
                   6838:                 
                   6839:                 goto notop;
                   6840: 
                   6841:                 
                   6842:             case XOR:
                   6843:                 
                   6844:                 ch = tvexpr (b);            /* beware case of a="" */
                   6845:                 *a = (tvexpr(a) == ch) ? '0' : '1';
                   6846: 
                   6847:                 goto notop;
                   6848: 
                   6849:                 
                   6850:             case CONTAINS:
                   6851: 
                   6852:                 if (*b == EOL || find (a, b)) {
                   6853:                     *a = '1';
                   6854:                 }
                   6855:                 else {
                   6856:                     *a = '0';
                   6857:                 }
                   6858:                 
                   6859:                 goto notop;     
                   6860: 
                   6861:                 
                   6862:             case EQFOLLOWS:
                   6863:                 
                   6864:                 if (stcmp (a, b) == 0) {
                   6865:                     a[0] = '1';
                   6866:                     goto notop;
                   6867:                 }
                   6868: 
                   6869:                 
                   6870:             case FOLLOWS:
                   6871: 
                   6872:                 if (*b == EOL) {
                   6873: 
                   6874:                     if (*a == EOL) {
                   6875:                         *a = '0';
                   6876:                     }
                   6877:                     else {
                   6878:                         *a = '1';
                   6879:                     }
                   6880:                     
                   6881:                 }               
                   6882:                 else if (stcmp (a, b) <= 0) {     /* frequent special case */
                   6883:                     *a = '0';
                   6884:                 }
                   6885:                 else {
                   6886:                     *a = '1';
                   6887:                 }
                   6888:                 
                   6889:                 goto notop;
                   6890: 
                   6891:                 
                   6892:             case POWER:
                   6893: 
                   6894:                 stcpy (tmp, b);
                   6895:                 numlit (a);
                   6896:                 numlit (tmp);
                   6897:                 power (a, tmp);
                   6898:                 goto next05;
                   6899: 
                   6900:                 
                   6901:             case EQSORTS:
                   6902:                 
                   6903:                 if (stcmp (a, b) == 0) {
                   6904:                     a[0] = '1';
                   6905:                     goto notop;
                   6906:                 }
                   6907: 
                   6908:                 
                   6909:             case SORTSAFTER:
                   6910: 
                   6911:                 if (collate (b, a)) {
                   6912:                     *a = '1';
                   6913:                 }
                   6914:                 else {
                   6915:                     *a = '0';
                   6916:                 }
                   6917:                 
                   6918:                 goto notop;
                   6919: 
                   6920:                 
                   6921:             case MAXOP:
                   6922: 
                   6923: #ifdef NOSCRAMBL
                   6924:                 if (standard) {
                   6925:                     merr_raise (NOSTAND);
                   6926:                     return;
                   6927:                 }                
                   6928: #endif /* NOSCRAMBL */
                   6929:                 
                   6930:                 stcpy (tmp, b);
                   6931:                 numlit (tmp);
                   6932:                 numlit (a);
                   6933:                 
                   6934:                 if (comp (a, tmp)) stcpy (a, tmp);
                   6935:                 
                   6936:                 goto next05;
                   6937: 
                   6938:                 
                   6939:             case MINOP:
                   6940: 
                   6941: #ifdef NOSCRAMBL
                   6942:                 if (standard) {
                   6943:                     merr_raise (NOSTAND);
                   6944:                     return;
                   6945:                 }                
                   6946: #endif /* NOSCRAMBL */
                   6947: 
                   6948:                 stcpy (tmp, b);
                   6949:                 numlit (tmp);
                   6950:                 numlit (a);
                   6951:                 
                   6952:                 if (comp (a, tmp) == 0) stcpy (a, tmp);
                   6953:                 
                   6954:                 goto next05;
                   6955: 
                   6956:                 
                   6957:             default:
                   6958:                 merr_raise (ILLOP);
                   6959:                 return;
                   6960: 
                   6961:         }
                   6962:     }                   /* end binary operators */
                   6963: 
                   6964:     switch (f) {
                   6965: 
                   6966:         case INDIRECT:
                   6967: 
                   6968: 
                   6969: indirect:
                   6970: 
                   6971:             if (*++codptr == '@' && *(codptr + 1) == '(') {
                   6972: 
                   6973:                 if (a[stlen (a) - 1] == ')') {
                   6974:                     codptr += 2;
                   6975:                     a[stlen (a) - 1] = ',';
                   6976:                 }
                   6977:                 else {
                   6978:                     codptr++;
                   6979:                 }
                   6980: 
                   6981:             }
                   6982:             
                   6983:             stcpy (a + stlen (a), codptr);
                   6984:             stcpy (&code[1], a);
                   6985:             codptr = code;
                   6986:             *codptr = SP;
                   6987:             arg--;
                   6988:             
                   6989:             if (spx <= 0) {
                   6990:                 op_stck[0] = 0;
                   6991:                 codptr++;
                   6992: 
                   6993:                 goto nextchr;
                   6994:             }
                   6995:             
                   6996:             if ((op_stck[spx] & 0177) != PATTERN) goto text;
                   6997: 
                   6998:             a = argstck[arg];
                   6999:             goto scan_pattern;
                   7000: 
                   7001:             
                   7002:         case MINUS:         /* unary minus */
                   7003: 
                   7004:             b = a + stlen (a) + 1;
                   7005: 
                   7006:             while (b > a) {
                   7007:                 *b = *(b - 1);
                   7008:                 b--;
                   7009:             }
                   7010:             
                   7011:             *a = '-';
                   7012: 
                   7013:             
                   7014:         case PLUS:              /* unary plus */
                   7015: 
                   7016:             atyp = numlit (a);
                   7017:             
                   7018: #ifdef EUR2DEM
                   7019:             if (atyp) {
                   7020:                 stcat (a, WHR[atyp]);
                   7021:             }
                   7022: #endif /* EUR2DEM */
                   7023:             goto nxt_operator;
                   7024: 
                   7025:             
                   7026:         case NOT:               /* unary not */
                   7027: 
                   7028:             tvexpr (a);
                   7029:             toggle (*a);
                   7030:             
                   7031:             goto nxt_operator;
                   7032: 
                   7033:             
                   7034:         default:
                   7035:             merr_raise (MISSOPD);
                   7036:             return;
                   7037:             
                   7038:     }                   /* end unary operators */
                   7039: 
                   7040:     
                   7041: }                   /* end expr() */
                   7042: 
                   7043: 
                   7044: /******************************************************************************/
                   7045: /* $ZSYNTAX */
                   7046: /* a simple syntax check.                                    */
                   7047: /* $ZSYNTAX expects one argument. If it finds no fault, it   */
                   7048: /* returns an empty string. Otherwise it returns a pair of   */
                   7049: /* integers separated by a comma. The first number indicates */
                   7050: /* the position where the error has been found. The second   */
                   7051: /* number returns an error code (same meaning as in $ZE)     */
                   7052: /* only the most frequent errors are searched for:           */
                   7053: /* - illegal commands                                        */
                   7054: /* - not matching brackets                                   */
                   7055: /* - not matching quotes                                     */
                   7056: /* - missing or surplus arguments                            */
                   7057: /* - surplus commata                                         */
                   7058: 
                   7059: void zsyntax(char *a)
                   7060: {
                   7061:     register int i;
                   7062:     register int j;
                   7063:     register int f;
                   7064:     register int ch;
                   7065:     
                   7066:     char    tmp[256];
                   7067:     char   *b;
                   7068:     short   cmnd;
                   7069:     short   forline;            /* flag: FOR encountered */
                   7070: 
                   7071:     b = a;
                   7072:     forline = FALSE;
                   7073:     while ((ch = *b) == '.' || ch == SP)
                   7074:         b++;                /* level points for blockstr. */
                   7075:     while ((ch = *b++) != EOL) {    /* scan command */
                   7076:         if (ch == ';' || ch == '!')
                   7077:             break;          /* comment or unix_call */
                   7078:         if (ch >= 'A' && ch <= 'Z')
                   7079:             ch += 32;           /* uppercase to lowercase */
                   7080:         f = ch;
                   7081:         cmnd = f;
                   7082:         if (ch < 'b' || ch > 'z' || /* illegal char in cmmd position */
                   7083:             ch == 'm' || ch == 't' || ch == 'y') {
                   7084:             j = CMMND;
                   7085: 
                   7086:             
                   7087: zserr:
                   7088: 
                   7089:             intstr (a, b - a);
                   7090:             a[i = stlen (a)] = ',';
                   7091: 
                   7092:             merr_num_to_code (j, &a[++i]);
                   7093:             stcnv_c2m (a);
                   7094:             
                   7095:             return;
                   7096:         }
                   7097:         i = 1;
                   7098:         while (((tmp[++i] = ch = *b++) != EOL) &&   /* check full command name */
                   7099:                ((ch >= 'A' && ch <= 'Z') ||
                   7100:                 (ch >= 'a' && ch <= 'z')))
                   7101:             if (ch < 'a')
                   7102:                 tmp[i] = ch + 32;
                   7103:         if (f != 'z') {
                   7104:             if (i > 2) {
                   7105:                 tmp[0] = SP;
                   7106:                 tmp[1] = f;
                   7107:                 tmp[i] = SP;
                   7108:                 tmp[++i] = EOL;
                   7109:                 if (find (
                   7110:                         " break close do else for goto hang halt if job kill lock new open quit read set use view write xecute "
                   7111:                         ,tmp) == FALSE) {
                   7112:                     j = CMMND;
                   7113:                     goto zserr;
                   7114:                 }
                   7115:             }
                   7116:         }
                   7117:         i = 0;              /* quote */
                   7118:         j = 0;              /* bracket */
                   7119:         if (ch == ':') {        /*  scan postcond */
                   7120:             while ((ch = *b++) != EOL) {
                   7121:                 if (ch == '*' && *b == ch)
                   7122:                     b++;        /* exponentiation */
                   7123:                 if (ch == '!' && *b == ch)
                   7124:                     b++;                /* XOR */
                   7125:                 if (ch == ']') {
                   7126:                     if (*b == ch)
                   7127:                         b++;        /* SORTSAFTER */
                   7128:                     if (*b == '=')
                   7129:                         b++;        /* EQFOLLOWS or EQSORTS */
                   7130:                 }
                   7131:                 if (ch == '"') {
                   7132:                     toggle (i);
                   7133:                     continue;
                   7134:                 }
                   7135:                 if (i)
                   7136:                     continue;
                   7137:                 if (ch == SP)
                   7138:                     break;
                   7139:                 if (ch == '$') {
                   7140:                     ch = *b++;
                   7141:                     if (ch >= 'A' && ch <= 'Z')
                   7142:                         ch += 32;
                   7143:                     if ((ch < 'a' || ch > 'z' || ch == 'b' ||
                   7144:                          ch == 'm' || ch == 'u' || ch == 'w') && ch != '$') {
                   7145:                         j = ILLFUN;
                   7146:                         goto zserr;
                   7147:                     }
                   7148:                     if (ch == 's') {    /* $SELECT */
                   7149:                         int     xch,
                   7150:                             xi,
                   7151:                             xj;
                   7152:                         char   *xb;
                   7153:                         int     sfl;
                   7154:                         
                   7155:                         xi = 0;     /* quotes */
                   7156:                         xj = 0;     /* brackets */
                   7157:                         xb = b;     /* do not change old 'b' pointer */
                   7158:                         sfl = TRUE; /* first ':' expected */
                   7159:                         for (;;)
                   7160:                         {
                   7161:                             if ((xch = *xb++) == EOL ||
                   7162:                                 ((xch == SP || xch == ',') && xj == 0)) {
                   7163:                                 if (xj == 0)
                   7164:                                     break;  /* $STORAGE */
                   7165:                                 j = SELER;
                   7166:                                 b = xb;
                   7167:                                 goto zserr;
                   7168:                             }
                   7169:                             if (xch == '"') {
                   7170:                                 toggle (xi);
                   7171:                                 continue;
                   7172:                             }
                   7173:                             if (xi)
                   7174:                                 continue;
                   7175:                             if (xch == ':') {
                   7176:                                 if (xj > 1)
                   7177:                                     continue;
                   7178:                                 if (sfl) {
                   7179:                                     sfl = FALSE;
                   7180:                                     continue;
                   7181:                                 }
                   7182:                                 j = SELER;
                   7183:                                 b = xb;
                   7184:                                 goto zserr;
                   7185:                             }
                   7186:                             if (xch == ',') {
                   7187:                                 if (xj > 1)
                   7188:                                     continue;
                   7189:                                 if (!sfl) {
                   7190:                                     sfl = TRUE;
                   7191:                                     continue;
                   7192:                                 }
                   7193:                                 j = SELER;
                   7194:                                 b = xb;
                   7195:                                 goto zserr;
                   7196:                             }
                   7197:                             if (xch == '(') {
                   7198:                                 xj++;
                   7199:                                 continue;
                   7200:                             }
                   7201:                             if (xch == ')') {
                   7202:                                 if ((xj--) > 1)
                   7203:                                     continue;
                   7204:                                 if (sfl) {
                   7205:                                     j = SELER;
                   7206:                                     b = xb;
                   7207:                                     goto zserr;
                   7208:                                 }
                   7209:                                 break;
                   7210:                             }
                   7211:                         }
                   7212:                     }
                   7213: /* end select check */
                   7214:                     else if (ch == 'd' ||   /* $DATA */
                   7215:                              ch == 'g' ||    /* $GET */
                   7216:                              ch == 'o' ||    /* $ORDER */
                   7217:                              ch == 'n' ||    /* $NEXT */
                   7218:                              ch == 'q' ||    /* $QUERY */
                   7219:                              ch == 'i') {    /* $INCREMENT */
                   7220:                         int     xch,
                   7221:                             xi,
                   7222:                             xj;
                   7223:                         char   *xb;
                   7224:                         
                   7225:                         xb = b;     /* do not change old 'b' pointer */
                   7226: /* skip name */
                   7227:                         while (((xch = (*xb)) >= 'A' && xch <= 'Z') ||
                   7228:                                (xch >= 'a' && xch <= 'z'))
                   7229:                             xb++;
                   7230:                         if (xch == '(') {
                   7231:                             if ((xch = (*++xb)) == '^' || xch == '%' ||
                   7232:                                 (xch >= 'A' && xch <= 'Z') ||
                   7233:                                 (xch >= 'a' && xch <= 'z')) {
                   7234:                                 xi = xch;
                   7235:                                 if (xch == '^' && *(xb + 1) == '%')
                   7236:                                     xb++;
                   7237:                                 while
                   7238:                                     (((xch = (*++xb)) >= 'A' && xch <= 'Z') ||
                   7239:                                      (xch >= 'a' && xch <= 'z') ||
                   7240:                                      (xch >= '0' && xch <= '9') ||
                   7241:                                      (xch == '.') ||
                   7242:                                      (xch == '/' && xi <= '^') ||
                   7243:                                      (xch == '%' && *(xb - 1) == '/')) ;
                   7244:                             } else {
                   7245:                                 if (xch == '@')
                   7246:                                     continue;
                   7247:                                 j = INVEXPR;
                   7248:                                 b = xb;
                   7249:                                 goto zserr;
                   7250:                             }
                   7251:                             xi = 0; /* quotes */
                   7252:                             xj = 0; /* brackets */
                   7253:                             for (;;)
                   7254:                             {
                   7255:                                 xch = *xb++;
                   7256:                                 if (xch == '"' && xj) {
                   7257:                                     toggle (xi);
                   7258:                                     continue;
                   7259:                                 }
                   7260:                                 if (xi && (xch != EOL))
                   7261:                                     continue;
                   7262:                                 if (xch == '(') {
                   7263:                                     xj++;
                   7264:                                     continue;
                   7265:                                 }
                   7266:                                 if (xch == ')') {
                   7267:                                     if (xj-- > 0)
                   7268:                                         continue;
                   7269:                                     break;
                   7270:                                 }
                   7271:                                 if (xj && xch != EOL)
                   7272:                                     continue;
                   7273:                                 if (xch == ',' &&
                   7274:                                     (ch == 'g' || ch == 'q' || ch == 'o'))
                   7275:                                     break;
                   7276:                                 j = INVEXPR;
                   7277:                                 b = xb;
                   7278:                                 goto zserr;
                   7279:                             }
                   7280:                         }
                   7281:                     }           /* end data/order/query check */
                   7282:                     if (ch == 'e' ||    /* $EXTRACT */
                   7283:                         ch == 'p' ||    /* $PIECE */
                   7284:                         ch == 'a' ||    /* $ASCII */
                   7285:                         ch == 'g' ||    /* $GET */
                   7286:                         ch == 'j' ||    /* $JUSTIFY */
                   7287:                         ch == 'l' ||    /* $LENGTH */
                   7288:                         ch == 'r' ||    /* $RANDOM/REVERSE */
                   7289:                         ch == 't' ||    /* $TEXT/TRANSLATE */
                   7290:                         ch == 'f') {    /* $FIND/FNUMBER */
                   7291:                         int     xch,
                   7292:                             xi,
                   7293:                             xj,
                   7294:                             xa;
                   7295:                         char   *xb;
                   7296:                         
                   7297:                         xb = b;     /* do not change old 'b' pointer */
                   7298: /* skip name */
                   7299:                         while (((xch = (*xb)) >= 'A' && xch <= 'Z') ||
                   7300:                                (xch >= 'a' && xch <= 'z'))
                   7301:                             xb++;
                   7302:                         if (xch == '(') {
                   7303:                             xi = 0; /* quotes */
                   7304:                             xj = 0; /* brackets */
                   7305:                             xa = 1;
                   7306:                             for (;;)
                   7307:                             {
                   7308:                                 xch = (*++xb);
                   7309:                                 if (xch == EOL)
                   7310:                                     break;
                   7311:                                 if (xch == '"') {
                   7312:                                     toggle (xi);
                   7313:                                     continue;
                   7314:                                 }
                   7315:                                 if (xi)
                   7316:                                     continue;
                   7317:                                 if (xch == '(') {
                   7318:                                     xj++;
                   7319:                                     continue;
                   7320:                                 }
                   7321:                                 if (xch == ')') {
                   7322:                                     if (xj-- > 0)
                   7323:                                         continue;
                   7324:                                     break;
                   7325:                                 }
                   7326:                                 if (xj == 0 && xch == ',') {
                   7327:                                     xa++;
                   7328:                                     continue;
                   7329:                                 }
                   7330:                             }
                   7331:                             if ((ch == 'e' && (xa > 3)) ||  /* $EXTRACT */
                   7332:                                 (ch == 'p' && (xa < 2 || xa > 4)) ||    /* $PIECE */
                   7333:                                 (ch == 'a' && (xa > 2)) ||  /* $ASCII */
                   7334:                                 (ch == 'g' && (xa > 2)) ||  /* $GET */
                   7335:                                 (ch == 'j' && (xa < 2 || xa > 3)) ||    /* $JUSTIFY */
                   7336:                                 (ch == 'l' && (xa > 2)) ||  /* $LENGTH */
                   7337:                                 (ch == 'r' && (xa > 1)) ||  /* $RANDON/$REVERSE */
                   7338:                                 (ch == 't' && (xa > 3)) ||  /* $TEXT/TRANSLATE */
                   7339:                                 (ch == 'f' && (xa < 2 || xa > 3))) {    /* $FIND/FNUMBER */
                   7340:                                 j = FUNARG;
                   7341:                                 b = xb;
                   7342:                                 goto zserr;
                   7343:                             }
                   7344:                         }
                   7345:                     }           /* end number of args check */
                   7346:                     continue;
                   7347:                 }
                   7348:                 if (ch == '(') {
                   7349:                     j++;
                   7350:                     continue;
                   7351:                 }
                   7352:                 if (ch == ')') {
                   7353:                     if (j--)
                   7354:                         continue;
                   7355:                     break;
                   7356:                 }
                   7357:                 if (ch == ',') {
                   7358:                     if ((ch = *b) == SP || ch == EOL || ch == ',') {
                   7359:                         j = ARGLIST;
                   7360:                         goto zserr;
                   7361:                     }
                   7362:                 }
                   7363:             }
                   7364:             if (i)
                   7365:                 j = QUOTER;
                   7366:             else if (j)
                   7367:                 j = j < 0 ? INVEXPR : BRAER;
                   7368:             if (j == OK && ch != EOL && ch != SP)
                   7369:                 j = SPACER;
                   7370:             if (j)
                   7371:                 goto zserr;
                   7372:         }               /* end postcond */
                   7373:         if (ch == SP)
                   7374:             ch = *b;
                   7375:         else if (ch != EOL) {
                   7376:             j = SPACER;
                   7377:             goto zserr;
                   7378:         }
                   7379:         if ((ch == SP || ch == EOL) &&  /* never argumentless */
                   7380:             (f == 'j' || f == 'o' || f == 'r' ||
                   7381:              f == 's' || f == 'u' || f == 'x' ||
                   7382:              f == 'g')) {
                   7383:             j = ARGLIST;
                   7384:             goto zserr;
                   7385:         }
                   7386: /* or.. always argumentless */
                   7387:         if ((ch != SP && ch != EOL) && (f == 'e' || (f == 'q' && forline))) {
                   7388:             j = SPACER;
                   7389:             goto zserr;
                   7390:         }
                   7391:         if (f == 'f')
                   7392:             forline = TRUE;
                   7393:         if (ch == EOL)
                   7394:             break;
                   7395: /* scan argument */
                   7396:         i = 0;              /* quotes */
                   7397:         j = 0;              /* brackets */
                   7398:         ch = SP;            /* init: previous character */
                   7399:         for (;;)                /* scan argument */
                   7400:         {
                   7401:             f = ch;         /* f=previous character */
                   7402:             if ((ch = *b++) == EOL)
                   7403:                 break;
                   7404:             if (ch == '*' && *b == ch)
                   7405:                 b++;            /* exponentiation */
                   7406:             if (ch == '!' && *b == ch)
                   7407:                 b++;                /* XOR */
                   7408:             if (ch == ']') {
                   7409:                 if (*b == ch)
                   7410:                     b++;        /* SORTSAFTER */
                   7411:                 if (*b == '=')
                   7412:                     b++;        /* EQFOLLOWS or EQSORTS */
                   7413:             }
                   7414:             if (ch == '"') {
                   7415:                 toggle (i);
                   7416:                 continue;
                   7417:             }
                   7418:             if (i)
                   7419:                 continue;
                   7420:             if (ch == '$') {
                   7421:                 ch = *b++;
                   7422:                 if (ch >= 'A' && ch <= 'Z')
                   7423:                     ch += 32;
                   7424:                 if ((ch < 'a' || ch > 'z' || ch == 'b' ||
                   7425:                      ch == 'm' || ch == 'u' || ch == 'w') && ch != '$') {
                   7426:                     j = ILLFUN;
                   7427:                     goto zserr;
                   7428:                 }
                   7429:                 if (ch == 's') {    /* $SELECT */
                   7430:                     int     xch,
                   7431:                         xi,
                   7432:                         xj;
                   7433:                     char   *xb;
                   7434:                     int     sfl;
                   7435:                     
                   7436:                     xi = 0;     /* quotes */
                   7437:                     xj = 0;     /* brackets */
                   7438:                     xb = b;     /* do not change old 'b' pointer */
                   7439:                     sfl = TRUE;     /* first ':' expected */
                   7440:                     for (;;)
                   7441:                     {
                   7442:                         if ((xch = *xb++) == EOL ||
                   7443:                             ((xch == SP || xch == ',') && xj == 0)) {
                   7444:                             if (xj == 0)
                   7445:                                 break;  /* $STORAGE */
                   7446:                             j = SELER;
                   7447:                             b = xb;
                   7448:                             goto zserr;
                   7449:                         }
                   7450:                         if (xch == '"') {
                   7451:                             toggle (xi);
                   7452:                             continue;
                   7453:                         }
                   7454:                         if (xi)
                   7455:                             continue;
                   7456:                         if (xch == ':') {
                   7457:                             if (xj > 1)
                   7458:                                 continue;
                   7459:                             if (sfl) {
                   7460:                                 sfl = FALSE;
                   7461:                                 continue;
                   7462:                             }
                   7463:                             j = SELER;
                   7464:                             b = xb;
                   7465:                             goto zserr;
                   7466:                         }
                   7467:                         if (xch == ',') {
                   7468:                             if (xj > 1)
                   7469:                                 continue;
                   7470:                             if (!sfl) {
                   7471:                                 sfl = TRUE;
                   7472:                                 continue;
                   7473:                             }
                   7474:                             j = SELER;
                   7475:                             b = xb;
                   7476:                             goto zserr;
                   7477:                         }
                   7478:                         if (xch == '(') {
                   7479:                             xj++;
                   7480:                             continue;
                   7481:                         }
                   7482:                         if (xch == ')') {
                   7483:                             if ((xj--) > 1)
                   7484:                                 continue;
                   7485:                             if (sfl) {
                   7486:                                 j = SELER;
                   7487:                                 b = xb;
                   7488:                                 goto zserr;
                   7489:                             }
                   7490:                             break;
                   7491:                         }
                   7492:                     }
                   7493:                 }
                   7494: /* end select check */
                   7495:                 else if (ch == 'd' ||   /* $DATA */
                   7496:                          ch == 'g' ||    /* $GET */
                   7497:                          ch == 'o' ||    /* $ORDER */
                   7498:                          ch == 'n' ||    /* $NEXT */
                   7499:                          ch == 'q') {    /* $QUERY */
                   7500:                     int     xch,
                   7501:                         xi,
                   7502:                         xj;
                   7503:                     char   *xb;
                   7504:                     
                   7505:                     xb = b;     /* do not change old 'b' pointer */
                   7506: /* skip name */
                   7507:                     while (((xch = (*xb)) >= 'A' && xch <= 'Z') ||
                   7508:                            (xch >= 'a' && xch <= 'z'))
                   7509:                         xb++;
                   7510:                     if (xch == '(') {
                   7511:                         if ((xch = (*++xb)) == '^' || xch == '%' ||
                   7512:                             (xch >= 'A' && xch <= 'Z') ||
                   7513:                             (xch >= 'a' && xch <= 'z')) {
                   7514:                             xi = xch;
                   7515:                             if (xch == '^' && *(xb + 1) == '%')
                   7516:                                 xb++;
                   7517:                             while
                   7518:                                 (((xch = (*++xb)) >= 'A' && xch <= 'Z') ||
                   7519:                                  (xch >= 'a' && xch <= 'z') ||
                   7520:                                  (xch >= '0' && xch <= '9') ||
                   7521:                                  (xch == '.') ||
                   7522:                                  (xch == '/' && xi <= '^') ||
                   7523:                                  (xch == '%' && *(xb - 1) == '/')) ;
                   7524:                             
                   7525:                         } else {
                   7526:                             if (xch == '@')
                   7527:                                 continue;
                   7528:                             j = INVEXPR;
                   7529:                             b = xb;
                   7530:                             goto zserr;
                   7531:                         }
                   7532:                         xi = 0;     /* quotes */
                   7533:                         xj = 0;     /* brackets */
                   7534:                         for (;;)
                   7535:                         {
                   7536:                             xch = *xb++;
                   7537:                             if (xch == '"' && xj) {
                   7538:                                 toggle (xi);
                   7539:                                 continue;
                   7540:                             }
                   7541:                             if (xi && (xch != EOL))
                   7542:                                 continue;
                   7543:                             if (xch == '(') {
                   7544:                                 xj++;
                   7545:                                 continue;
                   7546:                             }
                   7547:                             if (xch == ')') {
                   7548:                                 if (xj-- > 0)
                   7549:                                     continue;
                   7550:                                 break;
                   7551:                             }
                   7552:                             if (xj && xch != EOL)
                   7553:                                 continue;
                   7554:                             if (xch == ',' &&
                   7555:                                 (ch == 'g' || ch == 'q' || ch == 'o'))
                   7556:                                 break;
                   7557:                             j = INVEXPR;
                   7558:                             b = xb;
                   7559:                             goto zserr;
                   7560:                         }
                   7561:                     }
                   7562:                 }           /* end data/order/query check */
                   7563:                 if (ch == 'e' ||    /* $EXTRACT */
                   7564:                     ch == 'p' ||    /* $PIECE */
                   7565:                     ch == 'a' ||    /* $ASCII */
                   7566:                     ch == 'g' ||    /* $GET */
                   7567:                     ch == 'j' ||    /* $JUSTIFY */
                   7568:                     ch == 'l' ||    /* $LENGTH */
                   7569:                     ch == 'r' ||    /* $RANDON/$REVERSE */
                   7570:                     ch == 't' ||    /* $TEXT/TRANSLATE */
                   7571:                     ch == 'f') {    /* $FIND/FNUMBER */
                   7572:                     int     xch,
                   7573:                         xi,
                   7574:                         xj,
                   7575:                         xa;
                   7576:                     char   *xb;
                   7577:                     
                   7578:                     xb = b;     /* do not change old 'b' pointer */
                   7579: /* skip name */
                   7580:                     while (((xch = (*xb)) >= 'A' && xch <= 'Z') ||
                   7581:                            (xch >= 'a' && xch <= 'z'))
                   7582:                         xb++;
                   7583:                     if (xch == '(') {
                   7584:                         xi = 0;     /* quotes */
                   7585:                         xj = 0;     /* brackets */
                   7586:                         xa = 1;
                   7587:                         for (;;)
                   7588:                         {
                   7589:                             xch = (*++xb);
                   7590:                             if (xch == EOL)
                   7591:                                 break;
                   7592:                             if (xch == '"') {
                   7593:                                 toggle (xi);
                   7594:                                 continue;
                   7595:                             }
                   7596:                             if (xi)
                   7597:                                 continue;
                   7598:                             if (xch == '(') {
                   7599:                                 xj++;
                   7600:                                 continue;
                   7601:                             }
                   7602:                             if (xch == ')') {
                   7603:                                 if (xj-- > 0)
                   7604:                                     continue;
                   7605:                                 break;
                   7606:                             }
                   7607:                             if (xj == 0 && xch == ',') {
                   7608:                                 xa++;
                   7609:                                 continue;
                   7610:                             }
                   7611:                         }
                   7612:                         if ((ch == 'e' && (xa > 3)) ||  /* $EXTRACT */
                   7613:                             (ch == 'p' && (xa < 2 || xa > 4)) ||    /* $PIECE */
                   7614:                             (ch == 'a' && (xa > 2)) ||  /* $ASCII */
                   7615:                             (ch == 'o' && (xa > 2)) ||  /* $ORDER */
                   7616:                             (ch == 'q' && (xa > 2)) ||  /* $QUERY */
                   7617:                             (ch == 'g' && (xa > 2)) ||  /* $GET */
                   7618:                             (ch == 'j' && (xa < 2 || xa > 3)) ||    /* $JUSTIFY */
                   7619:                             (ch == 'l' && (xa > 2)) ||  /* $LENGTH */
                   7620:                             (ch == 't' && (xa > 3)) ||  /* $TEXT/TRANSLATE */
                   7621:                             (ch == 'f' && (xa < 2 || xa > 3))) {    /* $FIND/FNUMBER */
                   7622:                             j = FUNARG;
                   7623:                             b = xb;
                   7624:                             goto zserr;
                   7625:                         }
                   7626:                     }
                   7627:                 }           /* end number of args check */
                   7628:                 continue;
                   7629:             }
                   7630:             if (ch == '(') {
                   7631:                 if (f == ')' || f == '"') {
                   7632:                     j = ARGLIST;
                   7633:                     goto zserr;
                   7634:                 }
                   7635:                 j++;
                   7636:                 continue;
                   7637:             }
                   7638:             if (ch == ')') {
                   7639:                 tmp[0] = f;
                   7640:                 tmp[1] = EOL;
                   7641:                 if (find (" !#&'(*+,-/:<=>?@[\\]_\201", tmp)) {
                   7642:                     j = MISSOPD;
                   7643:                     goto zserr;
                   7644:                 }
                   7645:                 if (j--)
                   7646:                     continue;
                   7647:                 break;
                   7648:             }
                   7649:             if (ch == SP)
                   7650:                 break;
                   7651:             tmp[0] = ch;
                   7652:             tmp[1] = EOL;
                   7653:             if (ch == '/' && (cmnd == 'r' || cmnd == 'w') && (f == SP || f == ',')) {
                   7654:                 int     xch,
                   7655:                     xi,
                   7656:                     xj;
                   7657:                 char   *xb;
                   7658:                 
                   7659:                 xi = 0;         /* quotes */
                   7660:                 xj = 0;         /* brackets */
                   7661:                 xb = b;         /* do not change old 'b' pointer */
                   7662:                 while ((xch = *xb++) != EOL) {
                   7663:                     if (xch == '"') {
                   7664:                         toggle (xi);
                   7665:                         continue;
                   7666:                     }
                   7667:                     if (xi)
                   7668:                         continue;
                   7669:                     if (xch == '(') {
                   7670:                         xj++;
                   7671:                         continue;
                   7672:                     }
                   7673:                     if (xch == ')') {
                   7674:                         if ((xj--) > 1)
                   7675:                             continue;
                   7676:                         xch = *xb++;
                   7677:                         break;
                   7678:                     }
                   7679:                     if (xj)
                   7680:                         continue;
                   7681:                     if ((xch < 'A' || xch > 'Z') &&
                   7682:                         (xch < '1' || xch > '3'))
                   7683:                         break;
                   7684:                 }
                   7685:                 if (xch != ',' && xch != SP && xch != EOL) {
                   7686:                     b = xb;
                   7687:                     j = SPACER;
                   7688:                     goto zserr;
                   7689:                 }
                   7690:                 if (--xb == b) {
                   7691:                     j = ARGLIST;
                   7692:                     goto zserr;
                   7693:                 }
                   7694:             }
                   7695:             if (f == '?' && cmnd != 'r' && cmnd != 'w' &&
                   7696:                 find ("@1234567890.\201", tmp) == 0) {  /* pattern match */
                   7697:                 j = MISSOPD;
                   7698:                 goto zserr;
                   7699:             }
                   7700: /* note: write/read may have !?*#/ not as binary op */
                   7701:             if (find ("&<=>[\\]_\201", tmp) ||  /* binary operator */
                   7702:                 (find ("!?*#/\201", tmp) && cmnd != 'r' && cmnd != 'w'))
                   7703: /* some may be negated */
                   7704:             {
                   7705:                 if (find ("#*/\\_\201", tmp) || f != NOT) {
                   7706:                     tmp[0] = f;
                   7707:                     if (find (" &'(+-<=>[\\]_\201", tmp) ||
                   7708:                         (find ("!?*#/\201", tmp) && cmnd != 'r' && cmnd != 'w')) {
                   7709:                         j = MISSOPD;
                   7710:                         goto zserr;
                   7711:                     }
                   7712:                 }
                   7713:                 continue;
                   7714:             }
                   7715:             if (ch == '+' || ch == '-') {
                   7716:                 if (f == NOT) {
                   7717:                     j = MISSOPD;
                   7718:                     goto zserr;
                   7719:                 }
                   7720:                 continue;
                   7721:             }
                   7722:             if (ch == ':') {
                   7723:                 if (f == ',') {
                   7724:                     j = MISSOPD;
                   7725:                     goto zserr;
                   7726:                 }
                   7727:                 continue;
                   7728:             }
                   7729:             if (ch == '`' || ch == ';' || ch == '{' || ch == '|' ||
                   7730:                 ch == '}' || ch == '~') {   /* illegal characters */
                   7731:                 j = ILLOP;
                   7732:                 goto zserr;
                   7733:             }
                   7734:             if (ch == '$') {        /* check function */
                   7735:                 if (((f = *b | 0140) < 'a' || f > 'z') && f != '$') {
                   7736:                     j = ILLFUN;
                   7737:                     goto zserr;
                   7738:                 }
                   7739:                 continue;
                   7740:             }
                   7741:             if (ch == ',') {        /* comma is a delimiter! */
                   7742:                 if (*(b - 2) == SP || (f = *b) == SP || f == EOL || f == ',') {
                   7743:                     j = ARGLIST;
                   7744:                     goto zserr;
                   7745:                 }
                   7746:             }
                   7747:         }
                   7748:         if (i)
                   7749:             j = QUOTER;
                   7750:         else if (j)
                   7751:             j = j > 0 ? INVEXPR : BRAER;
                   7752:         if (j)
                   7753:             goto zserr;
                   7754:         if (ch == EOL)
                   7755:             break;
                   7756: /* skip spaces before next command */
                   7757:         while (ch == SP || ch == TAB)
                   7758:             ch = *b++;
                   7759:         b--;
                   7760:     }
                   7761:     *a = EOL;               /* no error found */
                   7762:     return;
                   7763: }                   /* end zsyntax() */
                   7764: 
                   7765: time_t horolog_to_unix (char *horo)
                   7766: {
                   7767:     
                   7768:     char *ptr = horo;
                   7769:     register char ch;
                   7770:     register short i;
                   7771:     
                   7772:     char horo_days[10];
                   7773:     char horo_seconds[10];
                   7774: 
                   7775:     time_t seconds;
                   7776: 
                   7777:     i = 0;
                   7778:     
                   7779:     while ((ch = *(ptr++)) != ',') {
                   7780:         horo_days[i++] = ch;
                   7781:     }
                   7782:     horo_days[i] = '\0';
                   7783: 
                   7784:     i = 0;
                   7785:     while ((ch = *(ptr++)) != EOL) {
                   7786:         horo_seconds[i++] = ch;
                   7787:     }
                   7788:     horo_seconds[i] = '\0';
                   7789: 
                   7790:     seconds = (((atol (horo_days) - 47117L) * 86400L) + 43200 + atol (horo_seconds) + tzoffset);
                   7791: 
                   7792:     return (time_t) seconds;
                   7793:     
                   7794: }
                   7795: 
                   7796: 
                   7797: /* a    = result string
                   7798:  * type = type of transform
                   7799:  */
                   7800: void zkey (char *a, long type)
                   7801: {
                   7802: 
                   7803:     char del0;
                   7804:     char del1;
                   7805:     char del2;
                   7806:     char del3;
                   7807:     char del4;
                   7808: 
                   7809:     int f;
                   7810:     char prod_rule[256];
                   7811:     int i;
                   7812:     int ncs;            /* flag: non_collating_substring */
                   7813: 
                   7814:     if (type == 0) type = (-v93);          /* zero is reverse of default type */
                   7815:     if ((f = (type < 0))) type = (-type);
                   7816:     
                   7817:     if (type-- > NO_V93) {
                   7818:         merr_raise (ARGER);
                   7819:         return;
                   7820:     }
                   7821:     
                   7822:     del2 = v93a[type][0];       /* delimiter between primary/seconary key */
                   7823:     del0 = v93a[type][1];       /* delimiter between 'from' and 'to' substring */
                   7824:     del3 = '(';             /* introducer for 'non-collating' substrings */
                   7825:     del4 = ')';             /* terminator for 'non-collating' substring */
                   7826:     ncs = FALSE;            /* non_collating_substring flag */
                   7827: 
                   7828:     if (del0 == EOL) return;             /* no rule under of this type */
                   7829: 
                   7830:     del1 = v93a[type][2];       /* delimiter between different from/to pairs */
                   7831: /* production rule, stripped from delimiter declaration */
                   7832: /* with an added separator character at both ends */
                   7833: 
                   7834:     i = stcpy (prod_rule, &v93a[type][2]);
                   7835:     prod_rule[i] = del1;
                   7836:     prod_rule[++i] = EOL;
                   7837: 
                   7838:     if (f) goto backw;         /* negative is backward transform */
                   7839:     
                   7840: /* forward transform */
                   7841:     i = stlen (a);
                   7842: 
                   7843:     if (i == 0) return;             /* string empty - nothing to do */
                   7844:     
                   7845:     {
                   7846:         char ct0[256];
                   7847:         char ct1[256];
                   7848:         int ch = 0;
                   7849:         int d = 0;
                   7850:         int i1 = 0;
                   7851:         int j = 0;
                   7852:         int n0 = 0;
                   7853:         int n1 = 0;
                   7854:         int pos = 0;
                   7855:         char c;
                   7856:         
                   7857:         i = 0;
                   7858:         n0 = 0;
                   7859:         n1 = 0;
                   7860:         
                   7861:         while ((c = a[i]) != EOL) { /* non-collating substring? */
                   7862: 
                   7863:             if (c == del3) {        /* introducer valid only with matching terminator! */
                   7864: 
                   7865:                 j = i;
                   7866: 
                   7867:                 while ((ch = a[++j]) != EOL) {
                   7868:                     if (ch == del4) break;
                   7869:                 }
                   7870:                 
                   7871:                 if (ch == del4) {
                   7872: 
                   7873:                     while (i <= j) ct1[n1++] = a[i++];
                   7874:                     continue;
                   7875:                     
                   7876:                 }
                   7877:                 
                   7878:             }
                   7879:             
                   7880:             j = 0;
                   7881:             d = 0;
                   7882:             
                   7883: /* search for longest matching string */
                   7884:             while ((ch = prod_rule[j++]) != EOL) {
                   7885: 
                   7886:                 if (ch == del1) {
                   7887:                     
                   7888:                     if (prod_rule[j] != c) continue;
                   7889:                     
                   7890:                     i1 = i;
                   7891: 
                   7892:                     while ((ch = prod_rule[j++]) != del0 && ch == a[i1++]) ;
                   7893: 
                   7894:                     if (ch != del0) continue;
                   7895:                     
                   7896:                     if ((ch = i1 - i) > d) {
                   7897:                         d = ch;
                   7898:                         pos = j;
                   7899:                     }
                   7900:                     
                   7901:                 }
                   7902:                 
                   7903:             }
                   7904:             
                   7905:             if (n0 > STRLEN) {
                   7906:                 merr_raise (M75);
                   7907:                 return;
                   7908:             }               /* string too long */
                   7909:             
                   7910:             if (d == 0) {
                   7911: 
                   7912:                 ct0[n0++] = c;
                   7913:                 ct1[n1++] = '0';
                   7914:                 i++;
                   7915: 
                   7916:                 continue;
                   7917:                 
                   7918:             }
                   7919:             
                   7920:             j = 0;
                   7921:             c = prod_rule[pos];
                   7922:             ch = '0';
                   7923: 
                   7924:             if (c == del1) {
                   7925:                 
                   7926:                 ct1[n1++] = ' ';
                   7927:                 
                   7928:                 while (j <= pos) {
                   7929: 
                   7930:                     if (prod_rule[j] == del0) ch++;
                   7931: 
                   7932:                     j++;
                   7933:                     
                   7934:                 }
                   7935:                 
                   7936:             }
                   7937:             else {
                   7938: 
                   7939:                 while (j <= pos) {
                   7940: 
                   7941:                     if (prod_rule[j] == del0 && prod_rule[j + 1] == c) ch++;
                   7942:                     
                   7943:                     j++;
                   7944:                     
                   7945:                 }
                   7946:                 
                   7947:             }
                   7948:             
                   7949:             j = 0;
                   7950:             i += d;
                   7951:             ct1[n1++] = ch;
                   7952: 
                   7953:             while ((ct0[n0++] = prod_rule[pos++]) != del1) {
                   7954: 
                   7955:                 if (n1 > STRLEN) {
                   7956:                     merr_raise (M75);
                   7957:                     return;
                   7958:                 }           /* string too long */
                   7959:                 
                   7960:             }
                   7961:             
                   7962:             n0--;
                   7963:             
                   7964:         }
                   7965:         
                   7966:         ct0[n0++] = del2;
                   7967:         ct0[n0] = EOL;
                   7968:         ct1[n1] = EOL;
                   7969: 
                   7970: /* purge trailing zeroes */
                   7971:         while (ct1[--n1] == '0') {
                   7972: 
                   7973:             ct1[n1] = EOL;
                   7974: 
                   7975:             if (n1 == 0) {
                   7976:                 n0--;
                   7977:                 break;
                   7978:             }
                   7979:             
                   7980:         }
                   7981:         
                   7982:         if (n0 + n1 > STRLEN) {
                   7983:             merr_raise (M75);
                   7984:             return;
                   7985:         }               /* string too long */
                   7986:         
                   7987:         stcpy (a, ct0);
                   7988:         stcpy (&a[n0], ct1);
                   7989:         
                   7990:     }
                   7991:     
                   7992:     return;
                   7993: 
                   7994:     
                   7995: /* backward transform */
                   7996: backw:
                   7997: 
                   7998:     i = stlen (a);
                   7999: 
                   8000:     if (i == 0) return;             /* string empty */
                   8001:     
                   8002:     {
                   8003:         int c;
                   8004:         int ch;
                   8005:         int d;
                   8006:         int n0;
                   8007:         int n1;
                   8008:         int n2;
                   8009:         int j;
                   8010:         char z[256];
                   8011:         
                   8012:         stcpy (z, a);
                   8013:         n0 = 0;
                   8014:         n1 = 0;
                   8015:         n2 = 0;
                   8016:         
                   8017:         while ((d = z[n1++]) != EOL && (d != del2)) ;
                   8018: 
                   8019:         if (d == EOL) return;         /* nothing to change */
                   8020: 
                   8021:         for (;;) {
                   8022:             
                   8023:             c = z[n0];
                   8024:             d = z[n1];
                   8025: 
                   8026:             if (c == del2 && d == EOL) break;
                   8027: 
                   8028:             if (d == EOL) {
                   8029:                 d = '0';
                   8030:             }
                   8031:             else {
                   8032:                 n1++;
                   8033:             }
                   8034: 
                   8035:             
                   8036:             if (d == del3) {
                   8037: 
                   8038:                 a[n2++] = d;
                   8039:                 ncs = TRUE;
                   8040:                 
                   8041:                 continue;
                   8042:                 
                   8043:             }
                   8044: 
                   8045:             if (ncs) {
                   8046: 
                   8047:                 a[n2++] = d;
                   8048:                 
                   8049:                 if (d == del4) ncs = FALSE;
                   8050:                 
                   8051:                 continue;
                   8052:                 
                   8053:             }
                   8054:             
                   8055:             if (d == ' ') {     /* replacement with no chars */
                   8056: 
                   8057:                 d = z[n1++] - '0';
                   8058:                 j = 1;
                   8059: 
                   8060:                 while ((ch = prod_rule[j++]) != EOL) {
                   8061:                     if (ch == del0 && (--d) == 0) break;
                   8062:                 }
                   8063:                 
                   8064:             }
                   8065:             else {
                   8066: 
                   8067:                 if ((d -= '0') == 0) {
                   8068: 
                   8069:                     a[n2++] = c;
                   8070:                     n0++;
                   8071: 
                   8072:                     continue;
                   8073:                     
                   8074:                 }
                   8075:                 
                   8076:                 j = 1;
                   8077: 
                   8078:                 while ((ch = prod_rule[j++]) != EOL) {
                   8079:                     if (ch == del0 && prod_rule[j] == c && (--d) == 0) break;
                   8080:                 }
                   8081:                 
                   8082:             }
                   8083:             
                   8084:             d = j;
                   8085: 
                   8086:             while ((ch = prod_rule[j++]) != EOL) {
                   8087: 
                   8088:                 if (ch == del1) break;
                   8089:                 
                   8090:                 n0++;
                   8091:                 
                   8092:             }
                   8093:             
                   8094:             d--;
                   8095: 
                   8096:             while (prod_rule[d--] != del1) ;
                   8097: 
                   8098:             if (prod_rule[d + 2] == EOL) {
                   8099:                 merr_raise (ARGER);
                   8100:                 return;
                   8101:             }               /* string is not of proper format */
                   8102: 
                   8103:             d++;
                   8104: 
                   8105:             while ((ch = prod_rule[++d]) != del0) a[n2++] = ch;
                   8106:             
                   8107:         }
                   8108:         
                   8109:         a[n2] = EOL;
                   8110:         
                   8111:     }
                   8112:     
                   8113:     return;
                   8114: }                   /* end zkey() */
                   8115: 
                   8116: int levenshtein (char *word1, char *word2)
                   8117: {
                   8118:     int l1 = 0;
                   8119:     int l2 = 0;
                   8120:     int i = 0;
                   8121:     int j = 0;
                   8122:     int m = 0;
                   8123:     int t = 0;
                   8124:     int x = 0;
                   8125:     char    d[2][256];
                   8126: 
                   8127:     l1 = stlen (word1);
                   8128:     word1--;
                   8129:     
                   8130:     l2 = stlen (word2);
                   8131:     word2--;
                   8132:     
                   8133:     if (l1 == 0) return (l2);
                   8134:     if (l2 == 0) return (l1);
                   8135:     
                   8136:     t = 0;
                   8137: 
                   8138:     for (i = 0; i <= l1; i++) d[0][i] = i;
                   8139:     
                   8140:     for (j = 1; j <= l2; j++) {
                   8141: 
                   8142:         t ^= 1;
                   8143:         d[t][0] = j;
                   8144: 
                   8145:         for (i = 1; i <= l1; i++) {
                   8146: 
                   8147:             m = d[t ^ 1][i - 1];
                   8148:             if (word1[i] != word2[j]) m++;
                   8149: 
                   8150:             x = d[t ^ 1][i];
                   8151:             if (++x < m) m = x;
                   8152: 
                   8153:             x = d[t][i - 1];
                   8154:             if (++x < m) m = x;
                   8155: 
                   8156:             d[t][i] = m;
                   8157:             
                   8158:         }
                   8159:         
                   8160:     }
                   8161:     
                   8162:     return (m);
                   8163: }
                   8164: 
                   8165: /* conditional rounding */
                   8166: /* 'a' is assumed to be a 'canonic' numeric string           */
                   8167: /* it is rounded to 'digits' fractional digits provided that */
                   8168: /* the canonic result has at most (digits-2) frac.digits     */
                   8169: void cond_round (char *a, int digits)
                   8170: {
                   8171:     int ch;
                   8172:     int i;
                   8173:     int point;
                   8174:     int lena;
                   8175: 
                   8176:     point = -1;
                   8177: 
                   8178:     i = 0;
                   8179:     i = 0;
                   8180: 
                   8181:     while (a[i] != EOL) {
                   8182: 
                   8183:         if (a[i] == '.') point = i;
                   8184:         i++;
                   8185:         
                   8186:     }
                   8187:     
                   8188:     lena = i;
                   8189: 
                   8190:     if (point < 0) point = i;
                   8191:     if ((point + digits + 1) >= i) return;             /* nothing to round */
                   8192:     
                   8193:     i = point + digits + 1;
                   8194: 
                   8195:     if (a[i] < '5') {
                   8196: 
                   8197:         if ((a[i - 1] != '0') || (a[i - 2] != '0')) return;         /* condition! */
                   8198:         
                   8199:         a[i] = EOL;
                   8200: 
                   8201:         while (a[--i] == '0') a[i] = EOL;
                   8202:         
                   8203:         if (a[i] == '.') {
                   8204: 
                   8205:             a[i] = EOL;
                   8206: 
                   8207:             if (i == 0 || (i == 1 && a[0] == '-')) a[0] = '0';
                   8208:             
                   8209:         }
                   8210:         
                   8211:         return;
                   8212:         
                   8213:     }
                   8214:     
                   8215:     if (a[i - 1] != '9' || a[i - 2] != '9') return;             /* condition */
                   8216:     
                   8217:     for (;;) {
                   8218:         
                   8219:         if (i >= point) {
                   8220:             a[i] = EOL;
                   8221:         }
                   8222:         else {
                   8223:             a[i] = '0';
                   8224:         }
                   8225:         
                   8226:         if (--i < (a[0] == '-')) {
                   8227: 
                   8228:             for (i = lena; i >= 0; i--) a[i + 1] = a[i];
                   8229: 
                   8230:             a[a[0] == '-'] = '1';
                   8231: 
                   8232:             break;
                   8233:             
                   8234:         }
                   8235:         
                   8236:         if ((ch = a[i]) == '.') continue;
                   8237:         
                   8238:         if (a[i] < '9' && ch >= '0') {
                   8239:             a[i] = ++ch;
                   8240:             break;
                   8241:         }
                   8242:         
                   8243:     }
                   8244: 
                   8245:     return;
                   8246:     
                   8247: }                   /* end cond_round */
                   8248: 
                   8249: short is_horolog(char *s)
                   8250: {
                   8251:     
                   8252:     register int i;
                   8253:     char ch;
                   8254:     int commata = 0;
                   8255:     int digits = 0;   
                   8256: 
                   8257:     if (!isdigit (s[0])) return FALSE;
                   8258: 
                   8259:     for (i = 0; i < stlen (s); i++) {
                   8260: 
                   8261:         ch = s[i];
                   8262: 
                   8263:         if (isdigit (ch)) {
                   8264:             digits++;
                   8265:         }
                   8266:         else if (ch == ',' && commata == 0) {
                   8267:             commata++;
                   8268:         }
                   8269:         else if (ch == ',' && commata > 0) {
                   8270:             return FALSE;         
                   8271:         }
                   8272:         else {
                   8273:             return FALSE;
                   8274:         }
                   8275: 
                   8276:     }
                   8277: 
                   8278:     if (commata != 1) {
                   8279:         return FALSE;
                   8280:     }
                   8281:     else {
                   8282:         return TRUE;
                   8283:     }
                   8284:     
                   8285: }

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