Blame


1 76193d7c 2003-09-30 devnull #include "sam.h"
2 76193d7c 2003-09-30 devnull #include "parse.h"
3 76193d7c 2003-09-30 devnull
4 76193d7c 2003-09-30 devnull static char linex[]="\n";
5 76193d7c 2003-09-30 devnull static char wordx[]=" \t\n";
6 76193d7c 2003-09-30 devnull struct cmdtab cmdtab[]={
7 76193d7c 2003-09-30 devnull /* cmdc text regexp addr defcmd defaddr count token fn */
8 76193d7c 2003-09-30 devnull '\n', 0, 0, 0, 0, aDot, 0, 0, nl_cmd,
9 76193d7c 2003-09-30 devnull 'a', 1, 0, 0, 0, aDot, 0, 0, a_cmd,
10 76193d7c 2003-09-30 devnull 'b', 0, 0, 0, 0, aNo, 0, linex, b_cmd,
11 76193d7c 2003-09-30 devnull 'B', 0, 0, 0, 0, aNo, 0, linex, b_cmd,
12 76193d7c 2003-09-30 devnull 'c', 1, 0, 0, 0, aDot, 0, 0, c_cmd,
13 76193d7c 2003-09-30 devnull 'd', 0, 0, 0, 0, aDot, 0, 0, d_cmd,
14 76193d7c 2003-09-30 devnull 'D', 0, 0, 0, 0, aNo, 0, linex, D_cmd,
15 76193d7c 2003-09-30 devnull 'e', 0, 0, 0, 0, aNo, 0, wordx, e_cmd,
16 76193d7c 2003-09-30 devnull 'f', 0, 0, 0, 0, aNo, 0, wordx, f_cmd,
17 76193d7c 2003-09-30 devnull 'g', 0, 1, 0, 'p', aDot, 0, 0, g_cmd,
18 76193d7c 2003-09-30 devnull 'i', 1, 0, 0, 0, aDot, 0, 0, i_cmd,
19 76193d7c 2003-09-30 devnull 'k', 0, 0, 0, 0, aDot, 0, 0, k_cmd,
20 76193d7c 2003-09-30 devnull 'm', 0, 0, 1, 0, aDot, 0, 0, m_cmd,
21 76193d7c 2003-09-30 devnull 'n', 0, 0, 0, 0, aNo, 0, 0, n_cmd,
22 76193d7c 2003-09-30 devnull 'p', 0, 0, 0, 0, aDot, 0, 0, p_cmd,
23 76193d7c 2003-09-30 devnull 'q', 0, 0, 0, 0, aNo, 0, 0, q_cmd,
24 76193d7c 2003-09-30 devnull 'r', 0, 0, 0, 0, aDot, 0, wordx, e_cmd,
25 76193d7c 2003-09-30 devnull 's', 0, 1, 0, 0, aDot, 1, 0, s_cmd,
26 76193d7c 2003-09-30 devnull 't', 0, 0, 1, 0, aDot, 0, 0, m_cmd,
27 76193d7c 2003-09-30 devnull 'u', 0, 0, 0, 0, aNo, 2, 0, u_cmd,
28 76193d7c 2003-09-30 devnull 'v', 0, 1, 0, 'p', aDot, 0, 0, g_cmd,
29 76193d7c 2003-09-30 devnull 'w', 0, 0, 0, 0, aAll, 0, wordx, w_cmd,
30 76193d7c 2003-09-30 devnull 'x', 0, 1, 0, 'p', aDot, 0, 0, x_cmd,
31 76193d7c 2003-09-30 devnull 'y', 0, 1, 0, 'p', aDot, 0, 0, x_cmd,
32 76193d7c 2003-09-30 devnull 'X', 0, 1, 0, 'f', aNo, 0, 0, X_cmd,
33 76193d7c 2003-09-30 devnull 'Y', 0, 1, 0, 'f', aNo, 0, 0, X_cmd,
34 76193d7c 2003-09-30 devnull '!', 0, 0, 0, 0, aNo, 0, linex, plan9_cmd,
35 76193d7c 2003-09-30 devnull '>', 0, 0, 0, 0, aDot, 0, linex, plan9_cmd,
36 76193d7c 2003-09-30 devnull '<', 0, 0, 0, 0, aDot, 0, linex, plan9_cmd,
37 76193d7c 2003-09-30 devnull '|', 0, 0, 0, 0, aDot, 0, linex, plan9_cmd,
38 76193d7c 2003-09-30 devnull '=', 0, 0, 0, 0, aDot, 0, linex, eq_cmd,
39 76193d7c 2003-09-30 devnull 'c'|0x100,0, 0, 0, 0, aNo, 0, wordx, cd_cmd,
40 76193d7c 2003-09-30 devnull 0, 0, 0, 0, 0, 0, 0, 0,
41 76193d7c 2003-09-30 devnull };
42 76193d7c 2003-09-30 devnull Cmd *parsecmd(int);
43 76193d7c 2003-09-30 devnull Addr *compoundaddr(void);
44 76193d7c 2003-09-30 devnull Addr *simpleaddr(void);
45 76193d7c 2003-09-30 devnull void freecmd(void);
46 76193d7c 2003-09-30 devnull void okdelim(int);
47 76193d7c 2003-09-30 devnull
48 76193d7c 2003-09-30 devnull Rune line[BLOCKSIZE];
49 76193d7c 2003-09-30 devnull Rune termline[BLOCKSIZE];
50 76193d7c 2003-09-30 devnull Rune *linep = line;
51 76193d7c 2003-09-30 devnull Rune *terminp = termline;
52 76193d7c 2003-09-30 devnull Rune *termoutp = termline;
53 76193d7c 2003-09-30 devnull List cmdlist;
54 76193d7c 2003-09-30 devnull List addrlist;
55 76193d7c 2003-09-30 devnull List relist;
56 76193d7c 2003-09-30 devnull List stringlist;
57 76193d7c 2003-09-30 devnull int eof;
58 76193d7c 2003-09-30 devnull
59 76193d7c 2003-09-30 devnull void
60 76193d7c 2003-09-30 devnull resetcmd(void)
61 76193d7c 2003-09-30 devnull {
62 76193d7c 2003-09-30 devnull linep = line;
63 76193d7c 2003-09-30 devnull *linep = 0;
64 76193d7c 2003-09-30 devnull terminp = termoutp = termline;
65 76193d7c 2003-09-30 devnull freecmd();
66 76193d7c 2003-09-30 devnull }
67 76193d7c 2003-09-30 devnull
68 76193d7c 2003-09-30 devnull int
69 76193d7c 2003-09-30 devnull inputc(void)
70 76193d7c 2003-09-30 devnull {
71 76193d7c 2003-09-30 devnull int n, nbuf;
72 76193d7c 2003-09-30 devnull char buf[3];
73 76193d7c 2003-09-30 devnull Rune r;
74 76193d7c 2003-09-30 devnull
75 76193d7c 2003-09-30 devnull Again:
76 76193d7c 2003-09-30 devnull nbuf = 0;
77 76193d7c 2003-09-30 devnull if(downloaded){
78 76193d7c 2003-09-30 devnull while(termoutp == terminp){
79 76193d7c 2003-09-30 devnull cmdupdate();
80 76193d7c 2003-09-30 devnull if(patset)
81 76193d7c 2003-09-30 devnull tellpat();
82 76193d7c 2003-09-30 devnull while(termlocked > 0){
83 76193d7c 2003-09-30 devnull outT0(Hunlock);
84 76193d7c 2003-09-30 devnull termlocked--;
85 76193d7c 2003-09-30 devnull }
86 76193d7c 2003-09-30 devnull if(rcv() == 0)
87 76193d7c 2003-09-30 devnull return -1;
88 76193d7c 2003-09-30 devnull }
89 76193d7c 2003-09-30 devnull r = *termoutp++;
90 76193d7c 2003-09-30 devnull if(termoutp == terminp)
91 76193d7c 2003-09-30 devnull terminp = termoutp = termline;
92 76193d7c 2003-09-30 devnull }else{
93 76193d7c 2003-09-30 devnull do{
94 76193d7c 2003-09-30 devnull n = read(0, buf+nbuf, 1);
95 76193d7c 2003-09-30 devnull if(n <= 0)
96 76193d7c 2003-09-30 devnull return -1;
97 76193d7c 2003-09-30 devnull nbuf += n;
98 76193d7c 2003-09-30 devnull }while(!fullrune(buf, nbuf));
99 76193d7c 2003-09-30 devnull chartorune(&r, buf);
100 76193d7c 2003-09-30 devnull }
101 76193d7c 2003-09-30 devnull if(r == 0){
102 76193d7c 2003-09-30 devnull warn(Wnulls);
103 76193d7c 2003-09-30 devnull goto Again;
104 76193d7c 2003-09-30 devnull }
105 76193d7c 2003-09-30 devnull return r;
106 76193d7c 2003-09-30 devnull }
107 76193d7c 2003-09-30 devnull
108 76193d7c 2003-09-30 devnull int
109 76193d7c 2003-09-30 devnull inputline(void)
110 76193d7c 2003-09-30 devnull {
111 76193d7c 2003-09-30 devnull int i, c;
112 76193d7c 2003-09-30 devnull
113 76193d7c 2003-09-30 devnull linep = line;
114 76193d7c 2003-09-30 devnull i = 0;
115 76193d7c 2003-09-30 devnull do{
116 76193d7c 2003-09-30 devnull if((c = inputc())<=0)
117 76193d7c 2003-09-30 devnull return -1;
118 76193d7c 2003-09-30 devnull if(i == (sizeof line)/RUNESIZE-1)
119 76193d7c 2003-09-30 devnull error(Etoolong);
120 76193d7c 2003-09-30 devnull }while((line[i++]=c) != '\n');
121 76193d7c 2003-09-30 devnull line[i] = 0;
122 76193d7c 2003-09-30 devnull return 1;
123 76193d7c 2003-09-30 devnull }
124 76193d7c 2003-09-30 devnull
125 76193d7c 2003-09-30 devnull int
126 76193d7c 2003-09-30 devnull getch(void)
127 76193d7c 2003-09-30 devnull {
128 76193d7c 2003-09-30 devnull if(eof)
129 76193d7c 2003-09-30 devnull return -1;
130 76193d7c 2003-09-30 devnull if(*linep==0 && inputline()<0){
131 76193d7c 2003-09-30 devnull eof = TRUE;
132 76193d7c 2003-09-30 devnull return -1;
133 76193d7c 2003-09-30 devnull }
134 76193d7c 2003-09-30 devnull return *linep++;
135 76193d7c 2003-09-30 devnull }
136 76193d7c 2003-09-30 devnull
137 76193d7c 2003-09-30 devnull int
138 76193d7c 2003-09-30 devnull nextc(void)
139 76193d7c 2003-09-30 devnull {
140 76193d7c 2003-09-30 devnull if(*linep == 0)
141 76193d7c 2003-09-30 devnull return -1;
142 76193d7c 2003-09-30 devnull return *linep;
143 76193d7c 2003-09-30 devnull }
144 76193d7c 2003-09-30 devnull
145 76193d7c 2003-09-30 devnull void
146 76193d7c 2003-09-30 devnull ungetch(void)
147 76193d7c 2003-09-30 devnull {
148 76193d7c 2003-09-30 devnull if(--linep < line)
149 76193d7c 2003-09-30 devnull panic("ungetch");
150 76193d7c 2003-09-30 devnull }
151 76193d7c 2003-09-30 devnull
152 76193d7c 2003-09-30 devnull Posn
153 76193d7c 2003-09-30 devnull getnum(int signok)
154 76193d7c 2003-09-30 devnull {
155 76193d7c 2003-09-30 devnull Posn n=0;
156 76193d7c 2003-09-30 devnull int c, sign;
157 76193d7c 2003-09-30 devnull
158 76193d7c 2003-09-30 devnull sign = 1;
159 76193d7c 2003-09-30 devnull if(signok>1 && nextc()=='-'){
160 76193d7c 2003-09-30 devnull sign = -1;
161 76193d7c 2003-09-30 devnull getch();
162 76193d7c 2003-09-30 devnull }
163 76193d7c 2003-09-30 devnull if((c=nextc())<'0' || '9'<c) /* no number defaults to 1 */
164 76193d7c 2003-09-30 devnull return sign;
165 76193d7c 2003-09-30 devnull while('0'<=(c=getch()) && c<='9')
166 76193d7c 2003-09-30 devnull n = n*10 + (c-'0');
167 76193d7c 2003-09-30 devnull ungetch();
168 76193d7c 2003-09-30 devnull return sign*n;
169 76193d7c 2003-09-30 devnull }
170 76193d7c 2003-09-30 devnull
171 76193d7c 2003-09-30 devnull int
172 76193d7c 2003-09-30 devnull skipbl(void)
173 76193d7c 2003-09-30 devnull {
174 76193d7c 2003-09-30 devnull int c;
175 76193d7c 2003-09-30 devnull do
176 76193d7c 2003-09-30 devnull c = getch();
177 76193d7c 2003-09-30 devnull while(c==' ' || c=='\t');
178 76193d7c 2003-09-30 devnull if(c >= 0)
179 76193d7c 2003-09-30 devnull ungetch();
180 76193d7c 2003-09-30 devnull return c;
181 76193d7c 2003-09-30 devnull }
182 76193d7c 2003-09-30 devnull
183 76193d7c 2003-09-30 devnull void
184 76193d7c 2003-09-30 devnull termcommand(void)
185 76193d7c 2003-09-30 devnull {
186 76193d7c 2003-09-30 devnull Posn p;
187 76193d7c 2003-09-30 devnull
188 522b0689 2003-09-30 devnull for(p=cmdpt; p<cmd->b.nc; p++){
189 76193d7c 2003-09-30 devnull if(terminp >= &termline[BLOCKSIZE]){
190 522b0689 2003-09-30 devnull cmdpt = cmd->b.nc;
191 76193d7c 2003-09-30 devnull error(Etoolong);
192 76193d7c 2003-09-30 devnull }
193 76193d7c 2003-09-30 devnull *terminp++ = filereadc(cmd, p);
194 76193d7c 2003-09-30 devnull }
195 522b0689 2003-09-30 devnull cmdpt = cmd->b.nc;
196 76193d7c 2003-09-30 devnull }
197 76193d7c 2003-09-30 devnull
198 76193d7c 2003-09-30 devnull void
199 76193d7c 2003-09-30 devnull cmdloop(void)
200 76193d7c 2003-09-30 devnull {
201 76193d7c 2003-09-30 devnull Cmd *cmdp;
202 76193d7c 2003-09-30 devnull File *ocurfile;
203 76193d7c 2003-09-30 devnull int loaded;
204 76193d7c 2003-09-30 devnull
205 76193d7c 2003-09-30 devnull for(;;){
206 76193d7c 2003-09-30 devnull if(!downloaded && curfile && curfile->unread)
207 76193d7c 2003-09-30 devnull load(curfile);
208 76193d7c 2003-09-30 devnull if((cmdp = parsecmd(0))==0){
209 76193d7c 2003-09-30 devnull if(downloaded){
210 76193d7c 2003-09-30 devnull rescue();
211 76193d7c 2003-09-30 devnull exits("eof");
212 76193d7c 2003-09-30 devnull }
213 76193d7c 2003-09-30 devnull break;
214 76193d7c 2003-09-30 devnull }
215 76193d7c 2003-09-30 devnull ocurfile = curfile;
216 76193d7c 2003-09-30 devnull loaded = curfile && !curfile->unread;
217 76193d7c 2003-09-30 devnull if(cmdexec(curfile, cmdp) == 0)
218 76193d7c 2003-09-30 devnull break;
219 76193d7c 2003-09-30 devnull freecmd();
220 76193d7c 2003-09-30 devnull cmdupdate();
221 76193d7c 2003-09-30 devnull update();
222 76193d7c 2003-09-30 devnull if(downloaded && curfile &&
223 76193d7c 2003-09-30 devnull (ocurfile!=curfile || (!loaded && !curfile->unread)))
224 76193d7c 2003-09-30 devnull outTs(Hcurrent, curfile->tag);
225 76193d7c 2003-09-30 devnull /* don't allow type ahead on files that aren't bound */
226 76193d7c 2003-09-30 devnull if(downloaded && curfile && curfile->rasp == 0)
227 76193d7c 2003-09-30 devnull terminp = termoutp;
228 76193d7c 2003-09-30 devnull }
229 76193d7c 2003-09-30 devnull }
230 76193d7c 2003-09-30 devnull
231 76193d7c 2003-09-30 devnull Cmd *
232 76193d7c 2003-09-30 devnull newcmd(void){
233 76193d7c 2003-09-30 devnull Cmd *p;
234 76193d7c 2003-09-30 devnull
235 76193d7c 2003-09-30 devnull p = emalloc(sizeof(Cmd));
236 76193d7c 2003-09-30 devnull inslist(&cmdlist, cmdlist.nused, (long)p);
237 76193d7c 2003-09-30 devnull return p;
238 76193d7c 2003-09-30 devnull }
239 76193d7c 2003-09-30 devnull
240 76193d7c 2003-09-30 devnull Addr*
241 76193d7c 2003-09-30 devnull newaddr(void)
242 76193d7c 2003-09-30 devnull {
243 76193d7c 2003-09-30 devnull Addr *p;
244 76193d7c 2003-09-30 devnull
245 76193d7c 2003-09-30 devnull p = emalloc(sizeof(Addr));
246 76193d7c 2003-09-30 devnull inslist(&addrlist, addrlist.nused, (long)p);
247 76193d7c 2003-09-30 devnull return p;
248 76193d7c 2003-09-30 devnull }
249 76193d7c 2003-09-30 devnull
250 76193d7c 2003-09-30 devnull String*
251 76193d7c 2003-09-30 devnull newre(void)
252 76193d7c 2003-09-30 devnull {
253 76193d7c 2003-09-30 devnull String *p;
254 76193d7c 2003-09-30 devnull
255 76193d7c 2003-09-30 devnull p = emalloc(sizeof(String));
256 76193d7c 2003-09-30 devnull inslist(&relist, relist.nused, (long)p);
257 76193d7c 2003-09-30 devnull Strinit(p);
258 76193d7c 2003-09-30 devnull return p;
259 76193d7c 2003-09-30 devnull }
260 76193d7c 2003-09-30 devnull
261 76193d7c 2003-09-30 devnull String*
262 76193d7c 2003-09-30 devnull newstring(void)
263 76193d7c 2003-09-30 devnull {
264 76193d7c 2003-09-30 devnull String *p;
265 76193d7c 2003-09-30 devnull
266 76193d7c 2003-09-30 devnull p = emalloc(sizeof(String));
267 76193d7c 2003-09-30 devnull inslist(&stringlist, stringlist.nused, (long)p);
268 76193d7c 2003-09-30 devnull Strinit(p);
269 76193d7c 2003-09-30 devnull return p;
270 76193d7c 2003-09-30 devnull }
271 76193d7c 2003-09-30 devnull
272 76193d7c 2003-09-30 devnull void
273 76193d7c 2003-09-30 devnull freecmd(void)
274 76193d7c 2003-09-30 devnull {
275 76193d7c 2003-09-30 devnull int i;
276 76193d7c 2003-09-30 devnull
277 76193d7c 2003-09-30 devnull while(cmdlist.nused > 0)
278 76193d7c 2003-09-30 devnull free(cmdlist.ucharpptr[--cmdlist.nused]);
279 76193d7c 2003-09-30 devnull while(addrlist.nused > 0)
280 76193d7c 2003-09-30 devnull free(addrlist.ucharpptr[--addrlist.nused]);
281 76193d7c 2003-09-30 devnull while(relist.nused > 0){
282 76193d7c 2003-09-30 devnull i = --relist.nused;
283 76193d7c 2003-09-30 devnull Strclose(relist.stringpptr[i]);
284 76193d7c 2003-09-30 devnull free(relist.stringpptr[i]);
285 76193d7c 2003-09-30 devnull }
286 76193d7c 2003-09-30 devnull while(stringlist.nused>0){
287 76193d7c 2003-09-30 devnull i = --stringlist.nused;
288 76193d7c 2003-09-30 devnull Strclose(stringlist.stringpptr[i]);
289 76193d7c 2003-09-30 devnull free(stringlist.stringpptr[i]);
290 76193d7c 2003-09-30 devnull }
291 76193d7c 2003-09-30 devnull }
292 76193d7c 2003-09-30 devnull
293 76193d7c 2003-09-30 devnull int
294 76193d7c 2003-09-30 devnull lookup(int c)
295 76193d7c 2003-09-30 devnull {
296 76193d7c 2003-09-30 devnull int i;
297 76193d7c 2003-09-30 devnull
298 76193d7c 2003-09-30 devnull for(i=0; cmdtab[i].cmdc; i++)
299 76193d7c 2003-09-30 devnull if(cmdtab[i].cmdc == c)
300 76193d7c 2003-09-30 devnull return i;
301 76193d7c 2003-09-30 devnull return -1;
302 76193d7c 2003-09-30 devnull }
303 76193d7c 2003-09-30 devnull
304 76193d7c 2003-09-30 devnull void
305 76193d7c 2003-09-30 devnull okdelim(int c)
306 76193d7c 2003-09-30 devnull {
307 76193d7c 2003-09-30 devnull if(c=='\\' || ('a'<=c && c<='z')
308 76193d7c 2003-09-30 devnull || ('A'<=c && c<='Z') || ('0'<=c && c<='9'))
309 76193d7c 2003-09-30 devnull error_c(Edelim, c);
310 76193d7c 2003-09-30 devnull }
311 76193d7c 2003-09-30 devnull
312 76193d7c 2003-09-30 devnull void
313 76193d7c 2003-09-30 devnull atnl(void)
314 76193d7c 2003-09-30 devnull {
315 76193d7c 2003-09-30 devnull skipbl();
316 76193d7c 2003-09-30 devnull if(getch() != '\n')
317 76193d7c 2003-09-30 devnull error(Enewline);
318 76193d7c 2003-09-30 devnull }
319 76193d7c 2003-09-30 devnull
320 76193d7c 2003-09-30 devnull void
321 76193d7c 2003-09-30 devnull getrhs(String *s, int delim, int cmd)
322 76193d7c 2003-09-30 devnull {
323 76193d7c 2003-09-30 devnull int c;
324 76193d7c 2003-09-30 devnull
325 76193d7c 2003-09-30 devnull while((c = getch())>0 && c!=delim && c!='\n'){
326 76193d7c 2003-09-30 devnull if(c == '\\'){
327 76193d7c 2003-09-30 devnull if((c=getch()) <= 0)
328 76193d7c 2003-09-30 devnull error(Ebadrhs);
329 76193d7c 2003-09-30 devnull if(c == '\n'){
330 76193d7c 2003-09-30 devnull ungetch();
331 76193d7c 2003-09-30 devnull c='\\';
332 76193d7c 2003-09-30 devnull }else if(c == 'n')
333 76193d7c 2003-09-30 devnull c='\n';
334 76193d7c 2003-09-30 devnull else if(c!=delim && (cmd=='s' || c!='\\')) /* s does its own */
335 76193d7c 2003-09-30 devnull Straddc(s, '\\');
336 76193d7c 2003-09-30 devnull }
337 76193d7c 2003-09-30 devnull Straddc(s, c);
338 76193d7c 2003-09-30 devnull }
339 76193d7c 2003-09-30 devnull ungetch(); /* let client read whether delimeter, '\n' or whatever */
340 76193d7c 2003-09-30 devnull }
341 76193d7c 2003-09-30 devnull
342 76193d7c 2003-09-30 devnull String *
343 76193d7c 2003-09-30 devnull collecttoken(char *end)
344 76193d7c 2003-09-30 devnull {
345 76193d7c 2003-09-30 devnull String *s = newstring();
346 76193d7c 2003-09-30 devnull int c;
347 76193d7c 2003-09-30 devnull
348 76193d7c 2003-09-30 devnull while((c=nextc())==' ' || c=='\t')
349 76193d7c 2003-09-30 devnull Straddc(s, getch()); /* blanks significant for getname() */
350 76193d7c 2003-09-30 devnull while((c=getch())>0 && utfrune(end, c)==0)
351 76193d7c 2003-09-30 devnull Straddc(s, c);
352 76193d7c 2003-09-30 devnull Straddc(s, 0);
353 76193d7c 2003-09-30 devnull if(c != '\n')
354 76193d7c 2003-09-30 devnull atnl();
355 76193d7c 2003-09-30 devnull return s;
356 76193d7c 2003-09-30 devnull }
357 76193d7c 2003-09-30 devnull
358 76193d7c 2003-09-30 devnull String *
359 76193d7c 2003-09-30 devnull collecttext(void)
360 76193d7c 2003-09-30 devnull {
361 76193d7c 2003-09-30 devnull String *s = newstring();
362 76193d7c 2003-09-30 devnull int begline, i, c, delim;
363 76193d7c 2003-09-30 devnull
364 76193d7c 2003-09-30 devnull if(skipbl()=='\n'){
365 76193d7c 2003-09-30 devnull getch();
366 76193d7c 2003-09-30 devnull i = 0;
367 76193d7c 2003-09-30 devnull do{
368 76193d7c 2003-09-30 devnull begline = i;
369 76193d7c 2003-09-30 devnull while((c = getch())>0 && c!='\n')
370 76193d7c 2003-09-30 devnull i++, Straddc(s, c);
371 76193d7c 2003-09-30 devnull i++, Straddc(s, '\n');
372 76193d7c 2003-09-30 devnull if(c < 0)
373 76193d7c 2003-09-30 devnull goto Return;
374 76193d7c 2003-09-30 devnull }while(s->s[begline]!='.' || s->s[begline+1]!='\n');
375 76193d7c 2003-09-30 devnull Strdelete(s, s->n-2, s->n);
376 76193d7c 2003-09-30 devnull }else{
377 76193d7c 2003-09-30 devnull okdelim(delim = getch());
378 76193d7c 2003-09-30 devnull getrhs(s, delim, 'a');
379 76193d7c 2003-09-30 devnull if(nextc()==delim)
380 76193d7c 2003-09-30 devnull getch();
381 76193d7c 2003-09-30 devnull atnl();
382 76193d7c 2003-09-30 devnull }
383 76193d7c 2003-09-30 devnull Return:
384 76193d7c 2003-09-30 devnull Straddc(s, 0); /* JUST FOR CMDPRINT() */
385 76193d7c 2003-09-30 devnull return s;
386 76193d7c 2003-09-30 devnull }
387 76193d7c 2003-09-30 devnull
388 76193d7c 2003-09-30 devnull Cmd *
389 76193d7c 2003-09-30 devnull parsecmd(int nest)
390 76193d7c 2003-09-30 devnull {
391 76193d7c 2003-09-30 devnull int i, c;
392 76193d7c 2003-09-30 devnull struct cmdtab *ct;
393 76193d7c 2003-09-30 devnull Cmd *cp, *ncp;
394 76193d7c 2003-09-30 devnull Cmd cmd;
395 76193d7c 2003-09-30 devnull
396 76193d7c 2003-09-30 devnull cmd.next = cmd.ccmd = 0;
397 76193d7c 2003-09-30 devnull cmd.re = 0;
398 76193d7c 2003-09-30 devnull cmd.flag = cmd.num = 0;
399 76193d7c 2003-09-30 devnull cmd.addr = compoundaddr();
400 76193d7c 2003-09-30 devnull if(skipbl() == -1)
401 76193d7c 2003-09-30 devnull return 0;
402 76193d7c 2003-09-30 devnull if((c=getch())==-1)
403 76193d7c 2003-09-30 devnull return 0;
404 76193d7c 2003-09-30 devnull cmd.cmdc = c;
405 76193d7c 2003-09-30 devnull if(cmd.cmdc=='c' && nextc()=='d'){ /* sleazy two-character case */
406 76193d7c 2003-09-30 devnull getch(); /* the 'd' */
407 76193d7c 2003-09-30 devnull cmd.cmdc='c'|0x100;
408 76193d7c 2003-09-30 devnull }
409 76193d7c 2003-09-30 devnull i = lookup(cmd.cmdc);
410 76193d7c 2003-09-30 devnull if(i >= 0){
411 76193d7c 2003-09-30 devnull if(cmd.cmdc == '\n')
412 76193d7c 2003-09-30 devnull goto Return; /* let nl_cmd work it all out */
413 76193d7c 2003-09-30 devnull ct = &cmdtab[i];
414 76193d7c 2003-09-30 devnull if(ct->defaddr==aNo && cmd.addr)
415 76193d7c 2003-09-30 devnull error(Enoaddr);
416 76193d7c 2003-09-30 devnull if(ct->count)
417 76193d7c 2003-09-30 devnull cmd.num = getnum(ct->count);
418 76193d7c 2003-09-30 devnull if(ct->regexp){
419 76193d7c 2003-09-30 devnull /* x without pattern -> .*\n, indicated by cmd.re==0 */
420 76193d7c 2003-09-30 devnull /* X without pattern is all files */
421 76193d7c 2003-09-30 devnull if((ct->cmdc!='x' && ct->cmdc!='X') ||
422 76193d7c 2003-09-30 devnull ((c = nextc())!=' ' && c!='\t' && c!='\n')){
423 76193d7c 2003-09-30 devnull skipbl();
424 76193d7c 2003-09-30 devnull if((c = getch())=='\n' || c<0)
425 76193d7c 2003-09-30 devnull error(Enopattern);
426 76193d7c 2003-09-30 devnull okdelim(c);
427 76193d7c 2003-09-30 devnull cmd.re = getregexp(c);
428 76193d7c 2003-09-30 devnull if(ct->cmdc == 's'){
429 76193d7c 2003-09-30 devnull cmd.ctext = newstring();
430 76193d7c 2003-09-30 devnull getrhs(cmd.ctext, c, 's');
431 76193d7c 2003-09-30 devnull if(nextc() == c){
432 76193d7c 2003-09-30 devnull getch();
433 76193d7c 2003-09-30 devnull if(nextc() == 'g')
434 76193d7c 2003-09-30 devnull cmd.flag = getch();
435 76193d7c 2003-09-30 devnull }
436 76193d7c 2003-09-30 devnull
437 76193d7c 2003-09-30 devnull }
438 76193d7c 2003-09-30 devnull }
439 76193d7c 2003-09-30 devnull }
440 76193d7c 2003-09-30 devnull if(ct->addr && (cmd.caddr=simpleaddr())==0)
441 76193d7c 2003-09-30 devnull error(Eaddress);
442 76193d7c 2003-09-30 devnull if(ct->defcmd){
443 76193d7c 2003-09-30 devnull if(skipbl() == '\n'){
444 76193d7c 2003-09-30 devnull getch();
445 76193d7c 2003-09-30 devnull cmd.ccmd = newcmd();
446 76193d7c 2003-09-30 devnull cmd.ccmd->cmdc = ct->defcmd;
447 76193d7c 2003-09-30 devnull }else if((cmd.ccmd = parsecmd(nest))==0)
448 76193d7c 2003-09-30 devnull panic("defcmd");
449 76193d7c 2003-09-30 devnull }else if(ct->text)
450 76193d7c 2003-09-30 devnull cmd.ctext = collecttext();
451 76193d7c 2003-09-30 devnull else if(ct->token)
452 76193d7c 2003-09-30 devnull cmd.ctext = collecttoken(ct->token);
453 76193d7c 2003-09-30 devnull else
454 76193d7c 2003-09-30 devnull atnl();
455 76193d7c 2003-09-30 devnull }else
456 76193d7c 2003-09-30 devnull switch(cmd.cmdc){
457 76193d7c 2003-09-30 devnull case '{':
458 76193d7c 2003-09-30 devnull cp = 0;
459 76193d7c 2003-09-30 devnull do{
460 76193d7c 2003-09-30 devnull if(skipbl()=='\n')
461 76193d7c 2003-09-30 devnull getch();
462 76193d7c 2003-09-30 devnull ncp = parsecmd(nest+1);
463 76193d7c 2003-09-30 devnull if(cp)
464 76193d7c 2003-09-30 devnull cp->next = ncp;
465 76193d7c 2003-09-30 devnull else
466 76193d7c 2003-09-30 devnull cmd.ccmd = ncp;
467 76193d7c 2003-09-30 devnull }while(cp = ncp);
468 76193d7c 2003-09-30 devnull break;
469 76193d7c 2003-09-30 devnull case '}':
470 76193d7c 2003-09-30 devnull atnl();
471 76193d7c 2003-09-30 devnull if(nest==0)
472 76193d7c 2003-09-30 devnull error(Enolbrace);
473 76193d7c 2003-09-30 devnull return 0;
474 76193d7c 2003-09-30 devnull default:
475 76193d7c 2003-09-30 devnull error_c(Eunk, cmd.cmdc);
476 76193d7c 2003-09-30 devnull }
477 76193d7c 2003-09-30 devnull Return:
478 76193d7c 2003-09-30 devnull cp = newcmd();
479 76193d7c 2003-09-30 devnull *cp = cmd;
480 76193d7c 2003-09-30 devnull return cp;
481 76193d7c 2003-09-30 devnull }
482 76193d7c 2003-09-30 devnull
483 76193d7c 2003-09-30 devnull String* /* BUGGERED */
484 76193d7c 2003-09-30 devnull getregexp(int delim)
485 76193d7c 2003-09-30 devnull {
486 76193d7c 2003-09-30 devnull String *r = newre();
487 76193d7c 2003-09-30 devnull int c;
488 76193d7c 2003-09-30 devnull
489 76193d7c 2003-09-30 devnull for(Strzero(&genstr); ; Straddc(&genstr, c))
490 76193d7c 2003-09-30 devnull if((c = getch())=='\\'){
491 76193d7c 2003-09-30 devnull if(nextc()==delim)
492 76193d7c 2003-09-30 devnull c = getch();
493 76193d7c 2003-09-30 devnull else if(nextc()=='\\'){
494 76193d7c 2003-09-30 devnull Straddc(&genstr, c);
495 76193d7c 2003-09-30 devnull c = getch();
496 76193d7c 2003-09-30 devnull }
497 76193d7c 2003-09-30 devnull }else if(c==delim || c=='\n')
498 76193d7c 2003-09-30 devnull break;
499 76193d7c 2003-09-30 devnull if(c!=delim && c)
500 76193d7c 2003-09-30 devnull ungetch();
501 76193d7c 2003-09-30 devnull if(genstr.n > 0){
502 76193d7c 2003-09-30 devnull patset = TRUE;
503 76193d7c 2003-09-30 devnull Strduplstr(&lastpat, &genstr);
504 76193d7c 2003-09-30 devnull Straddc(&lastpat, '\0');
505 76193d7c 2003-09-30 devnull }
506 76193d7c 2003-09-30 devnull if(lastpat.n <= 1)
507 76193d7c 2003-09-30 devnull error(Epattern);
508 76193d7c 2003-09-30 devnull Strduplstr(r, &lastpat);
509 76193d7c 2003-09-30 devnull return r;
510 76193d7c 2003-09-30 devnull }
511 76193d7c 2003-09-30 devnull
512 76193d7c 2003-09-30 devnull Addr *
513 76193d7c 2003-09-30 devnull simpleaddr(void)
514 76193d7c 2003-09-30 devnull {
515 76193d7c 2003-09-30 devnull Addr addr;
516 76193d7c 2003-09-30 devnull Addr *ap, *nap;
517 76193d7c 2003-09-30 devnull
518 76193d7c 2003-09-30 devnull addr.next = 0;
519 76193d7c 2003-09-30 devnull addr.left = 0;
520 76193d7c 2003-09-30 devnull switch(skipbl()){
521 76193d7c 2003-09-30 devnull case '#':
522 76193d7c 2003-09-30 devnull addr.type = getch();
523 76193d7c 2003-09-30 devnull addr.num = getnum(1);
524 76193d7c 2003-09-30 devnull break;
525 76193d7c 2003-09-30 devnull case '0': case '1': case '2': case '3': case '4':
526 76193d7c 2003-09-30 devnull case '5': case '6': case '7': case '8': case '9':
527 76193d7c 2003-09-30 devnull addr.num = getnum(1);
528 76193d7c 2003-09-30 devnull addr.type='l';
529 76193d7c 2003-09-30 devnull break;
530 76193d7c 2003-09-30 devnull case '/': case '?': case '"':
531 76193d7c 2003-09-30 devnull addr.are = getregexp(addr.type = getch());
532 76193d7c 2003-09-30 devnull break;
533 76193d7c 2003-09-30 devnull case '.':
534 76193d7c 2003-09-30 devnull case '$':
535 76193d7c 2003-09-30 devnull case '+':
536 76193d7c 2003-09-30 devnull case '-':
537 76193d7c 2003-09-30 devnull case '\'':
538 76193d7c 2003-09-30 devnull addr.type = getch();
539 76193d7c 2003-09-30 devnull break;
540 76193d7c 2003-09-30 devnull default:
541 76193d7c 2003-09-30 devnull return 0;
542 76193d7c 2003-09-30 devnull }
543 76193d7c 2003-09-30 devnull if(addr.next = simpleaddr())
544 76193d7c 2003-09-30 devnull switch(addr.next->type){
545 76193d7c 2003-09-30 devnull case '.':
546 76193d7c 2003-09-30 devnull case '$':
547 76193d7c 2003-09-30 devnull case '\'':
548 76193d7c 2003-09-30 devnull if(addr.type!='"')
549 76193d7c 2003-09-30 devnull case '"':
550 76193d7c 2003-09-30 devnull error(Eaddress);
551 76193d7c 2003-09-30 devnull break;
552 76193d7c 2003-09-30 devnull case 'l':
553 76193d7c 2003-09-30 devnull case '#':
554 76193d7c 2003-09-30 devnull if(addr.type=='"')
555 76193d7c 2003-09-30 devnull break;
556 76193d7c 2003-09-30 devnull /* fall through */
557 76193d7c 2003-09-30 devnull case '/':
558 76193d7c 2003-09-30 devnull case '?':
559 76193d7c 2003-09-30 devnull if(addr.type!='+' && addr.type!='-'){
560 76193d7c 2003-09-30 devnull /* insert the missing '+' */
561 76193d7c 2003-09-30 devnull nap = newaddr();
562 76193d7c 2003-09-30 devnull nap->type='+';
563 76193d7c 2003-09-30 devnull nap->next = addr.next;
564 76193d7c 2003-09-30 devnull addr.next = nap;
565 76193d7c 2003-09-30 devnull }
566 76193d7c 2003-09-30 devnull break;
567 76193d7c 2003-09-30 devnull case '+':
568 76193d7c 2003-09-30 devnull case '-':
569 76193d7c 2003-09-30 devnull break;
570 76193d7c 2003-09-30 devnull default:
571 76193d7c 2003-09-30 devnull panic("simpleaddr");
572 76193d7c 2003-09-30 devnull }
573 76193d7c 2003-09-30 devnull ap = newaddr();
574 76193d7c 2003-09-30 devnull *ap = addr;
575 76193d7c 2003-09-30 devnull return ap;
576 76193d7c 2003-09-30 devnull }
577 76193d7c 2003-09-30 devnull
578 76193d7c 2003-09-30 devnull Addr *
579 76193d7c 2003-09-30 devnull compoundaddr(void)
580 76193d7c 2003-09-30 devnull {
581 76193d7c 2003-09-30 devnull Addr addr;
582 76193d7c 2003-09-30 devnull Addr *ap, *next;
583 76193d7c 2003-09-30 devnull
584 76193d7c 2003-09-30 devnull addr.left = simpleaddr();
585 76193d7c 2003-09-30 devnull if((addr.type = skipbl())!=',' && addr.type!=';')
586 76193d7c 2003-09-30 devnull return addr.left;
587 76193d7c 2003-09-30 devnull getch();
588 76193d7c 2003-09-30 devnull next = addr.next = compoundaddr();
589 76193d7c 2003-09-30 devnull if(next && (next->type==',' || next->type==';') && next->left==0)
590 76193d7c 2003-09-30 devnull error(Eaddress);
591 76193d7c 2003-09-30 devnull ap = newaddr();
592 76193d7c 2003-09-30 devnull *ap = addr;
593 76193d7c 2003-09-30 devnull return ap;
594 76193d7c 2003-09-30 devnull }