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