maintain $path and $PATH simultaneously

This commit is contained in:
rsc 2005-01-12 16:59:50 +00:00
parent 7b0c2f155d
commit a9eaaa03e0
5 changed files with 74 additions and 4 deletions

View file

@ -117,6 +117,7 @@ main(int argc, char *argv[])
Trapinit(); Trapinit();
Vinit(); Vinit();
itoa(num, mypid=getpid()); itoa(num, mypid=getpid());
pathinit();
setvar("pid", newword(num, (word *)0)); setvar("pid", newword(num, (word *)0));
setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0) setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)
:(word *)0); :(word *)0);
@ -369,7 +370,7 @@ void Xwrite(void){
runq->pc++; runq->pc++;
poplist(); poplist();
} }
char *list2str(word *words){ char *_list2str(word *words, int c){
char *value, *s, *t; char *value, *s, *t;
int len=0; int len=0;
word *ap; word *ap;
@ -379,12 +380,15 @@ char *list2str(word *words){
s=value; s=value;
for(ap=words;ap;ap=ap->next){ for(ap=words;ap;ap=ap->next){
for(t=ap->word;*t;) *s++=*t++; for(t=ap->word;*t;) *s++=*t++;
*s++=' '; *s++=c;
} }
if(s==value) *s='\0'; if(s==value) *s='\0';
else s[-1]='\0'; else s[-1]='\0';
return value; return value;
} }
char *list2str(word *words){
return _list2str(words, ' ');
}
void Xmatch(void){ void Xmatch(void){
word *p; word *p;
char *subject; char *subject;
@ -464,6 +468,8 @@ void Xassign(void){
freewords(v->val); freewords(v->val);
v->val=runq->argv->words; v->val=runq->argv->words;
v->changed=1; v->changed=1;
if(v->changefn)
v->changefn(v);
runq->argv->words=0; runq->argv->words=0;
poplist(); poplist();
} }

View file

@ -27,6 +27,7 @@ void cleanhere(char*);
void codefree(code*); void codefree(code*);
int compile(tree*); int compile(tree*);
char * list2str(word*); char * list2str(word*);
char * _list2str(word*, int);
int count(word*); int count(word*);
void deglob(char*); void deglob(char*);
void dotrap(void); void dotrap(void);
@ -39,6 +40,7 @@ void kinit(void);
int match(char*, char*, int); int match(char*, char*, int);
int matchfn(char*, char*); int matchfn(char*, char*);
void panic(char*, int); void panic(char*, int);
void pathinit(void);
void poplist(void); void poplist(void);
void popword(void); void popword(void);
void pprompt(void); void pprompt(void);
@ -48,6 +50,7 @@ void pushword(char*);
void readhere(void); void readhere(void);
void setstatus(char*); void setstatus(char*);
void setvar(char*, word*); void setvar(char*, word*);
void _setvar(char*, word*, int);
void skipnl(void); void skipnl(void);
void start(code*, int, var*); void start(code*, int, var*);
int truestatus(void); int truestatus(void);

View file

@ -84,6 +84,7 @@ struct var{
int fnchanged; int fnchanged;
int pc; /* pc of start of function */ int pc; /* pc of start of function */
var *next; /* next on hash or local list */ var *next; /* next on hash or local list */
void (*changefn)(var*);
}; };
var *vlook(char*), *gvlook(char*), *newvar(char*, var*); var *vlook(char*), *gvlook(char*), *newvar(char*, var*);
#define NVAR 521 #define NVAR 521

View file

@ -168,7 +168,7 @@ void execcd(void){
if(cdpath==0) pfmt(err, "Can't cd %s: %r\n", a->next->word); if(cdpath==0) pfmt(err, "Can't cd %s: %r\n", a->next->word);
break; break;
case 1: case 1:
a=vlook("home")->val; a=vlook("HOME")->val;
if(count(a)>=1){ if(count(a)>=1){
if(dochdir(a->word)>=0) if(dochdir(a->word)>=0)
setstatus(""); setstatus("");

View file

@ -62,10 +62,70 @@ var *vlook(char *name)
if(strcmp(v->name, name)==0) return v; if(strcmp(v->name, name)==0) return v;
return gvlook(name); return gvlook(name);
} }
void setvar(char *name, word *val) void _setvar(char *name, word *val, int callfn)
{ {
register struct var *v=vlook(name); register struct var *v=vlook(name);
freewords(v->val); freewords(v->val);
v->val=val; v->val=val;
v->changed=1; 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);
} }