word* subwords(word *val, int len, word *sub, word *a) { int n, m; char *s; if(!sub) return a; a = subwords(val, len, sub->next, a); s = sub->word; deglob(s); m = 0; n = 0; while('0'<=*s && *s<='9') n = n*10+ *s++ -'0'; if(*s == '-'){ if(*++s == 0) m = len - n; else{ while('0'<=*s && *s<='9') m = m*10+ *s++ -'0'; m -= n; } } if(n<1 || n>len || m<0) return a; if(n+m>len) m = len-n; while(--n > 0) val = val->next; return copynwords(val, a, m+1); }
void Xcount(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); }
void Xqdol(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); }
void Xdol(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; }
void Xlocal(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(); }
void glob(void *ap) { uint8_t *p = ap; word *svglobv = globv; int globlen = Globsize(ap); if(!globlen){ deglob(p); globv = newword((char *)p, globv); return; } globname = emalloc(globlen); globname[0]='\0'; globdir(p, (uint8_t *)globname); efree(globname); if(svglobv==globv){ deglob(p); globv = newword((char *)p, globv); } else globsort(globv, svglobv); }
void Xsub(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; }
void Xassign(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; if(v->changefn) v->changefn(v); runq->argv->words = 0; poplist(); }