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