From a9eaaa03e043ba8e1b2f67d7c8c7ba471db6ba4b Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 12 Jan 2005 16:59:50 +0000 Subject: maintain $path and $PATH simultaneously --- src/cmd/rc/exec.c | 10 +++++++-- src/cmd/rc/fns.h | 3 +++ src/cmd/rc/rc.h | 1 + src/cmd/rc/simple.c | 2 +- src/cmd/rc/var.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 74 insertions(+), 4 deletions(-) (limited to 'src/cmd/rc') diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c index ebed11d8..9ab7c29d 100644 --- a/src/cmd/rc/exec.c +++ b/src/cmd/rc/exec.c @@ -117,6 +117,7 @@ main(int argc, char *argv[]) Trapinit(); Vinit(); itoa(num, mypid=getpid()); + pathinit(); setvar("pid", newword(num, (word *)0)); setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0) :(word *)0); @@ -369,7 +370,7 @@ void Xwrite(void){ runq->pc++; poplist(); } -char *list2str(word *words){ +char *_list2str(word *words, int c){ char *value, *s, *t; int len=0; word *ap; @@ -379,12 +380,15 @@ char *list2str(word *words){ s=value; for(ap=words;ap;ap=ap->next){ for(t=ap->word;*t;) *s++=*t++; - *s++=' '; + *s++=c; } if(s==value) *s='\0'; else s[-1]='\0'; return value; } +char *list2str(word *words){ + return _list2str(words, ' '); +} void Xmatch(void){ word *p; char *subject; @@ -464,6 +468,8 @@ void Xassign(void){ freewords(v->val); v->val=runq->argv->words; v->changed=1; + if(v->changefn) + v->changefn(v); runq->argv->words=0; poplist(); } diff --git a/src/cmd/rc/fns.h b/src/cmd/rc/fns.h index 4c8be104..b9e5cb73 100644 --- a/src/cmd/rc/fns.h +++ b/src/cmd/rc/fns.h @@ -27,6 +27,7 @@ void cleanhere(char*); void codefree(code*); int compile(tree*); char * list2str(word*); +char * _list2str(word*, int); int count(word*); void deglob(char*); void dotrap(void); @@ -39,6 +40,7 @@ void kinit(void); int match(char*, char*, int); int matchfn(char*, char*); void panic(char*, int); +void pathinit(void); void poplist(void); void popword(void); void pprompt(void); @@ -48,6 +50,7 @@ void pushword(char*); void readhere(void); void setstatus(char*); void setvar(char*, word*); +void _setvar(char*, word*, int); void skipnl(void); void start(code*, int, var*); int truestatus(void); diff --git a/src/cmd/rc/rc.h b/src/cmd/rc/rc.h index 9a739272..b7edbac4 100644 --- a/src/cmd/rc/rc.h +++ b/src/cmd/rc/rc.h @@ -84,6 +84,7 @@ struct var{ int fnchanged; int pc; /* pc of start of function */ var *next; /* next on hash or local list */ + void (*changefn)(var*); }; var *vlook(char*), *gvlook(char*), *newvar(char*, var*); #define NVAR 521 diff --git a/src/cmd/rc/simple.c b/src/cmd/rc/simple.c index 5318c9fd..a65bec22 100644 --- a/src/cmd/rc/simple.c +++ b/src/cmd/rc/simple.c @@ -168,7 +168,7 @@ void execcd(void){ if(cdpath==0) pfmt(err, "Can't cd %s: %r\n", a->next->word); break; case 1: - a=vlook("home")->val; + a=vlook("HOME")->val; if(count(a)>=1){ if(dochdir(a->word)>=0) setstatus(""); diff --git a/src/cmd/rc/var.c b/src/cmd/rc/var.c index 73e4e9ae..8a200ffd 100644 --- a/src/cmd/rc/var.c +++ b/src/cmd/rc/var.c @@ -62,10 +62,70 @@ var *vlook(char *name) if(strcmp(v->name, name)==0) return v; return gvlook(name); } -void setvar(char *name, word *val) +void _setvar(char *name, word *val, int callfn) { register struct var *v=vlook(name); freewords(v->val); v->val=val; v->changed=1; + if(callfn && v->changefn) + v->changefn(v); +} +void setvar(char *name, word *val) +{ + _setvar(name, val, 1); +} +void bigpath(var *v) +{ + /* convert $PATH to $path */ + char *p, *q; + word **l, *w; + + if(v->val == nil){ + _setvar("path", nil, 0); + return; + } + p = v->val->word; + w = nil; + l = &w; + /* + * Doesn't handle escaped colon nonsense. + */ + if(p[0] == 0) + p = nil; + while(p){ + q = strchr(p, ':'); + if(q) + *q = 0; + *l = newword(p[0] ? p : ".", nil); + l = &(*l)->next; + if(q){ + *q = ':'; + p = q+1; + }else + p = nil; + } + _setvar("path", w, 0); +} +void littlepath(var *v) +{ + /* convert $path to $PATH */ + char *p; + word *w; + + p = _list2str(v->val, ':'); + w = new(word); + w->word = p; + w->next = nil; + _setvar("PATH", w, 1); /* 1: recompute $path to expose colon problems */ +} +void pathinit(void) +{ + var *v; + + v = gvlook("path"); + v->changefn = littlepath; + v = gvlook("PATH"); + v->changefn = bigpath; + bigpath(v); } -- cgit v1.2.3