Commit | Line | Data |
---|---|---|
6a571c25 | 1 | #ifndef lint |
4cbe417d | 2 | static char *sccsid = "@(#)lcmd.c 3.6 83/08/25"; |
6a571c25 EW |
3 | #endif |
4 | ||
5 | #include "defs.h" | |
6 | ||
4cbe417d | 7 | int l_buffer(); |
6a571c25 EW |
8 | int l_window(); |
9 | int l_select(); | |
10 | int l_escape(); | |
11 | int l_label(); | |
12 | int l_terse(); | |
13 | int l_source(); | |
14 | int l_write(); | |
8aee01cc | 15 | int l_close(); |
6a571c25 EW |
16 | |
17 | struct lcmd { | |
18 | char *l_name; /* name of command */ | |
19 | int l_lmin; /* minimum length to check */ | |
20 | int l_lmax; /* maximum length to check */ | |
21 | int l_amin; /* minimum argument */ | |
22 | int l_amax; /* maximum argument */ | |
23 | int (*l_func)(); /* the function */ | |
24 | }; | |
25 | static struct lcmd lcmd[] = { | |
8aee01cc | 26 | "%", 1, 1, 0, 0, l_select, |
4cbe417d | 27 | "buffer", 1, 0, 1, 1, l_buffer, |
a4c3bba5 | 28 | "close", 1, 0, 0, -1, l_close, |
8aee01cc EW |
29 | "escape", 1, 0, 1, 1, l_escape, |
30 | "label", 1, 0, 2, 2, l_label, | |
31 | "source", 1, 0, 1, 1, l_source, | |
32 | "terse", 1, 0, 0, 1, l_terse, | |
4cbe417d | 33 | "window", 1, 0, 4, 5, l_window, |
8aee01cc | 34 | "write", 2, 0, 2, 2, l_write, |
6a571c25 EW |
35 | 0 |
36 | }; | |
37 | ||
38 | dosource(filename) | |
39 | char *filename; | |
40 | { | |
41 | register FILE *f; | |
42 | char buf[BUFSIZ]; | |
43 | ||
44 | if ((f = fopen(filename, "r")) == 0) | |
45 | return -1; | |
46 | insource++; | |
47 | beginerror(filename); | |
48 | for (lineno = 1; fgets(buf, sizeof buf, f) != 0; lineno++) | |
49 | dolongcmd(buf); | |
50 | enderror(); | |
51 | insource = 0; | |
52 | return 0; | |
53 | } | |
54 | ||
55 | dolongcmd(line) | |
56 | char *line; | |
57 | { | |
58 | register struct lcmd *lp; | |
59 | register len; | |
60 | ||
61 | makeargv(line); | |
62 | if (argc == 0) | |
63 | return; | |
64 | for (lp = lcmd; lp->l_name; lp++) { | |
65 | len = strlen(*argv); | |
66 | if (len < lp->l_lmin) | |
67 | continue; | |
68 | if (!strncmp(*argv, lp->l_name, lp->l_lmax ? lp->l_lmax : len)) | |
69 | break; | |
70 | } | |
71 | if (lp->l_name) { | |
72 | if (lp->l_amin > argc - 1) | |
73 | error("Too few arguments."); | |
8aee01cc | 74 | else if (lp->l_amax >= 0 && lp->l_amax < argc - 1) |
6a571c25 EW |
75 | error("Too many arguments."); |
76 | else | |
77 | (*lp->l_func)(); | |
78 | } else | |
79 | error("%s: Unknown command.", *argv); | |
80 | } | |
81 | ||
82 | makeargv(p) | |
83 | register char *p; | |
84 | { | |
85 | static char buf[BUFSIZ]; | |
86 | register char *q = buf, **pp = argv; | |
87 | char quote = 0, escape = 0; | |
88 | int i; | |
89 | ||
90 | for (; *p == ' ' || *p == '\t'; p++) | |
91 | ; | |
a4550a40 | 92 | while (*p && *p != '\n' && (*p != '#' || escape || quote) |
6a571c25 EW |
93 | && pp < &argv[sizeof argv/sizeof *argv - 1]) { |
94 | *pp++ = q; | |
95 | while (*p && *p != '\n') { | |
96 | if (escape) { | |
97 | switch (*p) { | |
98 | case 'n': | |
99 | *q++ = '\n'; | |
100 | p++; | |
101 | break; | |
102 | case 'r': | |
103 | *q++ = '\r'; | |
104 | p++; | |
105 | break; | |
106 | case '0': case '1': case '2': case '3': | |
107 | case '4': case '5': case '6': case '7': | |
108 | *q = 0; | |
109 | for (i = 3; --i >= 0 | |
110 | && *p >= '0' && *p <= '9';) | |
111 | *q = *q << 3 | *p++ - '0'; | |
112 | q++; | |
113 | break; | |
114 | default: | |
115 | *q++ = *p++; | |
116 | break; | |
117 | } | |
118 | escape = 0; | |
119 | } else if (*p == '\\') { | |
120 | escape = 1; | |
121 | p++; | |
122 | } else if (quote) { | |
123 | if (*p == quote) { | |
124 | quote = 0; | |
125 | p++; | |
126 | } else | |
127 | *q++ = *p++; | |
128 | } else { | |
129 | if (*p == '"' || *p == '\'') | |
130 | quote = *p++; | |
131 | else if (*p == ' ' || *p == '\t') | |
132 | break; | |
133 | else | |
134 | *q++ = *p++; | |
135 | } | |
136 | } | |
137 | *q++ = 0; | |
138 | for (; *p == ' ' || *p == '\t'; p++) | |
139 | ; | |
140 | } | |
141 | *pp = 0; | |
142 | argc = pp - argv; | |
143 | } |