4 static char linex[]="\n";
5 static char wordx[]=" \t\n";
6 struct cmdtab cmdtab[]={
7 /* cmdc text regexp addr defcmd defaddr count token fn */
8 '\n', 0, 0, 0, 0, aDot, 0, 0, nl_cmd,
9 'a', 1, 0, 0, 0, aDot, 0, 0, a_cmd,
10 'b', 0, 0, 0, 0, aNo, 0, linex, b_cmd,
11 'B', 0, 0, 0, 0, aNo, 0, linex, b_cmd,
12 'c', 1, 0, 0, 0, aDot, 0, 0, c_cmd,
13 'd', 0, 0, 0, 0, aDot, 0, 0, d_cmd,
14 'D', 0, 0, 0, 0, aNo, 0, linex, D_cmd,
15 'e', 0, 0, 0, 0, aNo, 0, wordx, e_cmd,
16 'f', 0, 0, 0, 0, aNo, 0, wordx, f_cmd,
17 'g', 0, 1, 0, 'p', aDot, 0, 0, g_cmd,
18 'i', 1, 0, 0, 0, aDot, 0, 0, i_cmd,
19 'k', 0, 0, 0, 0, aDot, 0, 0, k_cmd,
20 'm', 0, 0, 1, 0, aDot, 0, 0, m_cmd,
21 'n', 0, 0, 0, 0, aNo, 0, 0, n_cmd,
22 'p', 0, 0, 0, 0, aDot, 0, 0, p_cmd,
23 'q', 0, 0, 0, 0, aNo, 0, 0, q_cmd,
24 'r', 0, 0, 0, 0, aDot, 0, wordx, e_cmd,
25 's', 0, 1, 0, 0, aDot, 1, 0, s_cmd,
26 't', 0, 0, 1, 0, aDot, 0, 0, m_cmd,
27 'u', 0, 0, 0, 0, aNo, 2, 0, u_cmd,
28 'v', 0, 1, 0, 'p', aDot, 0, 0, g_cmd,
29 'w', 0, 0, 0, 0, aAll, 0, wordx, w_cmd,
30 'x', 0, 1, 0, 'p', aDot, 0, 0, x_cmd,
31 'y', 0, 1, 0, 'p', aDot, 0, 0, x_cmd,
32 'X', 0, 1, 0, 'f', aNo, 0, 0, X_cmd,
33 'Y', 0, 1, 0, 'f', aNo, 0, 0, X_cmd,
34 '!', 0, 0, 0, 0, aNo, 0, linex, plan9_cmd,
35 '>', 0, 0, 0, 0, aDot, 0, linex, plan9_cmd,
36 '<', 0, 0, 0, 0, aDot, 0, linex, plan9_cmd,
37 '|', 0, 0, 0, 0, aDot, 0, linex, plan9_cmd,
38 '=', 0, 0, 0, 0, aDot, 0, linex, eq_cmd,
39 'c'|0x100,0, 0, 0, 0, aNo, 0, wordx, cd_cmd,
40 0, 0, 0, 0, 0, 0, 0, 0,
43 Addr *compoundaddr(void);
44 Addr *simpleaddr(void);
49 Rune termline[BLOCKSIZE];
51 Rune *terminp = termline;
52 Rune *termoutp = termline;
64 terminp = termoutp = termline;
78 while(termoutp == terminp){
82 while(termlocked > 0){
90 if(termoutp == terminp)
91 terminp = termoutp = termline;
94 n = read(0, buf+nbuf, 1);
98 }while(!fullrune(buf, nbuf));
116 if((c = inputc())<=0)
118 if(i == (sizeof line)/RUNESIZE-1)
120 }while((line[i++]=c) != '\n');
130 if(*linep==0 && inputline()<0){
159 if(signok>1 && nextc()=='-'){
163 if((c=nextc())<'0' || '9'<c) /* no number defaults to 1 */
165 while('0'<=(c=getch()) && c<='9')
177 while(c==' ' || c=='\t');
188 for(p=cmdpt; p<cmd->b.nc; p++){
189 if(terminp >= &termline[BLOCKSIZE]){
193 *terminp++ = filereadc(cmd, p);
206 if(!downloaded && curfile && curfile->unread)
208 if((cmdp = parsecmd(0))==0){
216 loaded = curfile && !curfile->unread;
217 if(cmdexec(curfile, cmdp) == 0)
222 if(downloaded && curfile &&
223 (ocurfile!=curfile || (!loaded && !curfile->unread)))
224 outTs(Hcurrent, curfile->tag);
225 /* don't allow type ahead on files that aren't bound */
226 if(downloaded && curfile && curfile->rasp == 0)
235 p = emalloc(sizeof(Cmd));
236 inslist(&cmdlist, cmdlist.nused, (long)p);
245 p = emalloc(sizeof(Addr));
246 inslist(&addrlist, addrlist.nused, (long)p);
255 p = emalloc(sizeof(String));
256 inslist(&relist, relist.nused, (long)p);
266 p = emalloc(sizeof(String));
267 inslist(&stringlist, stringlist.nused, (long)p);
277 while(cmdlist.nused > 0)
278 free(cmdlist.ucharpptr[--cmdlist.nused]);
279 while(addrlist.nused > 0)
280 free(addrlist.ucharpptr[--addrlist.nused]);
281 while(relist.nused > 0){
283 Strclose(relist.stringpptr[i]);
284 free(relist.stringpptr[i]);
286 while(stringlist.nused>0){
287 i = --stringlist.nused;
288 Strclose(stringlist.stringpptr[i]);
289 free(stringlist.stringpptr[i]);
298 for(i=0; cmdtab[i].cmdc; i++)
299 if(cmdtab[i].cmdc == c)
307 if(c=='\\' || ('a'<=c && c<='z')
308 || ('A'<=c && c<='Z') || ('0'<=c && c<='9'))
321 getrhs(String *s, int delim, int cmd)
325 while((c = getch())>0 && c!=delim && c!='\n'){
334 else if(c!=delim && (cmd=='s' || c!='\\')) /* s does its own */
339 ungetch(); /* let client read whether delimeter, '\n' or whatever */
343 collecttoken(char *end)
345 String *s = newstring();
348 while((c=nextc())==' ' || c=='\t')
349 Straddc(s, getch()); /* blanks significant for getname() */
350 while((c=getch())>0 && utfrune(end, c)==0)
361 String *s = newstring();
362 int begline, i, c, delim;
369 while((c = getch())>0 && c!='\n')
371 i++, Straddc(s, '\n');
374 }while(s->s[begline]!='.' || s->s[begline+1]!='\n');
375 Strdelete(s, s->n-2, s->n);
377 okdelim(delim = getch());
378 getrhs(s, delim, 'a');
384 Straddc(s, 0); /* JUST FOR CMDPRINT() */
396 cmd.next = cmd.ccmd = 0;
398 cmd.flag = cmd.num = 0;
399 cmd.addr = compoundaddr();
405 if(cmd.cmdc=='c' && nextc()=='d'){ /* sleazy two-character case */
406 getch(); /* the 'd' */
409 i = lookup(cmd.cmdc);
412 goto Return; /* let nl_cmd work it all out */
414 if(ct->defaddr==aNo && cmd.addr)
417 cmd.num = getnum(ct->count);
419 /* x without pattern -> .*\n, indicated by cmd.re==0 */
420 /* X without pattern is all files */
421 if((ct->cmdc!='x' && ct->cmdc!='X') ||
422 ((c = nextc())!=' ' && c!='\t' && c!='\n')){
424 if((c = getch())=='\n' || c<0)
427 cmd.re = getregexp(c);
429 cmd.ctext = newstring();
430 getrhs(cmd.ctext, c, 's');
440 if(ct->addr && (cmd.caddr=simpleaddr())==0)
443 if(skipbl() == '\n'){
446 cmd.ccmd->cmdc = ct->defcmd;
447 }else if((cmd.ccmd = parsecmd(nest))==0)
450 cmd.ctext = collecttext();
452 cmd.ctext = collecttoken(ct->token);
462 ncp = parsecmd(nest+1);
475 error_c(Eunk, cmd.cmdc);
483 String* /* BUGGERED */
489 for(Strzero(&genstr); ; Straddc(&genstr, c))
490 if((c = getch())=='\\'){
493 else if(nextc()=='\\'){
497 }else if(c==delim || c=='\n')
503 Strduplstr(&lastpat, &genstr);
504 Straddc(&lastpat, '\0');
508 Strduplstr(r, &lastpat);
524 addr.num = getnum(1);
526 case '0': case '1': case '2': case '3': case '4':
527 case '5': case '6': case '7': case '8': case '9':
528 addr.num = getnum(1);
531 case '/': case '?': case '"':
532 addr.are = getregexp(addr.type = getch());
544 if(addr.next = simpleaddr())
545 switch(addr.next->type){
560 if(addr.type!='+' && addr.type!='-'){
561 /* insert the missing '+' */
564 nap->next = addr.next;
585 addr.left = simpleaddr();
586 if((addr.type = skipbl())!=',' && addr.type!=';')
589 next = addr.next = compoundaddr();
590 if(next && (next->type==',' || next->type==';') && next->left==0)