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