1 76193d7c 2003-09-30 devnull #include "sam.h"
2 76193d7c 2003-09-30 devnull #include "parse.h"
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,
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);
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;
60 76193d7c 2003-09-30 devnull resetcmd(void)
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();
69 76193d7c 2003-09-30 devnull inputc(void)
71 76193d7c 2003-09-30 devnull int n, nbuf;
72 76193d7c 2003-09-30 devnull char buf[3];
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--;
86 76193d7c 2003-09-30 devnull if(rcv() == 0)
87 76193d7c 2003-09-30 devnull return -1;
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;
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);
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;
105 76193d7c 2003-09-30 devnull return r;
109 76193d7c 2003-09-30 devnull inputline(void)
111 76193d7c 2003-09-30 devnull int i, c;
113 76193d7c 2003-09-30 devnull linep = line;
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;
126 76193d7c 2003-09-30 devnull getch(void)
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;
134 76193d7c 2003-09-30 devnull return *linep++;
138 76193d7c 2003-09-30 devnull nextc(void)
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;
146 76193d7c 2003-09-30 devnull ungetch(void)
148 76193d7c 2003-09-30 devnull if(--linep < line)
149 76193d7c 2003-09-30 devnull panic("ungetch");
153 76193d7c 2003-09-30 devnull getnum(int signok)
155 76193d7c 2003-09-30 devnull Posn n=0;
156 76193d7c 2003-09-30 devnull int c, sign;
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();
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;
172 76193d7c 2003-09-30 devnull skipbl(void)
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;
184 76193d7c 2003-09-30 devnull termcommand(void)
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);
193 76193d7c 2003-09-30 devnull *terminp++ = filereadc(cmd, p);
195 522b0689 2003-09-30 devnull cmdpt = cmd->b.nc;
199 76193d7c 2003-09-30 devnull cmdloop(void)
201 76193d7c 2003-09-30 devnull Cmd *cmdp;
202 76193d7c 2003-09-30 devnull File *ocurfile;
203 76193d7c 2003-09-30 devnull int loaded;
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");
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)
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;
232 76193d7c 2003-09-30 devnull newcmd(void){
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;
241 76193d7c 2003-09-30 devnull newaddr(void)
243 76193d7c 2003-09-30 devnull Addr *p;
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;
251 76193d7c 2003-09-30 devnull newre(void)
253 76193d7c 2003-09-30 devnull String *p;
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;
262 76193d7c 2003-09-30 devnull newstring(void)
264 76193d7c 2003-09-30 devnull String *p;
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;
273 76193d7c 2003-09-30 devnull freecmd(void)
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]);
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]);
294 76193d7c 2003-09-30 devnull lookup(int c)
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;
305 76193d7c 2003-09-30 devnull okdelim(int c)
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);
313 76193d7c 2003-09-30 devnull atnl(void)
315 76193d7c 2003-09-30 devnull skipbl();
316 76193d7c 2003-09-30 devnull if(getch() != '\n')
317 76193d7c 2003-09-30 devnull error(Enewline);
321 76193d7c 2003-09-30 devnull getrhs(String *s, int delim, int cmd)
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();
332 76193d7c 2003-09-30 devnull }else if(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, '\\');
337 76193d7c 2003-09-30 devnull Straddc(s, c);
339 76193d7c 2003-09-30 devnull ungetch(); /* let client read whether delimeter, '\n' or whatever */
342 76193d7c 2003-09-30 devnull String *
343 76193d7c 2003-09-30 devnull collecttoken(char *end)
345 76193d7c 2003-09-30 devnull String *s = newstring();
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')
355 76193d7c 2003-09-30 devnull return s;
358 76193d7c 2003-09-30 devnull String *
359 76193d7c 2003-09-30 devnull collecttext(void)
361 76193d7c 2003-09-30 devnull String *s = newstring();
362 76193d7c 2003-09-30 devnull int begline, i, c, delim;
364 76193d7c 2003-09-30 devnull if(skipbl()=='\n'){
365 76193d7c 2003-09-30 devnull getch();
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);
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();
384 76193d7c 2003-09-30 devnull Straddc(s, 0); /* JUST FOR CMDPRINT() */
385 76193d7c 2003-09-30 devnull return s;
389 76193d7c 2003-09-30 devnull parsecmd(int nest)
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;
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;
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();
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);
456 76193d7c 2003-09-30 devnull switch(cmd.cmdc){
457 76193d7c 2003-09-30 devnull case '{':
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);
464 76193d7c 2003-09-30 devnull cp->next = ncp;
466 76193d7c 2003-09-30 devnull cmd.ccmd = ncp;
467 76193d7c 2003-09-30 devnull }while(cp = ncp);
469 76193d7c 2003-09-30 devnull case '}':
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);
478 76193d7c 2003-09-30 devnull cp = newcmd();
479 76193d7c 2003-09-30 devnull *cp = cmd;
480 76193d7c 2003-09-30 devnull return cp;
483 76193d7c 2003-09-30 devnull String* /* BUGGERED */
484 76193d7c 2003-09-30 devnull getregexp(int delim)
486 76193d7c 2003-09-30 devnull String *r = newre();
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();
497 76193d7c 2003-09-30 devnull }else if(c==delim || c=='\n')
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');
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;
513 76193d7c 2003-09-30 devnull simpleaddr(void)
515 76193d7c 2003-09-30 devnull Addr addr;
516 76193d7c 2003-09-30 devnull Addr *ap, *nap;
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);
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';
530 76193d7c 2003-09-30 devnull case '/': case '?': case '"':
531 76193d7c 2003-09-30 devnull addr.are = getregexp(addr.type = getch());
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();
540 76193d7c 2003-09-30 devnull default:
541 76193d7c 2003-09-30 devnull return 0;
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);
552 76193d7c 2003-09-30 devnull case 'l':
553 76193d7c 2003-09-30 devnull case '#':
554 76193d7c 2003-09-30 devnull if(addr.type=='"')
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;
567 76193d7c 2003-09-30 devnull case '+':
568 76193d7c 2003-09-30 devnull case '-':
570 76193d7c 2003-09-30 devnull default:
571 76193d7c 2003-09-30 devnull panic("simpleaddr");
573 76193d7c 2003-09-30 devnull ap = newaddr();
574 76193d7c 2003-09-30 devnull *ap = addr;
575 76193d7c 2003-09-30 devnull return ap;
579 76193d7c 2003-09-30 devnull compoundaddr(void)
581 76193d7c 2003-09-30 devnull Addr addr;
582 76193d7c 2003-09-30 devnull Addr *ap, *next;
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;