Annotation of OpenXM_contrib2/fep/fep_com.c, Revision 1.5
1.1 noro 1: /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */
2:
1.4 fujimoto 3: #if defined(ANDROID)
4: #include <strings.h>
5: #define index(s,c) strchr(s,c)
6: #define rindex(s,c) strrchr(s,c)
7: #endif
8:
1.1 noro 9: #ifndef lint
10: static char rcsid[]=
11: "$Header: fep_com.c,v 4.9 91/05/29 14:30:43 utashiro Exp $ (SRA)";
12: #endif /* lint */
13:
14: #include <stdio.h>
1.3 ohara 15: #include <stdlib.h>
1.5 ! noro 16: #include <unistd.h>
1.3 ohara 17: #include <string.h>
1.1 noro 18: #include <sys/ioctl.h>
19: #ifdef TERMIOS
20: #include <termios.h>
21: #if defined(__linux__) || defined(__CYGWIN__)
22: #ifndef _POSIX_VDISABLE
23: #define _POSIX_VDISABLE '\0'
24: #endif
25: #endif
26: #else
27: #include <sgtty.h>
28: #endif
29: #include <ctype.h>
30: #include <sys/param.h>
31: #include <sys/file.h>
32: #include <sys/stat.h>
33: #include <sys/ioctl.h>
1.2 noro 34: #if defined(sun)
35: #include <sys/fcntl.h>
36: #endif
1.1 noro 37: #include "fep_defs.h"
38: #include "fep_glob.h"
39: #include "fep_funcs.h"
40:
41: int tty_fix_bell = OFF; /* ring bell if the tty mode is changed */
42:
43: typedef struct {
44: int cur_line;
45: int max_line;
46: } MORE;
47: MORE *create_more();
1.5 ! noro 48: int more (MORE *mp);
! 49: int showTable (MORE *m, FunctionTableEnt *fnte);
! 50: int showVariables (MORE *m);
! 51: void destroy_more(MORE *mp);
! 52: int showBindingTbl (MORE *m, FUNC ft[], char *prefix);
1.1 noro 53:
1.4 fujimoto 54: #if defined(ANDROID)
55: #define S_IREAD S_IRUSR
56: #define S_IWRITE S_IWUSR
57: #define S_IEXEC S_IXUSR
58: #endif
1.1 noro 59: /*
60: * Check command line if it call built-in function or not and execute it
61: */
1.5 ! noro 62: int executeBuiltInFunction (char *comline, char **more)
1.1 noro 63: {
64: register FunctionTableEnt *ftp;
65: char linebuf[MAXCMDLEN], *line;
66: char *search_string();
67: int argc;
68:
69: /*
70: * Skip white space.
71: */
72: while (isspace (*comline))
73: comline++;
74:
75: line = linebuf;
76: strcpy (line, comline);
77:
78: if (more) {
79: if (*more = search_string (comline, ";")) {
80: *(line + (*more - comline)) = '\0';
81: do {
82: *more += 1;
83: } while (**more == ';');
84: }
85: else {
86: *more = (char*) 0;
87: }
88: }
89:
90: /*
91: * Skip comment and blank line
92: */
93: if (*line == '#' || *line == '\0')
94: return (IGNORED);
95:
96: /*
97: * All built-in command should be prefixed by 'fep-'
98: */
99: if (strncmp (line, "fep-", 4) != 0)
100: return (NOT_PROCESSED);
101:
102: for (ftp = BuiltinFuncTable; ftp->name; ftp++) {
103: if (is_same_command (line, ftp->name)) {
104: if (debug)
105: showArgs (line);
106: if (
107: condition()
108: /* control structure should be processed on any condition */
109: || strncmp (line + 4, "if", 2) == 0
110: || strncmp (line + 4, "endif", 5) == 0
111: || strncmp (line + 4, "elseif", 6) == 0
112: || strncmp (line + 4, "else", 4) == 0
113: )
114: (*ftp->func)(line);
115: return (PROCESSED);
116: }
117: }
118: return (NOT_PROCESSED);
119: }
120:
1.5 ! noro 121: int is_same_command (char *a, char *b)
1.1 noro 122: {
123:
124: while (*a && *b && *a == *b)
125: ++a, ++b;
126: if ((*a == '\0' || isspace ((unsigned char)*a)) && (*b == '\0' || isspace ((unsigned char)*b)))
127: return 1;
128: else
129: return 0;
130: }
131:
132: /*
133: * Process 'fep-if' and 'fep-elseif'
134: */
1.5 ! noro 135: void fep_if (char *comline)
1.1 noro 136: {
137: char *argv[MAXARGS];
138: int argc;
139: char *err;
140: int cond;
141: int i;
142:
143: argc = mkargv (comline, argv, MAXARGS);
144:
145: if (argc != 2 && argc != 4) {
146: printf ("%s: Illegal number of arguments\n", argv[0]);
147: return;
148: }
149:
150: /*
151: * In case of only one argument,
152: * treat as true if the variable is set.
153: */
154: if (argc == 2) {
155: char *cp;
156:
157: if (argv[1][0] == '$')
158: cp = &argv[1][1];
159: else
160: cp = &argv[1][0];
161:
162: cond = look_var (cp) ? 1 : 0;
163: }
164: else {
165: int value;
166:
167: /*
168: * Substitute variable prefixed by '$' mark.
169: */
170: for (i = 0; i < argc; i++) {
171: if (argv[i][0] == '$') {
172: char *v;
173:
174: if (v = look_var (&argv[i][1]))
175: argv[i] = v;
176: else
177: argv[i] = "";
178: }
179: }
180:
181: if (debug) {
182: int i;
183: char **argp;
184:
185: for (i = 0, argp = argv; *argp; argp++, i++)
186: printf ("argv[%d] = \"%s\"\n", i, *argp);
187: }
188:
189: /*
190: * Check operator.
191: */
192: if (eq (argv[2], "==") || eq (argv[2], "="))
193: value = 1;
194: else if (eq (argv[2], "!="))
195: value = 0;
196: else {
197: printf ("%s: Unknown opperator \"%s\"", argv[0], argv[2]);
198: return;
199: }
200:
201: if (eq (argv[1], argv[3]))
202: cond = value;
203: else
204: cond = !value;
205: }
206:
207: if (eq (argv[0], "fep-elseif"))
208: err = change_condition (cond);
209: else
210: err = push_condition (cond);
211:
212: if (err)
213: printf ("%s: %s", argv[0], err);
214: else if (debug)
215: printf ("%s: %s\n", comline, cond ? "TRUE" : "FALSE");
216:
217: return;
218: }
219:
1.5 ! noro 220: void fep_else ()
1.1 noro 221: {
222: char *err;
223:
224: if (err = change_condition (1))
225: printf ("fep-else: %s", err);
226:
227: return;
228: }
229:
1.5 ! noro 230: void fep_endif ()
1.1 noro 231: {
232: char *err;
233:
234: if (err = pop_condition ())
235: printf ("fep-endif: %s", err);
236:
237: return;
238: }
239:
1.5 ! noro 240: void bind_to_key (char *comline)
1.1 noro 241: {
242: register FunctionTableEnt *fnte;
243: char *argv[MAXARGS];
244: int argc;
245:
246: argc = mkargv (comline, argv, MAXARGS);
247:
248: /*
249: * Something error occured. Print message and return
250: */
251: if (argc < 0) {
252: printf ("%s\n", argv[0]);
253: return;
254: }
255:
256: /*
257: * Number of arguments should be three.
258: */
259: if (argc != 3) {
260: printf ("Invalid number of arguments\n");
261: return;
262: }
263:
264: /*
265: * Find the function name from function name table.
266: */
267: for (fnte = FunctionNameTable; fnte->func; fnte++) {
268: if (strcmp (fnte->name, argv[1]) == 0) {
269: bind_key (curFuncTab, fnte->func, argv[2], fep_abort);
270: break;
271: }
272: }
273:
274: /*
275: * Couldn't find such a function
276: */
277: if (fnte->func == NULL)
278: printf ("%s: no such built-in command\n", argv[1]);
279: }
280:
1.5 ! noro 281: void alias(char *comline)
1.1 noro 282: {
283: char *argv[MAXARGS];
284: int argc;
285:
286: argc = mkargv (comline, argv, MAXARGS);
287:
288: switch (argc) {
289: case 1:
290: show_aliaslist (NULL);
291: break;
292:
293: case 2:
294: show_aliaslist (argv[1]);
295: break;
296:
297: case 3:
298: set_alias (argv[1], argv[2]);
299: break;
300:
301: default:
302: printf ("%s: Illegal number of arguments.\n", argv[0]);
303: }
304: return;
305: }
306:
1.5 ! noro 307: void unalias (char *comline)
1.1 noro 308: {
309: char *argv[MAXARGS];
310: int argc;
311: int i;
312:
313: argc = mkargv (comline, argv, MAXARGS);
314:
315: for (i=1; i<argc; i++)
316: unset_alias (argv[i]);
317:
318: return;
319: }
320:
1.5 ! noro 321: void set (char *comline)
1.1 noro 322: {
323: char line[MAXCMDLEN];
1.4 fujimoto 324: #if defined(ANDROID)
325: char *cp;
326: #else
1.1 noro 327: char *cp, *index();
1.4 fujimoto 328: #endif
1.1 noro 329: char *argv[MAXARGS];
330: int argc;
331:
332: /*
333: * If there is '=' character in command line, change it to space.
334: */
335: strcpy (line, comline);
336: if (cp = index (line, '='))
337: *cp = ' ';
338:
339: argc = mkargv (line, argv, MAXARGS);
340:
341: switch (argc) {
342:
343: /* set */
344: case 1:
345: show_varlist ();
346: return;
347:
348: /* set var */
349: case 2:
350: set_var (argv[1], "");
351: return;
352:
353: /* set var = val */
354: case 3:
355: set_var (argv[1], argv[2]);
356: break;
357:
358: default:
359: printf ("Invalid number of arguments\n");
360: return;
361: }
362: }
363:
1.5 ! noro 364: void unset(char *comline)
1.1 noro 365: {
366: char **vp;
367: char *argv[MAXARGS];
368: int argc;
369:
370: argc = mkargv (comline, argv, MAXARGS);
371:
372: if (argc < 2) {
373: printf ("Invalid number of arguments\n");
374: return;
375: }
376:
377: for (vp = &argv[1]; *vp; vp++)
378: unset_var (*vp);
379: }
380:
381: extern int Transparency;
382: extern int Through;
383: #ifdef TERMIOS
384: #define ttystruct termios
385: #elif defined(TIOCSETN)
386: #define ttystruct sgttyb
387: #endif
388: struct ttystruct master_ttymode; /* master tty mode */
389: struct ttystruct slave_ttymode; /* slave tty mode */
390: extern int master, slave;
391: extern char slave_tty[];
392:
393: /*
394: * Toggle transparency switch.
395: * If variable Transparency is ON, fep doesn't care about input.
396: * If OFF, line editing will be done by fep.
397: * But this Transparency is set automaticaly by getcharacter() routine,
398: * if the variable auto-tty-fix is ON.
399: */
1.5 ! noro 400: void toggle_through()
1.1 noro 401: {
402: int r;
403: int slave_fd;
404: #ifdef TERMIOS
405: struct termios s;
406: #else
407: struct sgttyb s;
408: #endif
409:
410: if (Through == OFF) {
411:
412: slave_fd = open (slave_tty, O_WRONLY);
413: if (slave_fd < 0) {
414: perror (slave_tty);
415: return;
416: }
417:
418: #ifdef TERMIOS
419: r = tcgetattr(slave_fd, &s);
420: #else
421: r = ioctl (slave_fd, TIOCGETP, (char *) &s);
422: #endif
423: if (r < 0) {
424: perror (slave_tty);
425: (void) close (slave_fd);
426: return;
427: }
428:
429: #ifdef TERMIOS
430: s.c_lflag &= ~(ICANON);
431: s.c_cc[VMIN] = 1;
432: s.c_cc[VTIME] = 0;
433: r = tcsetattr(0, TCSANOW, &s);
434: #else
435: s.sg_flags |= CBREAK;
436: r = ioctl (0, TIOCSETN, (char *) & s);
437: #endif
438: if (r < 0) {
439: perror (slave_tty);
440: (void) close (slave_fd);
441: }
442: (void) close (slave_fd);
443: }
444: else
445: #ifdef TERMIOS
446: r = tcsetattr(0, TCSANOW, & master_ttymode);
447: #else
448: r = ioctl (0, TIOCSETN, (char *) & master_ttymode);
449: #endif
450:
451: if (r < 0) {
452: printf ("Can't change pty mode.\n");
453: return;
454: }
455:
456: Through = !Through;
457: }
458:
459: /*
460: * Check tty mode of slave tty and fix stdout tty mode
461: */
1.5 ! noro 462: void fix_transparency()
1.1 noro 463: {
464: int r;
465: #ifdef TERMIOS
466: struct termios s;
467: #else
468: struct sgttyb s;
469: #endif
470:
471: if (Through)
472: return;
473:
474: if (slave < 0)
475: return;
476:
477: #ifdef TERMIOS
478: r = tcgetattr(slave, &s);
479: s.c_iflag |= ICRNL;
480: s.c_oflag |= ONLCR;
481: #else
482: r = ioctl (slave, TIOCGETP, (char *) &s);
483: /*
484: * slave CRMOD is off, but master should be.
485: */
486: s.sg_flags |= CRMOD;
487: #endif
488: if (r < 0) {
489: perror (slave_tty);
490: return;
491: }
492:
493: /*
494: * If find slave tty mode is cbreak or raw, fix tty mode of stdout to
495: * same mode as slave and set Transparency ON.
496: */
497:
498: #ifdef TERMIOS
499: if ((s.c_lflag & ICANON) == 0)
500: #else
501: if (s.sg_flags & (CBREAK|RAW))
502: #endif
503: {
504: if (Transparency == OFF) {
505: #ifdef TERMIOS
506: r = tcsetattr(0, TCSANOW, & s);
507: #else
508: r = ioctl (0, TIOCSETN, (char *) & s);
509: #endif
510: if (r < 0) {
511: perror ("stdout");
512: return;
513: }
514: if (tty_fix_bell) errorBell ();
515: Transparency = ON;
516: }
517: }
518: else {
519: if (Transparency == ON) {
520: #ifdef TERMIOS
521: r = tcsetattr(0, TCSANOW, & master_ttymode);
522: #else
523: r = ioctl (0, TIOCSETN, (char *) & master_ttymode);
524: #endif
525: if (r < 0) {
526: perror ("stdout");
527: return;
528: }
529: if (tty_fix_bell) errorBell ();
530: Transparency = OFF;
531: }
532: }
533:
534: if (r < 0) {
535: printf ("Can't change pty mode.\n");
536: return;
537: }
538: }
539:
1.5 ! noro 540: void putch (int c)
1.1 noro 541: {
542: putchar (c);
543: fflush (stdout);
544: }
545:
546: /*
547: int crt, sline;
548: */
549:
1.5 ! noro 550: int show_bindings ()
1.1 noro 551: {
552: MORE *m;
553:
554: m = create_more(lines);
555: if (!m) {
556: errorBell ();
557: return (0);
558: }
559:
560: clear_edit_line ();
561: (void) showBindingTbl (m, curFuncTab, "");
562: recover_edit_line (1);
563:
564: destroy_more(m);
565: return (0);
566: }
567:
1.5 ! noro 568: int showBindingTbl (MORE *m, FUNC ft[], char *prefix)
1.1 noro 569: {
570: register FunctionTableEnt *fnte;
571: register int i;
572:
573: for (i = 0; i < 128; i++) {
574: if (ft[i] == self_insert || ft[i] == fep_abort)
575: continue;
576:
577: /*
578: * If the pointer to function has indirect flag print "indirect".
579: */
580: if (isIndirect(ft[i])) {
581: char pf[64];
582:
583: sprintf (pf, "%s%s%c-",
584: prefix, (i == 0 || isctlchar(i)) ? "^" : "", unctl(i));
585: if (showBindingTbl (m, maskIndirect(ft[i]), pf) == 0)
586: break;
587: continue;
588: }
589:
590: /*
591: * Search function name table
592: */
593: for (fnte = FunctionNameTable; fnte->func; fnte++) {
594: if (ft[i] == fnte->func) {
595:
596: if (!more(m))
597: return (0);
598:
599: /*
600: * Show binding
601: */
602: printf ("%s%s%c\t%s\n",
603: prefix,
604: i == 0 || isctlchar(i) ? "^" : "",
605: unctl(i),
606: fnte->name
607: );
608: break;
609: }
610: }
611:
612: /*
613: * Can't find such a function
614: */
615: if (fnte->func == NULL)
616: printf (
617: "%s%c\tunknown function (0x%x)\n",
618: i == 0 || isctlchar(i) ? "^" : "",
619: unctl(i),
620: ft[i]
621: );
622: }
623: return (1);
624: }
625:
1.5 ! noro 626: void show_help ()
1.1 noro 627: {
628: MORE *m;
629:
630: m = create_more(lines);
631: if (m == 0) {
632: errorBell ();
633: return;
634: }
635:
636: clear_edit_line ();
637:
638: more(m) &&
639: (printf ("Functions:\n") || 1) &&
640: showTable (m, FunctionNameTable) &&
641: more(m) &&
642: (printf ("Commands:\n") || 1) &&
643: showTable (m, BuiltinFuncTable) &&
644: more(m) &&
645: (printf ("Variables:\n") || 1) &&
646: showVariables (m);
647:
648: recover_edit_line (1);
649: }
650:
1.5 ! noro 651: int showTable (MORE *m, FunctionTableEnt *fnte)
1.1 noro 652: {
653: int i;
654:
655: /*
656: * Search function name table
657: */
658: for (; fnte->func; fnte++) {
659: if (!more(m))
660: return (0);
661: printf ("\t%-30s %s\n", fnte->name, fnte->help);
662: }
663:
664: return (1);
665: }
666:
1.5 ! noro 667: int showVariables (MORE *m)
1.1 noro 668: {
669: extern VAR default_set_vars[], default_unset_vars[];
670: VAR *vp;
671:
672: for (vp = default_set_vars; vp->v_name; ++vp) {
673: if (!vp->v_help)
674: continue;
675: if (!more(m))
676: return (0);
677: printf ("\t%-30s %s\n", vp->v_name, vp->v_help);
678: }
679:
680: for (vp = default_unset_vars; vp->v_name; ++vp) {
681: if (!vp->v_help)
682: continue;
683: if (!more(m))
684: return (0);
685: printf ("\t%-30s %s\n", vp->v_name, vp->v_help);
686: }
687: return (1);
688: }
689:
1.5 ! noro 690: MORE *create_more(int maxline)
1.1 noro 691: {
692: MORE *mp;
693:
694: mp = (MORE *) malloc (sizeof (MORE));
695:
696: if (mp == 0)
697: return ((MORE*)0);
698: else {
699: mp->cur_line = 0;
700: mp->max_line = maxline;
701: return (mp);
702: }
703: }
704:
1.5 ! noro 705: void destroy_more(MORE *mp)
1.1 noro 706: {
707: if (mp)
708: free (mp);
709: }
710:
1.5 ! noro 711: int more (MORE *mp)
1.1 noro 712: {
713:
714: /*
715: * Print more message
716: */
717: # define PUTMORE printf ( "--More--");
718: # define DELMORE printf ("\r \r");
719: if (mp->max_line && ++mp->cur_line >= mp->max_line) {
720:
721: PUTMORE;
722: fflush (stdout);
723:
724: switch (getcharacter()) {
725: case '\n': case '\r': case 'j':
726: --mp->cur_line;
727: break;
728:
729: case 'd': case ctrl('D'):
730: mp->cur_line /= 2;
731: break;
732:
733: case 'q': case 'Q': case ctrl('C'):
734: DELMORE;
735: return (0);
736:
737: default:
738: mp->cur_line = 1;
739: break;
740: }
741: DELMORE;
742: }
743:
744: if (mp->cur_line == 1 && look_var ("clear-repaint") && term_clear)
745: tputs (term_clear, 1, putch);
746:
747: return (1);
748: }
749:
750: /*
751: * Change directory
752: */
1.5 ! noro 753: void fep_chdir (char *line)
1.1 noro 754: {
755: char *argv[MAXARGS];
756: int argc;
757:
758: switch (mkargv (line, argv, MAXARGS)) {
759:
760: /*
761: * Change directory with no arguments cause to chdir to home directory
762: */
763: case 1: {
764: char *home, *getenv();
765:
766: if (home = getenv ("HOME"))
767: argv[1] = home;
768: else {
769: printf ("Where is your home directory?\n");
770: return;
771: }
772: break;
773: }
774:
775: /*
776: * Change directory command with argument
777: */
778: case 2:
779: break;
780:
781: /*
782: * Something error occured in mkargv.
783: */
784: case -1:
785: printf ("%s\n", argv[0]);
786: return;
787:
788: default:
789: printf ("fep-chdir: Invalid number of arguments.\n");
790: return;
791: }
792:
793: /*
794: * Chane directory.
795: * Keep in mind that end process still in old directory
796: */
797: if (chdir (argv[1]) < 0) {
798: perror (argv[1]);
799: return;
800: }
801: }
802:
1.5 ! noro 803: void fep_pwd (char *line)
1.1 noro 804: {
805: char cwd[MAXPATHLEN];
806:
807: (void) getcwd (cwd, sizeof(cwd));
808: printf ("%s\n", cwd);
809: }
810:
1.5 ! noro 811: void fep_echo (char *comline)
1.1 noro 812: {
813: char *argv[MAXARGS];
814: int argc;
815: char **argp;
816: int putnewline = 1, first;
817:
818: argc = mkargv (comline, argv, MAXARGS);
819:
820: argp = &argv[1];
821: if (*argp && strcmp (*argp, "-n") == 0) {
822: putnewline = 0;
823: ++argp;
824: }
825:
826: for (first = 1; *argp; argp++) {
827: char *cp;
828:
829: /*
830: * Put space
831: */
832: if (! first)
833: printf ("%s", " ");
834:
835: /*
836: * Print argument
837: */
838: if (**argp == '$' && (cp = look_var (*argp + 1)))
839: printf ("%s", cp);
840: else
841: printf ("%s", *argp);
842:
843: first = 0;
844: }
845:
846: if (putnewline)
847: printf ("%c", '\n');
848: }
849:
1.5 ! noro 850: void fep_command (char *comline)
1.1 noro 851: {
852: char *argv[MAXARGS];
853: int argc;
854: int i;
855: char **argp;
856: char buf[256];
857:
858: argc = mkargv (comline, argv, MAXARGS);
859:
860: if (argc == 1) {
861: printf ("Invalid number of arguments.\n");
862: return;
863: }
864:
865: strcpy (buf, "");
866: for (i=1; i<argc; i++) {
867: strcat (buf, argv[i]);
868: strcat (buf, " ");
869: }
870:
871: invoke_command (buf);
872: }
873:
1.5 ! noro 874: void fep_source (char *comline)
1.1 noro 875: {
876: FILE *fp;
877: static char *argv[MAXARGS];
878: char file [MAXPATHLEN];
879: int argc;
880:
881: argc = mkargv (comline, argv, MAXARGS);
882:
883: if (argc != 2) {
884: printf ("Invalid number of arguments.\n");
885: return;
886: }
887:
888: strcpy (file, argv[1]);
889: source_file (file);
890:
891: return;
892: }
893:
1.5 ! noro 894: void sourceRcFile ()
1.1 noro 895: {
896: char *home, filename[64], *getenv();
897: char line[256];
898: struct stat stb_home, stb_cur;
899:
900: if (!(home = getenv ("HOME")))
901: return;
902:
903: strcpy (filename, home);
904: strcat (filename, "/.feprc");
905:
906: /*
907: * Source .feprc in home directory.
908: */
909: stb_home.st_ino = 0;
910: if (stat (filename, &stb_home) >= 0 && (stb_home.st_mode&S_IREAD))
911: source_file (filename);
912:
913: /*
914: * Source .feprc in current directory.
915: */
916: if ((stat (".feprc", &stb_cur) >= 0 && stb_cur.st_ino != stb_home.st_ino))
917: source_file (".feprc");
918:
919: return;
920: }
921:
1.5 ! noro 922: void source_file (char *file)
1.1 noro 923: {
924: FILE *fp;
925: char line[512], line2[512];
926: int i = 0;
927:
928: if ((fp = fopen (file, "r")) == NULL) {
929: perror (file);
930: return;
931: }
932:
933: while (fgets (line, 256, fp)) {
934: i++;
935: if (executeBuiltInFunction (line, 0) == NOT_PROCESSED) {
936: char *cp = line;
937:
938: while (isspace (*cp))
939: cp++;
940: strcpy (line2, "fep-");
941: strcat (line2, cp);
942: if (executeBuiltInFunction (line2, 0) == NOT_PROCESSED) {
943: printf ("\"%s\", line %d: cannot be executed\n", file, i);
944: printf (">>> %s", line);
945: }
946: }
947: }
948:
949: fclose (fp);
950: return;
951:
952: }
953:
954: #define MAX_IF_NEST 10
955:
956: #define CONDITION_MASK 0x00ff
957: #define HAS_BEEN_TRUE 0x0100
958:
959: int condition_stack [MAX_IF_NEST] = {1};
960: int current_if_stack = 0;
961:
1.5 ! noro 962: int condition ()
1.1 noro 963: {
964: int cond = 1, i;
965:
966: if (current_if_stack == 0)
967: return (1);
968:
969: for (i = 1; i <= current_if_stack; i++)
970: cond &= condition_stack [i];
971:
972: return (cond & CONDITION_MASK);
973: }
974:
1.5 ! noro 975: char * change_condition (int cond)
1.1 noro 976: {
977: if (debug)
978: printf ("old=0x%x, new=0x%x\n",
979: condition_stack [current_if_stack], cond);
980: if (current_if_stack > 0) {
981: if (condition_stack [current_if_stack] & HAS_BEEN_TRUE)
982: cond = 0;
983: else if (cond != 0)
984: condition_stack [current_if_stack] |= HAS_BEEN_TRUE;
985:
986: condition_stack [current_if_stack] &= ~CONDITION_MASK;
987: condition_stack [current_if_stack] |= cond;
988: return ((char *)0);
989: }
990: else
991: return ("Not in if close\n");
992: }
993:
1.5 ! noro 994: char * push_condition (int cond)
1.1 noro 995: {
996: if (current_if_stack < MAX_IF_NEST){
997: ++current_if_stack;
998: condition_stack [current_if_stack] = cond;
999: if (cond == 1)
1000: condition_stack [current_if_stack] |= HAS_BEEN_TRUE;
1001: return ((char*)0);
1002: }
1003: else
1004: return ("If stack over flow\n");
1005: }
1006:
1.5 ! noro 1007: char * pop_condition ()
1.1 noro 1008: {
1009:
1010: if (current_if_stack > 0) {
1011: --current_if_stack;
1012: return ((char*)0);
1013: }
1014: else
1015: return ("No more if stack\n");
1016: }
1017:
1.5 ! noro 1018: void invoke_shell ()
1.1 noro 1019: {
1020: char *shell = "/bin/sh";
1021:
1022: if (look_var ("shell"))
1023: shell = look_var ("shell");
1024:
1025: invoke_command (shell);
1026: }
1027:
1.5 ! noro 1028: void invoke_command (char *cmd)
1.1 noro 1029: {
1030: int (*func)();
1031:
1032: clear_edit_line ();
1033: if (look_var ("verbose"))
1034: printf ("Invoke %s\n", cmd);
1035: fflush (stdout);
1036: recover_tty();
1037: recover_signal ();
1038: system (cmd);
1039: fix_signal ();
1040: fix_tty();
1041: if (look_var ("verbose"))
1042: printf ("Return to fep\n");
1043: recover_edit_line (1);
1044: }
1045:
1046: FILE *redirect_fp = NULL;
1047: int redirect_line = 0;
1048:
1.5 ! noro 1049: void fep_read_from_file (char *comline)
1.1 noro 1050: {
1051: FILE *fp;
1052: static char *argv[MAXARGS];
1053: char file [MAXPATHLEN];
1054: int argc;
1055:
1056: argc = mkargv (comline, argv, MAXARGS);
1057:
1058: if (argc != 2) {
1059: printf ("Invalid number of arguments.\n");
1060: return;
1061: }
1062:
1063: if (redirect_fp) {
1064: fclose (redirect_fp);
1065: redirect_fp = NULL;
1066: }
1067:
1068: redirect_fp = fopen (argv[1], "r");
1069:
1070: if (redirect_fp = fopen (argv[1], "r")) {
1071: if (look_var ("verbose"))
1072: printf ("Input redirected from %s\n", argv[1]);
1073: errorBell ();
1074: redirect_line = 0;
1075: }
1076: else
1077: perror (argv[0]);
1078:
1079: return;
1080: }
1081:
1082: /*
1083: * Process ID of the process redirecting from.
1084: */
1085: int redirect_pid = 0;
1086:
1.5 ! noro 1087: void fep_read_from_command (char *comline)
1.1 noro 1088: {
1089: static char *argv[MAXARGS];
1090: char buf[256];
1091: int argc;
1092: int i;
1093: FILE *popen();
1094:
1095: argc = mkargv (comline, argv, MAXARGS);
1096:
1097: if (argc == 1) {
1098: printf ("Invalid number of arguments.\n");
1099: return;
1100: }
1101:
1102: if (redirect_fp) {
1103: fclose (redirect_fp);
1104: redirect_fp = NULL;
1105: }
1106:
1107: strcpy (buf, "");
1108: for (i=1; i<argc; i++) {
1109: strcat (buf, argv[i]);
1110: strcat (buf, " ");
1111: }
1112:
1113: if (redirect_fp = popen (buf, "r")) {
1114: if (look_var ("verbose"))
1115: printf ("Input redirected from %s\n", argv[1]);
1116: errorBell ();
1117: redirect_line = 0;
1118: }
1119: else
1120: perror (argv[0]);
1121:
1122: return;
1123: }
1124:
1125: char script_file[128];
1126:
1.5 ! noro 1127: void fep_start_script (char *comline)
1.1 noro 1128: {
1129: char *name;
1130:
1131: /*
1132: * Caution!! If editstatus is EDITING, comline argument is never passed.
1133: */
1134: if (editstatus == NOTEDITING) {
1135: int argc;
1136: static char *argv[MAXARGS];
1137: char buf[256];
1138:
1139: argc = mkargv (comline, argv, MAXARGS);
1140: switch (argc) {
1141:
1142: case 1:
1143: name = look_var ("script-file");
1144: break;
1145:
1146: case 2:
1147: name = argv[1];
1148: break;
1149:
1150: default:
1151: printf ("%s: Illegal number of arguments.\n", argv[0]);
1152: }
1153: }
1154: else
1155: name = look_var ("script-file");
1156:
1157: /*
1158: * If script is running alread, reatun.
1159: */
1160: if (script_fp) {
1161: clear_edit_line ();
1162: errorBell ();
1163: printf ("script is already running.\n");
1164: recover_edit_line (1);
1165: return;
1166: }
1167:
1168: if (!name) {
1169: clear_edit_line ();
1170: printf ("script-file is not set.\n");
1171: recover_edit_line (1);
1172: return;
1173: }
1174:
1175: if ((script_fp = fopen (name, "a")) == NULL) {
1176: clear_edit_line ();
1177: perror (name);
1178: recover_edit_line (1);
1179: return;
1180: }
1181:
1182: strncpy (script_file, name, sizeof (script_file));
1183:
1184: clear_edit_line ();
1185: printf ("script start (file=\"%s\").\n", script_file);
1186: recover_edit_line (1);
1187: }
1188:
1.5 ! noro 1189: void fep_end_script ()
1.1 noro 1190: {
1191: if (!script_fp) {
1192: clear_edit_line ();
1193: errorBell ();
1194: printf ("script is not started.\n");
1195: return;
1196: }
1197:
1198: fclose (script_fp);
1199: script_fp = NULL;
1200:
1201: clear_edit_line ();
1202: printf ("script end (file=\"%s\").\n", script_file);
1203: recover_edit_line (1);
1204:
1205: return;
1206: }
1207:
1.5 ! noro 1208: void fep_repaint(char *comline)
1.1 noro 1209: {
1210: int i;
1211: int line;
1212: CHAR ch;
1213: char *crt_hight;
1214: BUFFER *bp = output_buffer;
1215:
1216: /*
1217: * Caution!! If editstatus is EDITING, comline argument is never passed.
1218: */
1219: if (editstatus == NOTEDITING && comline) {
1220: int argc;
1221: static char *argv[MAXARGS];
1222: char buf[256];
1223:
1224: argc = mkargv (comline, argv, MAXARGS);
1225: switch (argc) {
1226:
1227: case 1:
1228: crt_hight = look_var ("crt");
1229: break;
1230:
1231: case 2:
1232: crt_hight = argv[1];
1233: break;
1234:
1235: default:
1236: printf ("%s: Illegal number of arguments.\n", argv[0]);
1237: }
1238: }
1239: else
1240: crt_hight = look_var ("crt");
1241:
1242: line = atoi (crt_hight);
1243:
1244: clear_edit_line ();
1245:
1246: ch = buf_char (bp, -1);
1247: for (i = -1; ; --i) {
1248: if ((ch = buf_char(bp, i)) == '\n')
1249: --line;
1250: if (ch == (CHAR)-1 || line <= 0)
1251: break;
1252: }
1253: i += 1;
1254:
1255: if (look_var("clear-repaint") && term_clear)
1256: tputs (term_clear, 1, putch);
1257:
1258: for (; i < 0; i++)
1259: putchar (buf_char(bp, i));
1260:
1261: /*
1262: * In this case, prompt should not be printed.
1263: * Saving prompt is ugly solution, but...
1264: */
1265: recover_edit_line (0);
1266: fflush (stdout);
1267: }
1268:
1.5 ! noro 1269: int view_buffer (char *comline)
1.1 noro 1270: {
1271: BUFFER *bp = output_buffer;
1272: MORE *m;
1273: int maxchar = buf_count (bp);
1274: int i;
1275: char c;
1276:
1277: /*
1278: * Skip first line
1279: */
1280: for (i = 0; (c = buf_char (bp, i)) != (char)-1 && c != '\n'; i++)
1281: ;
1282: i += 1;
1283:
1284: if (c == -1)
1285: return (0);
1286:
1287: if (!(m = create_more (lines)))
1288: return (0);
1289:
1290: clear_edit_line ();
1291: for (; i < maxchar; i++) {
1292: if (!more(m))
1293: break;
1294: while ((c = buf_char (bp, i)) != (char)-1 && c != '\n') {
1295: putchar (c);
1296: i++;
1297: }
1298: if (c == '\n')
1299: putchar ('\n');
1300: }
1301:
1302: /*
1303: * If all output is shown, prompt not to be shown.
1304: */
1305: if (i < maxchar)
1306: recover_edit_line (1);
1307: else
1308: recover_edit_line (0);
1309:
1310: destroy_more(m);
1311: return (0);
1312: }
1313:
1314: #ifdef STAT
1315:
1316: #include "fep_stat.h"
1317:
1318: long stat_obyte = 0;
1319: long stat_ibyte = 0;
1320: long stat_rerror = 0;
1321: long stat_werror = 0;
1322: long stat_nselect = 0;
1323:
1324: struct statistics stat_info[] = {
1325: "Command Output", &stat_obyte,
1326: "Command Input ", &stat_ibyte,
1327: "Read error ", &stat_rerror,
1328: "Write error ", &stat_werror,
1329: "Select count ", &stat_nselect,
1330: NULL, NULL
1331: };
1332:
1.5 ! noro 1333: void fep_showstat ()
1.1 noro 1334: {
1335: struct statistics *sp = stat_info;
1336: BUFFER *bp = output_buffer;
1337:
1338: printf ("I/O and system calls:\n");
1339: for (sp = stat_info; sp->info_name; sp++) {
1340: printf ("\t%s: %d\n", sp->info_name, *(sp->info_valp));
1341: }
1342:
1343: printf ("\nI/O Buffer:\n");
1344: printf ("\tMax : %d\n", bp->b_max);
1345: printf ("\tHiWtr: %d\n", bp->b_hiwater);
1346: printf ("\tCount: %d\n", bp->b_count);
1347: printf ("\tNext : %d\n", bp->b_next);
1348:
1349: }
1350: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>