9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

env.c (2280B)


      1 #include	"mk.h"
      2 
      3 enum {
      4 	ENVQUANTA=10
      5 };
      6 
      7 Envy	*envy;
      8 static int nextv;
      9 
     10 static char	*myenv[] =
     11 {
     12 	"target",
     13 	"stem",
     14 	"prereq",
     15 	"pid",
     16 	"nproc",
     17 	"newprereq",
     18 	"alltarget",
     19 	"newmember",
     20 	"stem0",		/* must be in order from here */
     21 	"stem1",
     22 	"stem2",
     23 	"stem3",
     24 	"stem4",
     25 	"stem5",
     26 	"stem6",
     27 	"stem7",
     28 	"stem8",
     29 	"stem9",
     30 	0
     31 };
     32 
     33 void
     34 initenv(void)
     35 {
     36 	char **p;
     37 
     38 	for(p = myenv; *p; p++)
     39 		symlook(*p, S_INTERNAL, (void *)"");
     40 	readenv();				/* o.s. dependent */
     41 }
     42 
     43 static void
     44 envinsert(char *name, Word *value)
     45 {
     46 	static int envsize;
     47 
     48 	if (nextv >= envsize) {
     49 		envsize += ENVQUANTA;
     50 		envy = (Envy *) Realloc((char *) envy, envsize*sizeof(Envy));
     51 	}
     52 	envy[nextv].name = name;
     53 	envy[nextv++].values = value;
     54 }
     55 
     56 static void
     57 envupd(char *name, Word *value)
     58 {
     59 	Envy *e;
     60 
     61 	for(e = envy; e->name; e++)
     62 		if(strcmp(name, e->name) == 0){
     63 			delword(e->values);
     64 			e->values = value;
     65 			return;
     66 		}
     67 	e->name = name;
     68 	e->values = value;
     69 	envinsert(0,0);
     70 }
     71 
     72 static void
     73 ecopy(Symtab *s)
     74 {
     75 	char **p;
     76 
     77 	if(symlook(s->name, S_NOEXPORT, 0))
     78 		return;
     79 	for(p = myenv; *p; p++)
     80 		if(strcmp(*p, s->name) == 0)
     81 			return;
     82 	envinsert(s->name, s->u.ptr);
     83 }
     84 
     85 void
     86 execinit(void)
     87 {
     88 	char **p;
     89 
     90 	nextv = 0;
     91 	for(p = myenv; *p; p++)
     92 		envinsert(*p, stow(""));
     93 
     94 	symtraverse(S_VAR, ecopy);
     95 	envinsert(0, 0);
     96 }
     97 
     98 Envy*
     99 buildenv(Job *j, int slot)
    100 {
    101 	char **p, *cp, *qp;
    102 	Word *w, *v, **l;
    103 	int i;
    104 	char buf[256];
    105 
    106 	envupd("target", wdup(j->t));
    107 	if(j->r->attr&REGEXP)
    108 		envupd("stem",newword(""));
    109 	else
    110 		envupd("stem", newword(j->stem));
    111 	envupd("prereq", wdup(j->p));
    112 	sprint(buf, "%d", getpid());
    113 	envupd("pid", newword(buf));
    114 	sprint(buf, "%d", slot);
    115 	envupd("nproc", newword(buf));
    116 	envupd("newprereq", wdup(j->np));
    117 	envupd("alltarget", wdup(j->at));
    118 	l = &v;
    119 	v = w = wdup(j->np);
    120 	while(w){
    121 		cp = strchr(w->s, '(');
    122 		if(cp){
    123 			qp = strchr(cp+1, ')');
    124 			if(qp){
    125 				*qp = 0;
    126 				strcpy(w->s, cp+1);
    127 				l = &w->next;
    128 				w = w->next;
    129 				continue;
    130 			}
    131 		}
    132 		*l = w->next;
    133 		free(w->s);
    134 		free(w);
    135 		w = *l;
    136 	}
    137 	envupd("newmember", v);
    138 		/* update stem0 -> stem9 */
    139 	for(p = myenv; *p; p++)
    140 		if(strcmp(*p, "stem0") == 0)
    141 			break;
    142 	for(i = 0; *p; i++, p++){
    143 		if((j->r->attr&REGEXP) && j->match[i])
    144 			envupd(*p, newword(j->match[i]));
    145 		else 
    146 			envupd(*p, newword(""));
    147 	}
    148 	return envy;
    149 }