File:  [Coherent Logic Development] / freem / src / views.c
Revision 1.9: download - view: text, annotated - select for diffs
Wed Jan 7 19:51:33 2026 UTC (2 months, 3 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Fix segfault in reverse $QUERY

    1: /*
    2:  *   $Id: views.c,v 1.9 2026/01/07 19:51:33 snw Exp $
    3:  *    implementation of VIEW command and $VIEW intrinsic function
    4:  *
    5:  *  
    6:  *   Author: Serena Willis <snw@coherent-logic.com>
    7:  *    Copyright (C) 1998 MUG Deutschland
    8:  *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
    9:  *
   10:  *
   11:  *   This file is part of FreeM.
   12:  *
   13:  *   FreeM is free software: you can redistribute it and/or modify
   14:  *   it under the terms of the GNU Affero Public License as published by
   15:  *   the Free Software Foundation, either version 3 of the License, or
   16:  *   (at your option) any later version.
   17:  *
   18:  *   FreeM is distributed in the hope that it will be useful,
   19:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   20:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21:  *   GNU Affero Public License for more details.
   22:  *
   23:  *   You should have received a copy of the GNU Affero Public License
   24:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
   25:  *
   26:  *   $Log: views.c,v $
   27:  *   Revision 1.9  2026/01/07 19:51:33  snw
   28:  *   Fix segfault in reverse $QUERY
   29:  *
   30:  *   Revision 1.8  2025/04/09 19:52:02  snw
   31:  *   Eliminate as many warnings as possible while building with -Wall
   32:  *
   33:  *   Revision 1.7  2025/04/02 03:02:42  snw
   34:  *   Stop requiring users to pass -e to fmadm when -u or -g are passed
   35:  *
   36:  *   Revision 1.6  2025/03/09 19:50:47  snw
   37:  *   Second phase of REUSE compliance and header reformat
   38:  *
   39:  *
   40:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
   41:  * SPDX-License-Identifier: AGPL-3.0-or-later
   42:  **/
   43: 
   44: #include <stdlib.h>
   45: 
   46: #include "mpsdef.h"
   47: #include "mwapi_window.h"
   48: 
   49: #define LOCK        'l'
   50: 
   51: /* system services */
   52: 
   53: #include <signal.h>
   54: 
   55: #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__linux__)
   56: #include <sys/ioctl.h>
   57: #endif
   58: 
   59: 
   60: #if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(EMSCRIPTEN)
   61: # if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__AMIGA)
   62: #  include <termios.h>
   63: #  if !defined(__AMIGA)
   64: #   define TCGETA TIOCGETA
   65: #   define TCSETA TIOCSETA
   66: #  endif
   67: #  define termio termios
   68: # else
   69: #  if !defined(MSDOS) && !defined(__linux__)
   70: #    include <termio.h>
   71: #  else
   72: #    include <termios.h>
   73: #    define termio termios
   74: #  endif
   75: # endif
   76: #else
   77: # include <termios.h>
   78: #endif
   79: 
   80: 
   81: #ifdef __CYGWIN__
   82: #include <errno.h>
   83: #endif /* __CYGWIN__ */
   84: #include <errno.h> /* snw */
   85: 
   86: 
   87: #include <fcntl.h>
   88: #include <unistd.h>
   89: #include <time.h>
   90: #include <string.h>
   91: #include <stdio.h>
   92: #include "shmmgr.h"
   93: 
   94: /* 01/18/99 rlf Apparently, tell disappeared with libc-6 */
   95: #if defined(LINUX_GLIBC) || defined(__APPLE__)
   96: 
   97: long int tell (int fd)
   98: {
   99:     return lseek (fd, 0, SEEK_CUR);
  100: }
  101: 
  102: #else
  103: long int tell ();
  104: #endif					/* LINUX_GLIBC */
  105: 
  106: 
  107: #if defined(MWAPI_GTK)
  108: void destroy(GtkWidget* widget, gpointer data)
  109: {
  110:     gtk_main_quit();
  111: }
  112: #endif
  113: 
  114: 
  115: void view_com (void)
  116: {
  117:     /* process VIEW command */
  118: 
  119:     int arg1;
  120:     register long int i;
  121:     register long int j;
  122:     register long int ch;
  123: 
  124:     if (*codptr == SP || *codptr == EOL) {	/* no argument form of VIEW */
  125:         merr_raise (ARGER);
  126:         return;
  127:     }
  128:     
  129:     expr (STRING);
  130:     
  131:     arg1 = intexpr (argptr);
  132:     
  133:     if (merr () > OK) return;
  134:     
  135:     if (*codptr == ':') {
  136:         
  137:         codptr++;
  138: 	
  139:         expr (STRING);
  140: 	
  141:         if (merr () > OK) return;
  142: 	
  143:         switch (arg1) {			
  144:             
  145:             
  146:             /* VIEW 52: G0 input translation table */
  147:             case 52:
  148:                 
  149:                 stcpy0 (G0I[io], argptr, 256L);
  150: 		
  151:                 for (i = 0; i < 256; i++) {
  152:                     
  153:                     if (G0I[io][i] == EOL) {
  154:                         
  155:                         while (i < 256) {
  156:                             G0I[io][i] = (char) i;
  157:                             i++;
  158:                         } 
  159:                         
  160:                         break;					
  161:                     }
  162:                     
  163:                 }
  164:                 
  165:                 break;
  166:                 
  167:                 
  168:                 /* VIEW 53: G0 output translation table */
  169:             case 53:
  170:                 
  171:                 stcpy0 (G0O[io], argptr, 256L);
  172: 		
  173:                 for (i = 0; i < 256; i++) {
  174:                     
  175:                     if (G0O[io][i] == EOL) {
  176:                         
  177:                         while (i < 256) {
  178:                             G0O[io][i] = (char) i;
  179:                             i++;
  180:                         } 
  181:                         
  182:                         break;
  183:                     }
  184:                     
  185:                 }
  186:                 
  187:                 break;
  188:                 
  189:                 
  190:                 /* VIEW 54: G1 input translation table */
  191:             case 54:
  192:                 
  193:                 stcpy0 (G1I[io], argptr, 256L);
  194:                 
  195:                 for (i = 0; i < 256; i++) {
  196:                     
  197:                     if (G1I[io][i] == EOL) {
  198:                         
  199:                         while (i < 256) {
  200:                             G1I[io][i] = (char) i;
  201:                             i++;
  202:                         }
  203:                         
  204:                         break;
  205:                         
  206:                     }
  207:                     
  208:                 }
  209:                 
  210:                 break;
  211:                 
  212:                 
  213:                 /* VIEW 55: G1 output translation table */
  214:             case 55:
  215:                 
  216:                 stcpy0 (G1O[io], argptr, 256L);
  217: 		
  218:                 for (i = 0; i < 256; i++) {
  219:                     
  220:                     if (G1O[io][i] == EOL) {
  221:                         
  222:                         while (i < 256) {
  223:                             G1O[io][i] = (char) i;
  224:                             i++;
  225:                         } 
  226:                         
  227:                         break;
  228:                         
  229:                     }
  230:                     
  231:                 }
  232:                 
  233:                 break;
  234:                 
  235:                 
  236:                 /* VIEW 62: random: seed number */
  237:             case 62:
  238:                 
  239:                 i = intexpr (argptr);
  240: 		
  241:                 if (merr () == MXNUM) return;
  242:                 
  243:                 if (i < 0) {
  244:                     merr_raise (ARGER);
  245:                 }
  246:                 else {
  247:                     nrandom = i;
  248:                 }
  249:                 
  250:                 break;
  251:                 
  252:                 
  253:                 /* VIEW 63: random: parameter a */
  254:             case 63:
  255:                 
  256:                 i = intexpr (argptr);
  257:                 
  258:                 if (merr () == MXNUM) return;
  259:                 
  260:                 if (i <= 0) {
  261:                     merr_raise (ARGER);
  262:                 }
  263:                 else {
  264:                     ran_a = i;
  265:                 }
  266:                 
  267:                 break;
  268:                 
  269:                 
  270:                 /* VIEW 64: random: parameter b */
  271:             case 64:
  272:                 
  273:                 i = intexpr (argptr);
  274: 		
  275:                 if (merr () == MXNUM) return;
  276:                 
  277:                 if (i < 0) {
  278:                     merr_raise (ARGER);
  279:                 }
  280:                 else {
  281:                     ran_b = i;
  282:                 }
  283:                 
  284:                 break;
  285:                 
  286:                 
  287:                 /* VIEW 65: random: parameter c */
  288:             case 65:
  289:                 
  290:                 i = intexpr (argptr);
  291: 		
  292:                 if (merr () == MXNUM) return;
  293: 		
  294:                 if (i <= 0) {
  295:                     merr_raise (ARGER);
  296:                 }
  297:                 else {
  298:                     ran_c = i;
  299:                 }
  300: 		
  301:                 break;
  302: 		
  303:                 
  304:                 /* VIEW 66: SIGTERM handling flag */
  305:             case 66:
  306:                 
  307:                 killerflag = tvexpr (argptr);
  308: 		
  309:                 break;
  310:                 
  311:                 
  312:                 /* VIEW 67: SIGHUP handling flag */
  313:             case 67:
  314:                 
  315:                 huperflag = tvexpr (argptr);
  316: 		
  317:                 break;
  318: 		
  319:                 
  320:                 /* ... reserved ... */
  321:                 
  322:                 /* VIEW 70: ZSORT/ZSYNTAX flag */
  323:             case 70:
  324:                 
  325:                 s_fun_flag = tvexpr (argptr);
  326: 		
  327:                 break;
  328: 		
  329:                 
  330:                 /* VIEW 71: ZNEXT/ZNAME flag */
  331:             case 71:
  332:                 
  333:                 n_fun_flag = tvexpr (argptr);
  334: 		
  335:                 break;
  336: 		
  337:                 
  338:                 /* VIEW 72: ZPREVIOUS/ZPIECE flag */
  339:             case 72:
  340:                 
  341:                 p_fun_flag = tvexpr (argptr);
  342: 		
  343:                 break;
  344: 		
  345:                 
  346:                 /* VIEW 73: ZDATA/ZDATE flag */
  347:             case 73:
  348:                 
  349:                 d_fun_flag = tvexpr (argptr);
  350: 		
  351:                 break;
  352:                 
  353:                 
  354:                 /* VIEW 79: old ZJOB vs. new ZJOB flag */
  355:             case 79:
  356:                 
  357:                 zjobflag = tvexpr (argptr);
  358: 		
  359:                 break;
  360:                 
  361:                 
  362:                 /* VIEW 80: 7 vs. 8 bit flag */
  363:             case 80:
  364:                 
  365:                 eightbit = tvexpr (argptr);
  366: 		
  367:                 break;
  368:                 
  369:                 
  370:                 /* VIEW 81: PF1 flag */
  371:             case 81:
  372:                 
  373:                 PF1flag = tvexpr (argptr);
  374: 		
  375:                 break;
  376:                 
  377:                 
  378:                 /* VIEW 82: not used */
  379:                 /* VIEW 83: text in $ZE flag */
  380:             case 83:
  381:                 
  382:                 etxtflag = tvexpr (argptr);
  383: 		
  384:                 break;
  385: 		
  386:                 
  387:                 /* VIEW 84: not used */
  388:                 /* VIEW 85: not used */
  389:                 /* VIEW 86: not used */
  390:                 
  391:             case 87:			/* VIEW 87: date type definition */
  392:                 
  393:                 i = intexpr (argptr);
  394: 		
  395:                 if (i < 0 || i >= NO_DATETYPE) {
  396:                     merr_raise (ARGER);
  397:                     return;
  398:                 }
  399:                 
  400:                 if (*codptr != ':') {
  401:                     datetype = i;
  402:                     break;
  403:                 }
  404:                 
  405:                 if (i == 0) {
  406:                     merr_raise (ARGER);
  407:                     return;
  408:                 }
  409:                 
  410:                 codptr++;
  411: 		
  412:                 expr (STRING);
  413: 		
  414:                 j = intexpr (argptr);
  415: 		
  416:                 if (*codptr != ':') {
  417:                     merr_raise (ARGER);
  418:                     return;
  419:                 }
  420:                 
  421:                 codptr++;
  422: 		
  423:                 expr (STRING);
  424: 		
  425:                 if (j > 0 && j < 15 && stlen (argptr) > MONTH_LEN) {
  426:                     merr_raise (M75);
  427:                 }
  428:                 else if (j > 0 && j < 13) {
  429:                     stcpy (month[i][j - 1], argptr);
  430:                 }
  431:                 else if (j == 13) {
  432:                     stcpy (dat1char[i], argptr);
  433:                 }
  434:                 else if (j == 14) {
  435:                     stcpy (dat2char[i], argptr);
  436:                 }
  437:                 else if (j == 15) {
  438:                     dat3char[i] = (*argptr);
  439:                 }
  440:                 else if (j == 16) {
  441: 					
  442:                     if ((j = intexpr (argptr)) < 0 || j > 2) {
  443:                         merr_raise (ARGER);
  444:                         return;
  445:                     }
  446: 
  447:                     dat4flag[i] = j;
  448: 
  449:                 } 
  450:                 else if (j == 17) {
  451:                     dat5flag[i] = tvexpr (argptr);
  452:                 }
  453:                 else if (j == 18) {
  454:                     if ((j = intexpr (argptr) + 672411L) <= 0L) {
  455:                         merr_raise (ARGER);
  456:                         return;
  457:                     }
  458:                     datGRbeg[i] = j;
  459:                 } 
  460:                 else {
  461:                     merr_raise (ARGER);
  462:                 }
  463: 
  464:                 if (merr () > OK) return;
  465: 
  466:                 break;
  467: 
  468: 
  469:             case 88:			/* VIEW 88: time type definition */
  470: 				
  471:                 i = intexpr (argptr);
  472: 				
  473:                 if (i < 0 || i >= NO_TIMETYPE) {
  474:                     merr_raise (ARGER);
  475:                     return;
  476:                 }
  477: 				
  478:                 if (*codptr != ':') {
  479:                     timetype = i;
  480:                     break;
  481:                 }
  482: 				
  483:                 codptr++;
  484: 				
  485:                 expr (STRING);
  486: 				
  487:                 j = intexpr (argptr);
  488: 				
  489:                 if (*codptr != ':') {
  490:                     merr_raise (ARGER);
  491:                     return;
  492:                 }
  493: 				
  494:                 codptr++;
  495: 				
  496:                 expr (STRING);
  497: 				
  498:                 if (j == 1) {
  499:                     tim1char[i] = (*argptr);
  500:                 }
  501:                 else if (j == 2) {
  502:                     tim2char[i] = (*argptr);
  503:                 }
  504:                 else if (j == 3) {
  505:                     tim3char[i] = (*argptr);
  506:                 }
  507:                 else if (j == 4) {
  508:                     tim4flag[i] = tvexpr (argptr);
  509:                 }
  510:                 else if (j == 5) {
  511:                     tim5flag[i] = tvexpr (argptr);
  512:                 }
  513:                 else {
  514:                     merr_raise (ARGER);
  515:                 }
  516: 				
  517:                 if (merr () > OK) return;
  518: 				
  519:                 break;
  520: 
  521: 
  522:             case 91:			/* VIEW 91: missing QUIT expr default expression */
  523: 				
  524:                 stcpy (exfdefault, argptr);
  525: 				
  526:                 break;
  527: 
  528: 
  529:             case 92:			/* VIEW 92: EUR2DEM: type mismatch error */
  530: 				
  531:                 typemmflag = tvexpr (argptr);
  532: 				
  533:                 break;
  534: 
  535: 
  536:             case 93:			/* VIEW 93: zkey production rule definition */
  537: 
  538:                 i = intexpr (argptr);
  539: 				
  540:                 if (i < 1 || i > NO_V93) {
  541:                     merr_raise (ARGER);
  542:                     return;
  543:                 }
  544: 				
  545:                 if (*codptr != ':') {
  546:                     v93 = i;
  547:                     break;
  548:                 }
  549: 				
  550:                 codptr++;
  551: 				
  552:                 expr (STRING);
  553: 				
  554:                 stcpy (v93a[i - 1], argptr);
  555: 				
  556:                 break;
  557: 
  558: 
  559:             case 96:			/* VIEW 96: global prefix */
  560: 				
  561:                 if (stlen (argptr) > MONTH_LEN)  {
  562:                     merr_raise (M75);
  563:                 }
  564:                 else {
  565:                     stcpy (glo_prefix, argptr);
  566:                 }
  567: 				
  568:                 break;
  569: 
  570: 
  571:             case 97:			/* VIEW 97: global postfix */
  572: 
  573:                 if (stlen (argptr) > MONTH_LEN) {
  574:                     merr_raise (M75);
  575:                 }
  576:                 else {
  577:                     stcpy (glo_ext, argptr);
  578:                 }
  579: 				
  580:                 break;
  581: 
  582: 
  583:             case 98:			/* VIEW 98: routine extension */
  584: 
  585:                 if (stlen (argptr) > MONTH_LEN) {
  586:                     merr_raise (M75);
  587:                 }
  588:                 else {
  589:                     stcpy (rou_ext, argptr);
  590:                 }
  591: 
  592:                 break;
  593: 
  594: 
  595:             case 101:			/* VIEW 101: set ierr */
  596: 
  597:                 merr_raise (intexpr (argptr));
  598: 
  599:                 break;
  600: 
  601:             case 102:			/* VIEW 102 set deferred_ierr */
  602: 
  603:                 deferred_ierr = intexpr (argptr);
  604: 
  605:                 break;
  606: 
  607:                                 
  608:             case 103:                       /* MERGE to ^$WINDOW complete. Parameter is empty (for all windows) or string for window name in subscript 1 */
  609: #if defined(MWAPI_GTK)                            
  610:                 mwapi_on_merge_complete (argptr);
  611: #endif                            
  612:                 break;
  613: 
  614: 
  615: 	
  616: #if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(__AMIGA) && !defined(EMSCRIPTEN) && !defined(MSDOS)
  617: 
  618:             case 113:			/* VIEW 113: set termio infos */
  619:             {
  620: 					
  621:                 struct termio tpara;
  622: 
  623:                 i = intexpr (argptr);
  624: 					
  625:                 if (i < 1 || i > MAXDEV) {
  626:                     merr_raise (NODEVICE);
  627:                 }
  628:                 else if (devopen[i] == 0) {
  629:                     merr_raise (NOPEN);
  630:                 }
  631:                 else if (*codptr != ':') {
  632:                     merr_raise (ARGER);
  633:                 }
  634:                 else {
  635: 						
  636:                     codptr++;
  637: 						
  638:                     expr (STRING);
  639: 
  640:                     j = intexpr (argptr);
  641: 
  642:                 }
  643: 
  644:                 if (merr () > OK) return;
  645: 
  646:                 ioctl (fileno (opnfile[i]), TCGETA, &tpara);
  647: 					
  648:                 j = 0;
  649: 					
  650:                 tpara.c_iflag = intexpr (argptr);
  651: 					
  652:                 while ((ch = argptr[j]) != EOL) {
  653: 
  654:                     j++;
  655: 						
  656:                     if (ch == ':') break;
  657: 
  658:                 }
  659: 
  660:                 tpara.c_oflag = intexpr (&argptr[j]);
  661: 					
  662:                 while ((ch = argptr[j]) != EOL) {
  663: 						
  664:                     j++;
  665: 						
  666:                     if (ch == ':') break;
  667: 
  668:                 }
  669: 
  670:                 tpara.c_cflag = intexpr (&argptr[j]);
  671: 					
  672:                 while ((ch = argptr[j]) != EOL) {
  673: 					
  674:                     j++;
  675: 					
  676:                     if (ch == ':') break;
  677: 
  678:                 }
  679: 
  680:                 tpara.c_lflag = intexpr (&argptr[j]);
  681: 					
  682:                 ioctl (fileno (opnfile[i]), TCSETA, &tpara);
  683: 					
  684:                 return;
  685: 
  686:             }
  687: 
  688: #endif /* __APPLE__ */				
  689: 
  690: 
  691:             /* VIEW 133: remember ZLOAD directory on ZSAVE */
  692:             case 133:
  693: 				
  694:                 zsavestrategy = tvexpr (argptr);
  695: 
  696:                 return;
  697: 			
  698: 
  699:             default:
  700: 
  701:                 merr_raise (ARGER);
  702:                 return;
  703: 
  704:         }				/* end switch one parameter VIEWs */
  705:     } 
  706:     else {				/* no parameters VIEWs */
  707: 		
  708:         switch (arg1) {
  709: 
  710: 			
  711:             /* VIEW 21: close all globals */
  712:             case 21:
  713: 				
  714:                 close_all_globals ();
  715: 				
  716:                 return;
  717: 
  718: 
  719: 
  720:                 /* VIEW 29: symtab copy */
  721:             case 29:			/* get space if needed */
  722: 
  723:                 if (apartition == NULL) apartition = calloc ((unsigned) (PSIZE + 1), 1);
  724: 				
  725:                 for (i = 0; i <= PSIZE; i++) apartition[i] = partition[i];
  726: 				
  727:                 asymlen = symlen;
  728: 				
  729:                 for (i = 0; i < 128; i++) aalphptr[i] = alphptr[i];
  730: 				
  731:                 return;
  732: 
  733:         }
  734: 
  735:         merr_raise (ARGER);
  736:         return;
  737: 
  738:     }
  739: 
  740:     return;
  741: }					/* end view_com() */
  742: 
  743: /*
  744:  * f = number of arguments
  745:  * a = the arguments
  746:  */
  747: void view_fun (int f, char *a)				/* process VIEW function */
  748: {
  749:     int i;
  750: 
  751:     if (standard) {
  752:         merr_raise (NOSTAND);
  753:         return;
  754:     }					/* non_standard */
  755: 
  756:     if (f == 1) {
  757: 
  758:         f = intexpr (a);
  759: 		
  760:         switch (f) {
  761: 
  762:             /* $V(21) returns size of last global */
  763:             case 21:
  764: 
  765:                 if (oldfil[inuse][0] != NUL) {
  766: 				
  767:                     lseek (olddes[inuse], 0L, 2);
  768:                     lintstr (a, (long) tell (olddes[inuse]));
  769: 				
  770:                 } 
  771:                 else {
  772:                     *a = EOL;
  773:                 }
  774: 
  775:                 break;
  776: 
  777: 
  778:                 /* $V(22): number of v22_aliases */
  779:             case 22:
  780: 
  781:                 i = 0;
  782:                 f = 0;
  783: 		
  784:                 while (f < v22ptr) {
  785:                     i++;
  786:                     f += UNSIGN (v22ali[f]) + 1;
  787:                 }
  788: 
  789:                 intstr (a, i);
  790: 				
  791:                 break;
  792: 
  793: 
  794:                 /* $V(23): contents of 'input buffer' */
  795:             case 23:
  796: 
  797:                 stcpy (a, ug_buf[io]);
  798:                 break;
  799: 			
  800: 
  801:                 /* $V(24)/$V(25) number of screen lines */
  802:             case 24:
  803:             case 25:
  804: 					
  805:                 intstr (a, N_LINES);
  806:                 break;
  807: 
  808: 
  809:                 /* $V(26): DO-FOR-XEC stack pointer */
  810:             case 26:
  811: 				
  812:                 intstr (a, nstx);
  813:                 break;
  814: 			
  815: 
  816:                 /* $V(27): DO-FOR-XEC stack pointer (copy on error) */
  817:             case 27:
  818: 				
  819:                 intstr (a, nesterr);
  820:                 break;
  821: 			
  822: 
  823:                 /* $V(30): number of mumps arguments */
  824:             case 30:
  825: 			
  826:                 intstr (a, m_argc);
  827:                 break;
  828: 			
  829: 
  830:                 /* $V(31): environment variables */
  831:             case 31:
  832: 				
  833:                 f = 0;
  834: 				
  835:                 while (m_envp[f] && m_envp[f][0] != NUL) f++;
  836: 
  837:                 intstr (a, f);
  838:                 break;                                			
  839: 			
  840: 
  841:                 /* $V(52): G0 input translation table */
  842:             case 52:
  843: 				
  844:                 stcpy0 (a, G0I[io], 257L);
  845:                 a[255] = EOL;
  846:                 break;
  847: 			
  848: 
  849:                 /* $V(53): G0 output translation table */
  850:             case 53:
  851: 				
  852:                 stcpy0 (a, G0O[io], 257L);
  853:                 a[255] = EOL;
  854: 				
  855:                 break;
  856: 			
  857: 
  858:                 /* $V(54): G1 input translation table */
  859:             case 54:
  860: 				
  861:                 stcpy0 (a, G1I[io], 257L);
  862:                 a[255] = EOL;
  863: 				
  864:                 break;
  865: 			
  866: 
  867:                 /* $V(55): G1 output translation table */
  868:             case 55:
  869: 				
  870:                 stcpy0 (a, G1O[io], 257L);
  871:                 a[255] = EOL;
  872: 				
  873:                 break;
  874: 			
  875: 
  876:                 /* $V(60): partial pattern match flag */
  877:             case 60:
  878: 				
  879:                 intstr (a, pattrnflag);
  880:                 break;
  881: 			
  882: 
  883:                 /* $V(61): partial pattern supplement character */
  884:             case 61:
  885: 				
  886:                 a[0] = pattrnchar;
  887:                 a[1] = EOL;
  888: 				
  889:                 break;
  890: 			
  891: 
  892:                 /* $V(62): random: seed number */
  893:             case 62:
  894: 				
  895:                 lintstr (a, nrandom);
  896:                 break;
  897: 
  898: 
  899:                 /* $V(63): random: parameter a */
  900:             case 63:
  901: 				
  902:                 lintstr (a, ran_a);
  903:                 break;
  904: 
  905: 
  906:                 /* $V(64): random: parameter b */
  907:             case 64:
  908: 				
  909:                 lintstr (a, ran_b);
  910:                 break;
  911: 
  912: 
  913:                 /* $V(65): random: parameter c */
  914:             case 65:
  915: 				
  916:                 lintstr (a, ran_c);
  917:                 break;
  918: 
  919: 
  920:                 /* $V(66): SIGTERM handling flag */
  921:             case 66:
  922: 				
  923:                 intstr (a, killerflag);
  924:                 break;
  925: 
  926: 
  927:                 /* $V(67): SIGHUP handling flag */
  928:             case 67:
  929: 				
  930:                 intstr (a, huperflag);
  931:                 break;
  932: 
  933: 
  934:                 /* ... reserved ... */
  935: 
  936: 
  937:                 /* $V(70): ZSORT/ZSYNTAX flag */
  938:             case 70:
  939: 				
  940:                 intstr (a, s_fun_flag);
  941:                 break;
  942: 
  943: 
  944:                 /* $V(71): ZNEXT/ZNAME flag */
  945:             case 71:
  946: 				
  947:                 intstr (a, n_fun_flag);
  948:                 break;
  949: 
  950: 
  951:                 /* $V(72): ZPREVIOUS/ZPIECE flag */
  952:             case 72:
  953: 				
  954:                 intstr (a, p_fun_flag);
  955:                 break;
  956: 
  957: 
  958:                 /* $V(73): ZDATA/ZDATE flag */
  959:             case 73:
  960: 				
  961:                 intstr (a, d_fun_flag);
  962:                 break;
  963: 
  964: 
  965:                 /* ... reserved ... */
  966: 
  967: 
  968:                 /* $V(79): old ZJOB vs. new ZJOB flag */
  969:             case 79:
  970: 				
  971:                 intstr (a, zjobflag);
  972:                 break;
  973: 
  974: 
  975:                 /* $V(80): 7 vs. 8 bit flag */
  976:             case 80:
  977: 				
  978:                 intstr (a, eightbit);
  979:                 break;
  980: 
  981: 
  982:                 /* $V(81): PF1 flag */
  983:             case 81:
  984: 				
  985:                 intstr (a, PF1flag);
  986:                 break;
  987: 			
  988: 
  989:                 /* $V(82): order counter */
  990:             case 82:
  991: 				
  992:                 intstr (a, ordercounter);
  993:                 break;
  994: 			
  995: 
  996:                 /* $V(83): text in $ZE flag */
  997:             case 83:
  998: 				
  999:                 intstr (a, etxtflag);
 1000:                 break;
 1001: 				
 1002: 
 1003:                 /* $V(84): path of current routine */
 1004:             case 84:			/* look whether we know where the routine came from */
 1005: 				
 1006:                 for (i = 0; i < NO_OF_RBUF; i++) {
 1007: 					
 1008:                     int j;
 1009: 
 1010:                     if (pgms[i][0] == 0) {
 1011:                         *a = EOL;
 1012:                         return;
 1013:                     }			/* buffer empty */
 1014: 					
 1015:                     j = 0;
 1016: 					
 1017:                     while (rou_name[j] == pgms[i][j]) {
 1018: 						
 1019:                         if (rou_name[j++] == EOL) {
 1020: 
 1021:                             stcpy (a, path[i]);
 1022:                             i = stlen (a);
 1023: 							
 1024:                             if (i > 0) a[i - 1] = EOL;
 1025: 
 1026:                             return;
 1027: 
 1028:                         }
 1029: 
 1030:                     }
 1031: 
 1032:                 }
 1033: 
 1034:                 *a = EOL;
 1035: 				
 1036:                 break;			/* not found */
 1037: 			
 1038: 
 1039:                 /* $V(85): path of last global     */
 1040:             case 85:
 1041: 				
 1042:                 if (oldfil[inuse][0]) {
 1043:                     stcpy (a, oldfil[inuse]);
 1044:                 }
 1045:                 else {
 1046:                     *a = EOL;
 1047:                 }
 1048: 				
 1049:                 i = 0;
 1050: 				
 1051:                 while (a[i] != EOL) {
 1052: 					
 1053:                     if (a[i] == '^') {
 1054: 					
 1055:                         if (i > 0) {
 1056:                             i--;
 1057:                         }
 1058: 						
 1059:                         a[i] = EOL;
 1060: 						
 1061:                         break;
 1062: 
 1063:                     }
 1064: 
 1065:                     i++;
 1066: 
 1067:                 }
 1068: 
 1069:                 break;
 1070: 			
 1071: 
 1072:                 /* $V(86): path of current device  */
 1073:             case 86:
 1074: 				
 1075:                 stcpy (a, act_oucpath[io]);
 1076:                 break;
 1077: 			
 1078: 
 1079:                 /* $V(87): date type definitions */
 1080:             case 87:
 1081: 				
 1082:                 intstr (a, datetype);
 1083:                 break;
 1084: 			
 1085: 
 1086:                 /* $V(88): date type definitions */
 1087:             case 88:
 1088: 				
 1089:                 intstr (a, timetype);
 1090:                 break;
 1091: 						
 1092: 
 1093:                 /* $V(91): missig QUIT expr default expression */
 1094:             case 91:
 1095: 				
 1096:                 stcpy (a, exfdefault);
 1097:                 break;
 1098: 			
 1099: 
 1100:                 /* $V(92): type mismatch error */
 1101:             case 92:
 1102: 				
 1103:                 intstr (a, typemmflag);
 1104:                 break;
 1105: 			
 1106: 
 1107:                 /* $V(93): zkey production default rule definition */
 1108:             case 93:
 1109: 				
 1110:                 lintstr (a, v93);
 1111:                 break;
 1112: 			
 1113: 
 1114:                 /* $V(98): routine extention */
 1115:             case 98:
 1116: 				
 1117:                 stcpy (a, rou_ext);
 1118:                 break;		       			
 1119: 
 1120:                 /* $V(100): exit status of last kill */
 1121:             case 100:
 1122: 				
 1123:                 intstr (a, v100);
 1124:                 break;						
 1125: 
 1126:                 /* $V(114): Number of rows in terminal */
 1127:             case 114:
 1128: 				
 1129:                 intstr (a, n_lines);
 1130:                 break;
 1131: 			
 1132: 
 1133:                 /* $V(115): Number of columns in terminal */
 1134:             case 115:
 1135: 				
 1136:                 intstr (a, n_columns);
 1137:                 break;
 1138: 			
 1139: 
 1140:                 /* $V(133): remember ZLOAD directory on ZSAVE */
 1141:             case 133:
 1142: 				
 1143:                 intstr (a, zsavestrategy);
 1144:                 break;
 1145: 
 1146: 
 1147:             default:
 1148: 				
 1149:                 merr_raise (ARGER);
 1150:                 return;
 1151: 
 1152:         }
 1153: 
 1154:         return;
 1155:     }
 1156: 
 1157:     if (f == 2) {
 1158: 		
 1159:         char tmp[256];
 1160: 
 1161:         stcpy (tmp, argstck[arg + 1]);
 1162: 		
 1163:         i = intexpr (argstck[arg + 1]);
 1164:         f = intexpr (a);
 1165: 		
 1166:         if (merr () == MXNUM) return;
 1167: 
 1168:         if (f == 16) {
 1169: 
 1170:             if (i <= OK || i >= MAXERR) {
 1171:                 merr_raise (ARGER);
 1172:                 return;
 1173:             } 
 1174:             else {
 1175:                 stcpy (a, errmes[i]);
 1176:             }
 1177: 
 1178:         } 
 1179:         else if (f == 22) {		/* return v22_alias entry */
 1180: 
 1181:             if (i) {			/* give one of the names which are aliases */
 1182: 			
 1183:                 f = 0;
 1184: 			
 1185:                 while (f < v22ptr) {
 1186: 
 1187:                     i--;
 1188: 					
 1189:                     if (i == 0) {					
 1190:                         stcpy (a, &v22ali[f + 1]);
 1191:                         return;
 1192:                     }
 1193: 
 1194:                     f += UNSIGN (v22ali[f]) + 1;
 1195: 
 1196:                 }
 1197: 
 1198:                 a[0] = EOL;
 1199: 				
 1200:                 return;			/* that number had no entry in the table */
 1201: 			
 1202:             }
 1203: 			
 1204:             if (tstglvn (tmp) == FALSE) {
 1205:                 merr_raise (INVREF);
 1206:                 return;
 1207:             }
 1208: 			
 1209:             if (v22ptr) {		/* there are aliases */
 1210: 				
 1211:                 int k, j;
 1212: 
 1213:                 i = 0;
 1214: 				
 1215:                 while (i < v22ptr) {
 1216: 
 1217:                     k = i + UNSIGN (v22ali[i]) + 1;
 1218:                     j = 0;		/* is current reference an alias ??? */
 1219: 					
 1220:                     while (v22ali[++i] == tmp[j]) {
 1221: 
 1222:                         if (v22ali[i] == EOL) break;
 1223: 						
 1224:                         j++;
 1225: 
 1226:                     }
 1227: 
 1228:                     /* yes, it is, return it */
 1229:                     if (v22ali[i] == EOL && tmp[j] == EOL) {
 1230:                         stcpy (a, &v22ali[i + 1]);
 1231:                         return;
 1232:                     }
 1233: 
 1234:                     i = k;
 1235: 
 1236:                 }
 1237: 
 1238:             }
 1239: 
 1240:             a[0] = EOL;			/* entry was not in the table */
 1241: 			
 1242:             return;
 1243: 
 1244:         } 
 1245:         else if (f == 24) {		/* return screen line */
 1246: 
 1247:             if (i < -N_LINES || i > N_LINES || i == 0) {
 1248:                 *a = EOL;
 1249:             }
 1250:             else if (i < 0) {
 1251: 				
 1252:                 stcpy0 (a, (*screen).screena[(unsigned int) (*screen).sclines[-i - 1]], (long) N_COLUMNS);			
 1253:                 a[80] = EOL;
 1254: 
 1255:                 return;
 1256: 
 1257:             } 
 1258:             else {
 1259: 				
 1260:                 stcpy0 (a, (*screen).screenx[(unsigned int) (*screen).sclines[i - 1]], (long) N_COLUMNS);
 1261:                 a[80] = EOL;
 1262: 				
 1263:                 return;
 1264: 
 1265:             }
 1266:         } 
 1267:         else if (f == 25) {		/* return screen line with attribute */
 1268: 
 1269:             i--;
 1270: 			
 1271:             if (i < 0 || i >= N_LINES) {
 1272:                 *a = EOL;
 1273:             }
 1274:             else {
 1275:                 v25 (a, i);
 1276:             }
 1277: 
 1278:             return;
 1279: 
 1280:         } 
 1281:         else if (f == 26) {		/* $V(26) returns DO-FOR-XEC stack pointer */
 1282: 			
 1283:             if (i < 1 || i > nstx) {
 1284:                 merr_raise (ARGER);
 1285:                 return;
 1286:             }
 1287: 
 1288:             getraddress (a, i);
 1289: 			
 1290:             return;
 1291: 
 1292:         }		/* $V(27) returns DO-FOR-XEC stack pointer(error state) */
 1293:         else if (f == 27) {
 1294: 
 1295:             if (i < 1 || i > nesterr) {
 1296:                 merr_raise (ARGER);
 1297:                 return;
 1298:             }
 1299: 			
 1300:             stcpy (a, callerr[i]);
 1301: 			
 1302:             return;
 1303: 
 1304:         } 
 1305:         else if (f == 30) {		/* $V(30): arguments of mumps */
 1306: 
 1307:             if (i < 1 || i > m_argc) {
 1308:                 merr_raise (ARGER);
 1309:                 return;
 1310:             }
 1311: 		
 1312:             strcpy (a, m_argv[i - 1]);
 1313:             a[strlen (a)] = EOL;
 1314: 		
 1315:             return;
 1316: 
 1317:             /* guard against very long environment name=value entries */
 1318:         } 
 1319:         else if (f == 31) { /* $V(31): environment variables */
 1320: 			
 1321:             f = 0;
 1322: 			
 1323:             while (m_envp[f] && m_envp[f++][0] != NUL) {
 1324: 				
 1325:                 if (f != i) continue;
 1326: 
 1327:                 if ((f = strlen (m_envp[i - 1])) > STRLEN) {
 1328:                     merr_raise (M75);
 1329:                     return; 
 1330:                 }
 1331: 
 1332:                 strcpy (a, m_envp[i - 1]);
 1333:                 a[f] = EOL;		
 1334: 				
 1335:                 return;
 1336: 
 1337:             }
 1338: 
 1339:             merr_raise (ARGER);
 1340:             return;
 1341: 
 1342:         } 
 1343:         else if (f == 93) { /* $V(93): zkey production rule definition */
 1344: 			
 1345:             if (i <= 0 || i > NO_V93) {
 1346:                 merr_raise (ARGER);
 1347:             }
 1348:             else {
 1349:                 strcpy (a, v93a[i - 1]);
 1350:             }
 1351: 			
 1352:             return;
 1353: 
 1354:         } 
 1355: #if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(__AMIGA) && !defined(EMSCRIPTEN) && !defined(MSDOS)
 1356:         else if (f == 113) {		/* $V(113): get termio infos */
 1357: 			
 1358:             struct termio tpara;
 1359: 
 1360:             if (i < 1 || i > MAXDEV) {
 1361:                 merr_raise (NODEVICE);
 1362:                 return;
 1363:             }
 1364: 
 1365:             if (devopen[i] == 0) {
 1366:                 merr_raise (NOPEN);
 1367:                 return;
 1368:             }
 1369: 
 1370:             ioctl (fileno (opnfile[i]), TCGETA, &tpara);
 1371: 			
 1372:             intstr (a, tpara.c_iflag);
 1373:             i = stlen (a);
 1374:             a[i++] = ':';
 1375: 			
 1376:             intstr (&a[i], tpara.c_oflag);
 1377:             i = stlen (a);
 1378:             a[i++] = ':';
 1379: 			
 1380:             intstr (&a[i], tpara.c_cflag);
 1381:             i = stlen (a);
 1382:             a[i++] = ':';
 1383: 			
 1384:             intstr (&a[i], tpara.c_lflag);
 1385: 			
 1386:             return;
 1387: 
 1388:         } 
 1389: #endif		
 1390:         else {
 1391:             merr_raise (ARGER);
 1392:             return;
 1393:         }
 1394: 
 1395:     } 
 1396:     else if (f == 3) {
 1397: 
 1398:         char tmp[256];
 1399: 
 1400:         stcpy (tmp, argstck[arg + 2]);
 1401:         i = intexpr (argstck[arg + 1]);
 1402:         f = intexpr (a);
 1403: 		
 1404:         if (merr () == MXNUM) return;
 1405: 
 1406:         if (f == 87) {			/* $V(87): date type definitions */
 1407: 			
 1408:             if (i < 0 || i >= NO_DATETYPE) {
 1409:                 merr_raise (ARGER);
 1410:                 return;
 1411:             }
 1412: 
 1413:             f = intexpr (tmp);
 1414: 			
 1415:             if (f > 0 && f < 13) {
 1416:                 stcpy (a, month[i][f - 1]);
 1417:                 return;
 1418:             }
 1419: 
 1420:             switch (f) {
 1421: 				
 1422: 
 1423:                 case 13:
 1424: 					
 1425:                 {
 1426:                     stcpy (a, dat1char[i]);
 1427:                     return;
 1428:                 }
 1429: 
 1430: 
 1431:                 case 14:
 1432: 
 1433:                 {
 1434:                     stcpy (a, dat2char[i]);
 1435:                     return;
 1436:                 }
 1437: 					
 1438: 
 1439:                 case 15:
 1440: 
 1441:                 {
 1442:                     a[0] = dat3char[i];
 1443:                     a[1] = EOL;
 1444: 
 1445:                     return;
 1446:                 }
 1447: 				
 1448: 
 1449:                 case 16:
 1450: 
 1451:                 {
 1452:                     a[0] = dat4flag[i] + '0';
 1453:                     a[1] = EOL;
 1454: 					
 1455:                     return;
 1456:                 }
 1457: 				
 1458: 
 1459:                 case 17:
 1460: 
 1461:                 {
 1462:                     a[0] = dat5flag[i] + '0';
 1463:                     a[1] = EOL;
 1464: 
 1465:                     return;
 1466:                 }
 1467: 				
 1468: 
 1469:                 case 18:
 1470: 
 1471:                 {
 1472:                     lintstr (a, datGRbeg[i] - 672411L);
 1473:                     return;
 1474:                 }
 1475: 
 1476: 
 1477:             }
 1478:         } 
 1479:         else if (f == 88) {		/* $V(88): time type definitions */
 1480: 			
 1481:             if (i < 0 || i >= NO_TIMETYPE) {
 1482:                 merr_raise (ARGER);
 1483:                 return;
 1484:             }
 1485: 
 1486:             f = intexpr (tmp);
 1487: 			
 1488:             switch (f) {
 1489:                 case 1:
 1490: 
 1491:                 {
 1492:                     a[0] = tim1char[i];
 1493:                     a[1] = EOL;
 1494: 
 1495:                     return;
 1496:                 }
 1497: 				
 1498: 
 1499:                 case 2:
 1500: 				
 1501:                 {
 1502:                     a[0] = tim2char[i];
 1503:                     a[1] = EOL;
 1504: 
 1505:                     return;
 1506:                 }
 1507: 				
 1508: 
 1509:                 case 3:
 1510: 				
 1511:                 {
 1512:                     a[0] = tim3char[i];
 1513:                     a[1] = EOL;
 1514: 
 1515:                     return;
 1516:                 }
 1517: 				
 1518: 
 1519:                 case 4:
 1520: 				
 1521:                 {
 1522:                     a[0] = tim4flag[i] + '0';
 1523:                     a[1] = EOL;
 1524: 
 1525:                     return;
 1526:                 }
 1527: 				
 1528: 
 1529:                 case 5:
 1530: 				
 1531:                 {
 1532:                     a[0] = tim5flag[i] + '0';
 1533:                     a[1] = EOL;
 1534: 
 1535:                     return;
 1536:                 }
 1537: 
 1538: 
 1539:             }
 1540: 
 1541:         }
 1542: 
 1543:         merr_raise (ARGER);
 1544:         return;
 1545: 
 1546:     } 
 1547:     else {
 1548:         merr_raise (FUNARG);
 1549:         return;
 1550:     }
 1551: 
 1552:     return;
 1553: }					/* end view_fun() */
 1554: 
 1555: 
 1556: void m_tolower (char *str)
 1557: {
 1558:     int ch;
 1559: 
 1560:     while ((ch = *str) != EOL) {
 1561: 		
 1562:         ch = *str;
 1563: 		
 1564:         if (ch <= 'Z' && ch >= 'A') {
 1565:             ch += 32;
 1566:             *str = ch;
 1567:         }
 1568: 
 1569:         str++;
 1570: 
 1571:     }
 1572: 
 1573:     return;
 1574: 
 1575: }					/* end tolower() */
 1576: 
 1577: 
 1578: /*
 1579:  * size = desired size for 'partition'
 1580:  */
 1581: short int newpsize (long size)
 1582: {
 1583:     char *newpart = NULL;
 1584:     char *anewpart = NULL;
 1585:     long dif, j;
 1586: 
 1587:     if (size == PSIZE) return 0;			/* nothing changes */
 1588:     if (size <= (PSIZE - symlen + 512)) return 0;			/* cannot decrease it now */
 1589:     if (apartition && size <= (PSIZE - asymlen + 512)) return 0;			/* cannot decrease it now */
 1590: 
 1591:     if (writing_mb) {
 1592:         newpart = shm_alloc ((size_t) (size+1));
 1593:     }
 1594:     else {
 1595:         newpart = calloc ((unsigned) (size + 1), 1);
 1596:     }
 1597:         
 1598:     if (newpart == NULL) return 1;			/* could not allocate stuff */
 1599: 	
 1600:     if (apartition) {
 1601: 
 1602:         anewpart = calloc ((unsigned) (size + 1), 1);
 1603: 		
 1604:         if (anewpart == NULL) {
 1605:             free (newpart);
 1606:             return 1;
 1607:         }	
 1608:         /* no more space */
 1609: 
 1610:     }
 1611: 
 1612:     dif = argptr - partition + 256;
 1613: 	
 1614:     if (dif > PSIZE) dif = PSIZE;
 1615: 	
 1616:     stcpy0 (newpart, partition, dif);	/* intermediate results */
 1617:     dif = size - PSIZE;
 1618:     stcpy0 (&newpart[symlen + dif], &partition[symlen], PSIZE - symlen);
 1619: 	
 1620:     if (apartition) stcpy0 (&anewpart[asymlen + dif], &apartition[asymlen], PSIZE - asymlen);
 1621: 	
 1622:     for (j = '%'; j <= 'z'; j++) {	/* update alphpointers */
 1623: 		
 1624:         if (alphptr[j])	alphptr[j] += dif;
 1625:         if (aalphptr[j]) aalphptr[j] += dif;
 1626: 
 1627:     }
 1628: 
 1629:     PSIZE = size;
 1630:     symlen += dif;
 1631:     asymlen += dif;
 1632: 
 1633:     if (writing_mb) {
 1634:         shm_free (partition);
 1635:     }
 1636:     else {
 1637:         free (partition);			/* free previously allocated space */
 1638:     }
 1639:     
 1640:     if (apartition) free (apartition);		/* free previously allocated space */
 1641: 	
 1642:     dif = newpart - partition;
 1643:     partition = newpart;
 1644: 	
 1645:     if (apartition) apartition = anewpart;
 1646: 	
 1647:     s = &partition[symlen] - 256;	/* pointer to symlen_offset        */
 1648:     argptr += dif;			/* pointer to beg of tmp-storage   */
 1649: 	
 1650:     for (j = 0; j <= PARDEPTH; j++) {
 1651: 
 1652:         if (argstck[j])	argstck[j] += dif;
 1653: 
 1654:     }
 1655: 
 1656:     return 0;
 1657: 
 1658: }					/* end newpsize() */
 1659: 
 1660: /* change size of svn_table to 'size' */
 1661: short int newusize (long size)
 1662: {
 1663: 	
 1664:     char   *newsvn;
 1665:     long    dif, j;
 1666: 
 1667:     if (size <= (UDFSVSIZ - svnlen)) return 0;			/* cannot decrease it now */
 1668:     if (size == UDFSVSIZ) return 0;			/* nothing changes */
 1669: 
 1670:     newsvn = calloc ((unsigned) (size + 1), 1);
 1671: 
 1672:     if (newsvn == NULL) return 1;			/* could not allocate stuff */
 1673: 	
 1674:     stcpy0 (newsvn, svntable, svnlen);	/* intermediate results */
 1675:     dif = size - UDFSVSIZ;
 1676:     stcpy0 (&newsvn[svnlen + dif], &svntable[svnlen], UDFSVSIZ - svnlen);
 1677: 	
 1678:     for (j = '%'; j <= 'z'; j++) {	/* update svn_alphpointers */
 1679:         if (svnaptr[j]) svnaptr[j] += dif;
 1680:     }
 1681: 
 1682:     UDFSVSIZ = size;
 1683:     svnlen += dif;
 1684: 	
 1685:     free (svntable);			/* free previously allocated space */
 1686: 	
 1687:     svntable = newsvn;
 1688: 
 1689:     return 0;
 1690: 
 1691: }					/* end newusize() */
 1692: 
 1693: /*
 1694:  * allocate 'nbrbuf' routine buffers
 1695:  * of 'size' bytes
 1696:  */
 1697: short int newrsize (long size, long nbrbuf)
 1698: {
 1699: 
 1700:     char *newrbuf;
 1701:     int i;
 1702:     long dif;
 1703:     unsigned long total;
 1704: 
 1705:     if (size <= (rouend - rouptr + 1)) return 0;			/* making it smaller would be a mistake */
 1706: 
 1707:     if (nbrbuf > MAXNO_OF_RBUF)	nbrbuf = MAXNO_OF_RBUF;
 1708: 
 1709:     total = (unsigned) nbrbuf *(unsigned) size;
 1710: 
 1711:     /* some overflow ??? */
 1712:     if ((total / (unsigned) size) != (unsigned) nbrbuf) {
 1713:         merr_raise (ARGER);
 1714:         return 1;
 1715:     }
 1716: 
 1717:     newrbuf = calloc (total, 1);	/* routine buffer pool             */
 1718: 	
 1719:     while (newrbuf == NULL) {		/* could not allocate stuff...     */
 1720: 		
 1721:         if (--nbrbuf < 2) return 1;			/* ...so try with less buffers     */
 1722: 		
 1723:         total = (unsigned) nbrbuf *(unsigned) size;
 1724: 
 1725:         newrbuf = calloc (total, 1);
 1726: 
 1727:     }
 1728: 
 1729:     /* clear all routine buffers but one */
 1730:     for (i = 0; i < MAXNO_OF_RBUF; i++) {	/* empty routine buffers */
 1731:         pgms[i][0] = 0;
 1732:         ages[i] = 0L;
 1733:     }
 1734: 
 1735:     /* transfer to new buffer */
 1736:     stcpy0 (newrbuf, rouptr, (long) (rouend - rouptr + 1));
 1737: 	
 1738:     dif = newrbuf - rouptr;
 1739:     rouend += dif;
 1740:     ends[0] = rouend;
 1741: 	
 1742:     stcpy (pgms[0], rou_name);
 1743: 	
 1744:     rouins += dif;
 1745: 	
 1746:     if (roucur == (buff + (NO_OF_RBUF * PSIZE0 + 1))) {
 1747:         roucur = newrbuf + (nbrbuf * size + 1);
 1748:     }
 1749:     else {
 1750:         roucur += dif;
 1751:     }
 1752: 	
 1753:     rouptr = newrbuf;
 1754: 
 1755:     free (buff);			/* free previously allocated space */
 1756: 
 1757:     buff = newrbuf;
 1758:     NO_OF_RBUF = nbrbuf;
 1759:     PSIZE0 = size;
 1760: 	
 1761:     return 0;
 1762: 
 1763: }					/* end newrsize() */
 1764: 
 1765: 
 1766: void zreplace (char *a, char *b, char *c)
 1767: {
 1768:     long int ch, f, l, m, n;
 1769:     char d[256];
 1770: 
 1771:     if (b[0] == EOL) return;				/* 2nd argument was empty */
 1772: 	
 1773:     l = stlen (c);			/* length of 3rd argument */
 1774:     n = 0;
 1775:     f = 0;
 1776: 	
 1777:     for (;;) {
 1778: 
 1779:         m = 0;
 1780: 		
 1781:         while ((ch = a[f + m]) == b[m] && ch != EOL) m++;
 1782: 
 1783:         if (b[m] == EOL) {
 1784: 			
 1785:             if (n + l > STRLEN) {
 1786:                 merr_raise (M75);
 1787:                 return;
 1788:             }
 1789: 
 1790:             stcpy0 (&d[n], c, l);
 1791: 			
 1792:             n += l;
 1793:             f += m;
 1794: 
 1795:         } 
 1796:         else {
 1797: 
 1798:             m = 1;
 1799: 			
 1800:             if (n + 1 > STRLEN) {
 1801:                 merr_raise (M75);
 1802:                 return;
 1803:             }
 1804: 
 1805:             d[n++] = a[f++];
 1806: 
 1807:         }
 1808: 
 1809:         if (a[f] == EOL) break;
 1810: 
 1811:     }
 1812: 
 1813:     d[n] = EOL;
 1814:     stcpy (a, d);
 1815: 	
 1816:     return;
 1817: 
 1818: }					/* end zreplace() */
 1819: 
 1820: short int tstglvn (char *a)				/* tests whether 'a' is a proper unsubscripted glvn */
 1821: {
 1822:     int i, ch;
 1823: 
 1824:     i = 0;
 1825: 
 1826:     if (a[0] == '^') {
 1827: 		
 1828:         while (((ch = a[++i]) >= 'A' && ch <= 'Z') ||
 1829:                (ch >= 'a' && ch <= 'z') ||
 1830:                (ch >= '0' && ch <= '9') ||
 1831:                ((ch == '%' && i == 1) ||
 1832:                 (standard == 0 &&
 1833:                  (((ch == '.' || ch == '/') && i == 1) ||
 1834:                   (((ch == '/' && a[i - 1] != '/') ||
 1835:                     (ch == '%' && a[i - 1] == '/')) &&
 1836:                    (a[1] == '.' || a[1] == '/'))))));
 1837: 		
 1838:         return a[i] == EOL;
 1839: 
 1840:     }
 1841: 	
 1842:     if ((ch = a[i++]) != '%' && (ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) return FALSE;
 1843: 	
 1844:     while ((ch = a[i++]) != EOL) {
 1845: 	
 1846:         if ((ch < '0' || ch > '9') && (ch < 'A' || ch > 'Z') &&	(ch < 'a' || ch > 'z')) {
 1847:             return FALSE;
 1848:         }
 1849: 	
 1850:     }
 1851: 	
 1852:     return TRUE;
 1853: 
 1854: }					/* end tstnam() */
 1855: 
 1856: void zname (char *a, char *b)
 1857: {
 1858:     int i, j, f, n;
 1859: 
 1860:     i = 0;
 1861:     j = 0;
 1862:     f = FALSE;				/* we are in name section (vs.subscr.) */
 1863:     n = FALSE;				/* part is numeric (vs.alphabetic) */
 1864: 	
 1865:     while ((a[i] = b[j++]) != EOL) {
 1866: 
 1867:         if (a[i] == '"') a[++i] = '"';
 1868: 		
 1869:         if (a[i] == DELIM) {
 1870: 
 1871:             if (f) {
 1872: 
 1873:                 if (n == FALSE) a[i++] = '"';
 1874: 
 1875:                 if (i >= (STRLEN-2)/*was 253*/) {
 1876:                     a[i] = EOL;
 1877:                     merr_raise (M75);
 1878: 				
 1879:                     return;
 1880:                 }
 1881: 
 1882:                 a[i] = ',';
 1883: 				
 1884:                 if ((n = znamenumeric (&b[j])) == FALSE) a[++i] = '"';
 1885: 
 1886:             } 
 1887:             else {
 1888: 				
 1889:                 a[i] = '(';
 1890:                 f = TRUE;
 1891: 			
 1892:                 if ((n = znamenumeric (&b[j])) == FALSE) a[++i] = '"';
 1893: 
 1894:             }
 1895: 
 1896:         }
 1897: 
 1898:         if (++i >= STRLEN) {
 1899: 
 1900:             a[STRLEN] = EOL;
 1901: 			
 1902:             if (b[j] != EOL) {
 1903:                 merr_raise (M75);
 1904:                 return;
 1905:             }
 1906: 
 1907:         }
 1908: 
 1909:     }
 1910: 	
 1911:     if (f) {
 1912: 
 1913:         if (i > (STRLEN-2) /* was 253 */) {
 1914:             merr_raise (M75);
 1915:             return;
 1916:         }
 1917: 
 1918:         if (n == FALSE) a[i++] = '"';
 1919: 
 1920:         a[i++] = ')';
 1921:         a[i] = EOL;
 1922: 
 1923:     }
 1924: 
 1925:     return;
 1926: 
 1927: }					/* end zname() */
 1928: 
 1929: /* boolean function that tests whether str is a canonical numeric */
 1930: short int znamenumeric (char *str)
 1931: {
 1932: 
 1933:     register int ptr = 0;
 1934:     register int ch;
 1935:     register int point;
 1936: 
 1937:     if (str[0] == '-') ptr = 1;
 1938: 
 1939:     if (str[ptr] == EOL) return FALSE;
 1940:     if (str[ptr] == DELIM) return FALSE;
 1941:     if (str[ptr] == '0') return str[1] == EOL || str[1] == DELIM;	/* leading zero */
 1942: 	
 1943:     point = FALSE;
 1944: 	
 1945:     while ((ch = str[ptr++]) != EOL && ch != DELIM) {
 1946: 		
 1947:         if (ch > '9') return FALSE;
 1948: 		
 1949:         if (ch < '0') {
 1950: 
 1951:             if (ch != '.') return FALSE;
 1952:             if (point) return FALSE;		/* multiple points */
 1953: 			
 1954:             point = TRUE;
 1955: 
 1956:         }
 1957: 
 1958:     }
 1959: 
 1960:     if (point) {
 1961:         if ((ch = str[ptr - 2]) == '0')	return FALSE;		/* trailing zero */
 1962:         if (ch == '.') return FALSE;		/* trailing point */
 1963:     }
 1964: 
 1965:     return TRUE;
 1966: 
 1967: }					/* end of znamenumeric() */
 1968: 
 1969: void procv22 (char *key)				/* process v22 translation */
 1970: {
 1971:     int     i, j, k1;
 1972:     char    tmp1[256];
 1973: 
 1974:     if (*key == EOL || *key == 0) return;
 1975: 
 1976:     i = 0;
 1977:     j = 0;
 1978: 	
 1979:     while (i < v22ptr) {
 1980: 
 1981:         k1 = i + UNSIGN (v22ali[i]) + 1;
 1982: 		
 1983:         /* is current reference an alias ??? */
 1984: 		
 1985:         j = 0;
 1986: 		
 1987:         while (v22ali[++i] == key[j]) {
 1988: 
 1989:             if (v22ali[i] == EOL) break;
 1990: 			
 1991:             j++;
 1992:         }
 1993: 
 1994:         /* yes, it is, so resolve it now! */
 1995:         if (v22ali[i] == EOL && (key[j] == EOL || key[j] == DELIM)) {
 1996: 
 1997:             stcpy (tmp1, key);
 1998:             stcpy (key, &v22ali[i + 1]);
 1999:             stcat (key, &tmp1[j]);
 2000: 			
 2001:             i = 0;
 2002: 			
 2003:             continue;			/* try again, it might be a double alias! */
 2004: 
 2005:         }
 2006: 
 2007:         i = k1;
 2008: 
 2009:     }
 2010: 
 2011:     return;
 2012: 
 2013: }					/* end of procv22() */
 2014: 
 2015: void v25 (char *a, int i)
 2016: {
 2017:     short c, exc, k, l, p;
 2018: 
 2019:     k = 0;
 2020:     exc = ~((*screen).screena[(unsigned int) (*screen).sclines[i]][0]);
 2021: 	
 2022:     for (l = 0; l < N_COLUMNS; l++) {
 2023: 		
 2024:         p = exc;
 2025:         exc = (*screen).screena[(unsigned int) (*screen).sclines[i]][l];
 2026:         c = (*screen).screenx[(unsigned int) (*screen).sclines[i]][l];
 2027: 
 2028: #ifdef NEVER
 2029: 
 2030:         /* this may result in a problem, when in a system */
 2031:         /* different G0O/G1O sets are in use !!!          */
 2032:         if (((exc == 1 && (p == 0)) || ((exc == 0) && (p == 1))) && (G0O[HOME][c] == G1O[HOME][c])) {
 2033:             exc = p;			/* if char looks same in SI/SO, delay SI/SO */
 2034:         }
 2035: 
 2036: #endif /* NEVER */
 2037: 
 2038:         if (exc != p) {			/* set attribute */
 2039: 
 2040: #ifdef SCO
 2041: 
 2042:             p = p & ~04;		/* suppress SGR(3) */
 2043: 
 2044:             if (p & 0200) p = p & 0201;		/* no display */
 2045:             if (p & 0100) p = p & 0101;		/* inverse */
 2046: 
 2047: #endif /* SCO */
 2048: 
 2049:             if ((p & 01) != (exc & 01)) a[k++] = (exc & 01) ? SO : SI;
 2050: 			
 2051:             if ((p & ~01) != (exc & ~01)) {
 2052: 				
 2053:                 a[k++] = ESC;
 2054:                 a[k++] = '[';
 2055: 			
 2056:                 for (p = 1; p < 8; p++) {
 2057: 					
 2058:                     if (exc & (1 << p)) {
 2059: 
 2060: #ifdef SCO
 2061: 
 2062:                         if (p == 1) {
 2063:                             a[k++] = '1';
 2064:                             a[k++] = ';';
 2065: 						
 2066:                             continue;
 2067:                         }
 2068: 
 2069: #endif /* SCO */
 2070: 
 2071:                         a[k++] = '1' + p;
 2072:                         a[k++] = ';';
 2073: 
 2074:                     }
 2075: 
 2076:                 }
 2077: 
 2078:                 if (a[k - 1] == ';') k--;
 2079: 			
 2080:                 a[k++] = 'm';
 2081:             }
 2082: 
 2083:         }
 2084: 
 2085:         a[k++] = c;
 2086: 
 2087:     }
 2088: 
 2089:     if (exc & 01) a[k++] = SI;
 2090: 
 2091:     a[k] = EOL;
 2092: 	
 2093:     return;
 2094: 
 2095: }					/* end of v25() */

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