📄 exec.c
字号:
Xerror("can't open"); return; } pushredir(ROPEN, f, runq->code[runq->pc].i); runq->pc++; poplist();}char*list2str(word *words){ char *value, *s, *t; int len = 0; word *ap; for(ap = words;ap;ap = ap->next) len+=1+strlen(ap->word); value = emalloc(len+1); s = value; for(ap = words;ap;ap = ap->next){ for(t = ap->word;*t;) *s++=*t++; *s++=' '; } if(s==value) *s='\0'; else s[-1]='\0'; return value;}voidXmatch(void){ word *p; char *subject; subject = list2str(runq->argv->words); setstatus("no match"); for(p = runq->argv->next->words;p;p = p->next) if(match(subject, p->word, '\0')){ setstatus(""); break; } efree(subject); poplist(); poplist();}voidXcase(void){ word *p; char *s; int ok = 0; s = list2str(runq->argv->next->words); for(p = runq->argv->words;p;p = p->next){ if(match(s, p->word, '\0')){ ok = 1; break; } } efree(s); if(ok) runq->pc++; else runq->pc = runq->code[runq->pc].i; poplist();}word*conclist(word *lp, word *rp, word *tail){ char *buf; word *v; if(lp->next || rp->next) tail = conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next, tail); buf = emalloc(strlen(lp->word)+strlen(rp->word)+1); strcpy(buf, lp->word); strcat(buf, rp->word); v = newword(buf, tail); efree(buf); return v;}voidXconc(void){ word *lp = runq->argv->words; word *rp = runq->argv->next->words; word *vp = runq->argv->next->next->words; int lc = count(lp), rc = count(rp); if(lc!=0 || rc!=0){ if(lc==0 || rc==0){ Xerror1("null list in concatenation"); return; } if(lc!=1 && rc!=1 && lc!=rc){ Xerror1("mismatched list lengths in concatenation"); return; } vp = conclist(lp, rp, vp); } poplist(); poplist(); runq->argv->words = vp;}voidXassign(void){ var *v; if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } deglob(runq->argv->words->word); v = vlook(runq->argv->words->word); poplist(); globlist(); freewords(v->val); v->val = runq->argv->words; v->changed = 1; runq->argv->words = 0; poplist();}/* * copy arglist a, adding the copy to the front of tail */word*copywords(word *a, word *tail){ word *v = 0, **end; for(end=&v;a;a = a->next,end=&(*end)->next) *end = newword(a->word, 0); *end = tail; return v;}voidXdol(void){ word *a, *star; char *s, *t; int n; if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->words->word; deglob(s); n = 0; for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; a = runq->argv->next->words; if(n==0 || *t) a = copywords(vlook(s)->val, a); else{ star = vlook("*")->val; if(star && 1<=n && n<=count(star)){ while(--n) star = star->next; a = newword(star->word, a); } } poplist(); runq->argv->words = a;}voidXqdol(void){ word *a, *p; char *s; int n; if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->words->word; deglob(s); a = vlook(s)->val; poplist(); n = count(a); if(n==0){ pushword(""); return; } for(p = a;p;p = p->next) n+=strlen(p->word); s = emalloc(n); if(a){ strcpy(s, a->word); for(p = a->next;p;p = p->next){ strcat(s, " "); strcat(s, p->word); } } else s[0]='\0'; pushword(s); efree(s);}word*subwords(word *val, int len, word *sub, word *a){ int n; char *s; if(!sub) return a; a = subwords(val, len, sub->next, a); s = sub->word; deglob(s); n = 0; while('0'<=*s && *s<='9') n = n*10+ *s++ -'0'; if(n<1 || len<n) return a; for(;n!=1;--n) val = val->next; return newword(val->word, a);}voidXsub(void){ word *a, *v; char *s; if(count(runq->argv->next->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->next->words->word; deglob(s); a = runq->argv->next->next->words; v = vlook(s)->val; a = subwords(v, count(v), runq->argv->words, a); poplist(); poplist(); runq->argv->words = a;}voidXcount(void){ word *a; char *s, *t; int n; char num[12]; if(count(runq->argv->words)!=1){ Xerror1("variable name not singleton!"); return; } s = runq->argv->words->word; deglob(s); n = 0; for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; if(n==0 || *t){ a = vlook(s)->val; inttoascii(num, count(a)); } else{ a = vlook("*")->val; inttoascii(num, a && 1<=n && n<=count(a)?1:0); } poplist(); pushword(num);}voidXlocal(void){ if(count(runq->argv->words)!=1){ Xerror1("variable name must be singleton\n"); return; } deglob(runq->argv->words->word); runq->local = newvar(strdup(runq->argv->words->word), runq->local); runq->local->val = copywords(runq->argv->next->words, (word *)0); runq->local->changed = 1; poplist(); poplist();}voidXunlocal(void){ var *v = runq->local, *hid; if(v==0) panic("Xunlocal: no locals!", 0); runq->local = v->next; hid = vlook(v->name); hid->changed = 1; efree(v->name); freewords(v->val); efree((char *)v);}voidfreewords(word *w){ word *nw; while(w){ efree(w->word); nw = w->next; efree((char *)w); w = nw; }}voidXfn(void){ var *v; word *a; int end; end = runq->code[runq->pc].i; for(a = runq->argv->words;a;a = a->next){ v = gvlook(a->word); if(v->fn) codefree(v->fn); v->fn = codecopy(runq->code); v->pc = runq->pc+2; v->fnchanged = 1; } runq->pc = end; poplist();}voidXdelfn(void){ var *v; word *a; for(a = runq->argv->words;a;a = a->next){ v = gvlook(a->word); if(v->fn) codefree(v->fn); v->fn = 0; v->fnchanged = 1; } poplist();}char*concstatus(char *s, char *t){ static char v[NSTATUS+1]; int n = strlen(s); strncpy(v, s, NSTATUS); if(n<NSTATUS){ v[n]='|'; strncpy(v+n+1, t, NSTATUS-n-1); } v[NSTATUS]='\0'; return v;}voidXpipewait(void){ char status[NSTATUS+1]; if(runq->pid==-1) setstatus(concstatus(runq->status, getstatus())); else{ strncpy(status, getstatus(), NSTATUS); status[NSTATUS]='\0'; Waitfor(runq->pid, 1); runq->pid=-1; setstatus(concstatus(getstatus(), status)); }}voidXrdcmds(void){ struct thread *p = runq; word *prompt; flush(err); nerror = 0; if(flag['s'] && !truestatus()) pfmt(err, "status=%v\n", vlook("status")->val); if(runq->iflag){ prompt = vlook("prompt")->val; if(prompt) promptstr = prompt->word; else promptstr="% "; } Noerror(); if(yyparse()){ if(!p->iflag || p->eof && !Eintr()){ if(p->cmdfile) efree(p->cmdfile); closeio(p->cmdfd); Xreturn(); /* should this be omitted? */ } else{ if(Eintr()){ pchr(err, '\n'); p->eof = 0; } --p->pc; /* go back for next command */ } } else{ ntrap = 0; /* avoid double-interrupts during blocked writes */ --p->pc; /* re-execute Xrdcmds after codebuf runs */ start(codebuf, 1, runq->local); } freenodes();}voidXerror(char *s){ if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) pfmt(err, "rc: %s: %r\n", s); else pfmt(err, "rc (%s): %s: %r\n", argv0, s); flush(err); while(!runq->iflag) Xreturn();}voidXerror1(char *s){ if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) pfmt(err, "rc: %s\n", s); else pfmt(err, "rc (%s): %s\n", argv0, s); flush(err); while(!runq->iflag) Xreturn();}voidsetstatus(char *s){ setvar("status", newword(s, (word *)0));}char*getstatus(void){ var *status = vlook("status"); return status->val?status->val->word:"";}inttruestatus(void){ char *s; for(s = getstatus();*s;s++) if(*s!='|' && *s!='0') return 0; return 1;}voidXdelhere(void){ Unlink(runq->code[runq->pc++].s);}voidXfor(void){ if(runq->argv->words==0){ poplist(); runq->pc = runq->code[runq->pc].i; } else{ freelist(runq->local->val); runq->local->val = runq->argv->words; runq->local->changed = 1; runq->argv->words = runq->argv->words->next; runq->local->val->next = 0; runq->pc++; }}voidXglob(void){ globlist();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -