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