172339Sabial#define Extern extern 272339Sabial#include <sys/types.h> 372339Sabial#include <sys/stat.h> 472339Sabial#include <dirent.h> 572339Sabial#include <limits.h> 672339Sabial#include <signal.h> 772339Sabial#define _NSIG NSIG 872339Sabial#include <errno.h> 972339Sabial#include <setjmp.h> 1072339Sabial#include "sh.h" 1172339Sabial 1272339Sabial/* -------- eval.c -------- */ 1372339Sabial/* #include "sh.h" */ 1472339Sabial/* #include "word.h" */ 1572339Sabial 1672339Sabial/* 1772339Sabial * ${} 1872339Sabial * `command` 1972339Sabial * blank interpretation 2072339Sabial * quoting 2172339Sabial * glob 2272339Sabial */ 2372339Sabial 2472339Sabial_PROTOTYPE(static int expand, (char *cp, struct wdblock **wbp, int f )); 2572339Sabial_PROTOTYPE(static char *blank, (int f )); 2672339Sabial_PROTOTYPE(static int dollar, (int quoted )); 2772339Sabial_PROTOTYPE(static int grave, (int quoted )); 2872339Sabial_PROTOTYPE(void globname, (char *we, char *pp )); 2972339Sabial_PROTOTYPE(static char *generate, (char *start1, char *end1, char *middle, char *end )); 3072339Sabial_PROTOTYPE(static int anyspcl, (struct wdblock *wb )); 3172339Sabial_PROTOTYPE(static int xstrcmp, (char *p1, char *p2 )); 3272339Sabial_PROTOTYPE(void glob0, (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *))); 3372339Sabial_PROTOTYPE(void glob1, (char *base, char *lim )); 3472339Sabial_PROTOTYPE(void glob2, (char *i, char *j )); 3572339Sabial_PROTOTYPE(void glob3, (char *i, char *j, char *k )); 3672339Sabial_PROTOTYPE(char *memcopy, (char *ato, char *from, int nb )); 3772339Sabial 3872339Sabialchar ** 3972339Sabialeval(ap, f) 4072339Sabialregister char **ap; 4172339Sabialint f; 4272339Sabial{ 4372339Sabial struct wdblock *wb; 4472339Sabial char **wp; 4572339Sabial char **wf; 4672339Sabial jmp_buf ev; 4772339Sabial 4872339Sabial wp = NULL; 4972339Sabial wb = NULL; 5072339Sabial wf = NULL; 5172339Sabial if (newenv(setjmp(errpt = ev)) == 0) { 5272339Sabial while (*ap && isassign(*ap)) 5372339Sabial expand(*ap++, &wb, f & ~DOGLOB); 5472339Sabial if (flag['k']) { 5572339Sabial for (wf = ap; *wf; wf++) { 5672339Sabial if (isassign(*wf)) 5772339Sabial expand(*wf, &wb, f & ~DOGLOB); 5872339Sabial } 5972339Sabial } 6072339Sabial for (wb = addword((char *)0, wb); *ap; ap++) { 6172339Sabial if (!flag['k'] || !isassign(*ap)) 6272339Sabial expand(*ap, &wb, f & ~DOKEY); 6372339Sabial } 6472339Sabial wb = addword((char *)0, wb); 6572339Sabial wp = getwords(wb); 6672339Sabial quitenv(); 6772339Sabial } else 6872339Sabial gflg = 1; 6972339Sabial return(gflg? (char **)NULL: wp); 7072339Sabial} 7172339Sabial 7272339Sabial/* 7372339Sabial * Make the exported environment from the exported 7472339Sabial * names in the dictionary. Keyword assignments 7572339Sabial * will already have been done. 7672339Sabial */ 7772339Sabialchar ** 7872339Sabialmakenv() 7972339Sabial 8072339Sabial{ 8172339Sabial register struct wdblock *wb; 8272339Sabial register struct var *vp; 8372339Sabial 8472339Sabial wb = NULL; 8572339Sabial for (vp = vlist; vp; vp = vp->next) 8672339Sabial if (vp->status & EXPORT) 8772339Sabial wb = addword(vp->name, wb); 8872339Sabial wb = addword((char *)0, wb); 8972339Sabial return(getwords(wb)); 9072339Sabial} 9172339Sabial 9272339Sabialchar * 9372339Sabialevalstr(cp, f) 9472339Sabialregister char *cp; 9572339Sabialint f; 9672339Sabial{ 9772339Sabial struct wdblock *wb; 9872339Sabial 9972339Sabial wb = NULL; 10072339Sabial if (expand(cp, &wb, f)) { 10172339Sabial if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL) 10272339Sabial cp = ""; 10372339Sabial DELETE(wb); 10472339Sabial } else 10572339Sabial cp = NULL; 10672339Sabial return(cp); 10772339Sabial} 10872339Sabial 10972339Sabialstatic int 11072339Sabialexpand(cp, wbp, f) 11172339Sabialregister char *cp; 11272339Sabialregister struct wdblock **wbp; 11372339Sabialint f; 11472339Sabial{ 11572339Sabial jmp_buf ev; 11672339Sabial 11772339Sabial gflg = 0; 11872339Sabial if (cp == NULL) 11972339Sabial return(0); 12072339Sabial if (!anys("$`'\"", cp) && 12172339Sabial !anys(ifs->value, cp) && 12272339Sabial ((f&DOGLOB)==0 || !anys("[*?", cp))) { 12372339Sabial cp = strsave(cp, areanum); 12472339Sabial if (f & DOTRIM) 12572339Sabial unquote(cp); 12672339Sabial *wbp = addword(cp, *wbp); 12772339Sabial return(1); 12872339Sabial } 12972339Sabial if (newenv(setjmp(errpt = ev)) == 0) { 13072339Sabial PUSHIO(aword, cp, strchar); 13172339Sabial e.iobase = e.iop; 13272339Sabial while ((cp = blank(f)) && gflg == 0) { 13372339Sabial e.linep = cp; 13472339Sabial cp = strsave(cp, areanum); 13572339Sabial if ((f&DOGLOB) == 0) { 13672339Sabial if (f & DOTRIM) 13772339Sabial unquote(cp); 13872339Sabial *wbp = addword(cp, *wbp); 13972339Sabial } else 14072339Sabial *wbp = glob(cp, *wbp); 14172339Sabial } 14272339Sabial quitenv(); 14372339Sabial } else 14472339Sabial gflg = 1; 14572339Sabial return(gflg == 0); 14672339Sabial} 14772339Sabial 14872339Sabial/* 14972339Sabial * Blank interpretation and quoting 15072339Sabial */ 15172339Sabialstatic char * 15272339Sabialblank(f) 15372339Sabialint f; 15472339Sabial{ 15572339Sabial register c, c1; 15672339Sabial register char *sp; 15772339Sabial int scanequals, foundequals; 15872339Sabial 15972339Sabial sp = e.linep; 16072339Sabial scanequals = f & DOKEY; 16172339Sabial foundequals = 0; 16272339Sabial 16372339Sabialloop: 16472339Sabial switch (c = subgetc('"', foundequals)) { 16572339Sabial case 0: 16672339Sabial if (sp == e.linep) 16772339Sabial return(0); 16872339Sabial *e.linep++ = 0; 16972339Sabial return(sp); 17072339Sabial 17172339Sabial default: 17272339Sabial if (f & DOBLANK && any(c, ifs->value)) 17372339Sabial goto loop; 17472339Sabial break; 17572339Sabial 17672339Sabial case '"': 17772339Sabial case '\'': 17872339Sabial scanequals = 0; 17972339Sabial if (INSUB()) 18072339Sabial break; 18172339Sabial for (c1 = c; (c = subgetc(c1, 1)) != c1;) { 18272339Sabial if (c == 0) 18372339Sabial break; 18472339Sabial if (c == '\'' || !any(c, "$`\"")) 18572339Sabial c |= QUOTE; 18672339Sabial *e.linep++ = c; 18772339Sabial } 18872339Sabial c = 0; 18972339Sabial } 19072339Sabial unget(c); 19172339Sabial if (!letter(c)) 19272339Sabial scanequals = 0; 19372339Sabial for (;;) { 19472339Sabial c = subgetc('"', foundequals); 19572339Sabial if (c == 0 || 19672339Sabial f & (DOBLANK && any(c, ifs->value)) || 19772339Sabial (!INSUB() && any(c, "\"'"))) { 19872339Sabial scanequals = 0; 19972339Sabial unget(c); 20072339Sabial if (any(c, "\"'")) 20172339Sabial goto loop; 20272339Sabial break; 20372339Sabial } 20472339Sabial if (scanequals) 20572339Sabial if (c == '=') { 20672339Sabial foundequals = 1; 20772339Sabial scanequals = 0; 20872339Sabial } 20972339Sabial else if (!letnum(c)) 21072339Sabial scanequals = 0; 21172339Sabial *e.linep++ = c; 21272339Sabial } 21372339Sabial *e.linep++ = 0; 21472339Sabial return(sp); 21572339Sabial} 21672339Sabial 21772339Sabial/* 21872339Sabial * Get characters, substituting for ` and $ 21972339Sabial */ 22072339Sabialint 22172339Sabialsubgetc(ec, quoted) 22272339Sabialregister char ec; 22372339Sabialint quoted; 22472339Sabial{ 22572339Sabial register char c; 22672339Sabial 22772339Sabialagain: 22872339Sabial c = getc(ec); 22972339Sabial if (!INSUB() && ec != '\'') { 23072339Sabial if (c == '`') { 23172339Sabial if (grave(quoted) == 0) 23272339Sabial return(0); 23372339Sabial e.iop->task = XGRAVE; 23472339Sabial goto again; 23572339Sabial } 23672339Sabial if (c == '$' && (c = dollar(quoted)) == 0) { 23772339Sabial e.iop->task = XDOLL; 23872339Sabial goto again; 23972339Sabial } 24072339Sabial } 24172339Sabial return(c); 24272339Sabial} 24372339Sabial 24472339Sabial/* 24572339Sabial * Prepare to generate the string returned by ${} substitution. 24672339Sabial */ 24772339Sabialstatic int 24872339Sabialdollar(quoted) 24972339Sabialint quoted; 25072339Sabial{ 25172339Sabial int otask; 25272339Sabial struct io *oiop; 25372339Sabial char *dolp; 25472339Sabial register char *s, c, *cp; 25572339Sabial struct var *vp; 25672339Sabial 25772339Sabial c = readc(); 25872339Sabial s = e.linep; 25972339Sabial if (c != '{') { 26072339Sabial *e.linep++ = c; 26172339Sabial if (letter(c)) { 26272339Sabial while ((c = readc())!=0 && letnum(c)) 26372339Sabial if (e.linep < elinep) 26472339Sabial *e.linep++ = c; 26572339Sabial unget(c); 26672339Sabial } 26772339Sabial c = 0; 26872339Sabial } else { 26972339Sabial oiop = e.iop; 27072339Sabial otask = e.iop->task; 27172339Sabial e.iop->task = XOTHER; 27272339Sabial while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n') 27372339Sabial if (e.linep < elinep) 27472339Sabial *e.linep++ = c; 27572339Sabial if (oiop == e.iop) 27672339Sabial e.iop->task = otask; 27772339Sabial if (c != '}') { 27872339Sabial err("unclosed ${"); 27972339Sabial gflg++; 28072339Sabial return(c); 28172339Sabial } 28272339Sabial } 28372339Sabial if (e.linep >= elinep) { 28472339Sabial err("string in ${} too long"); 28572339Sabial gflg++; 28672339Sabial e.linep -= 10; 28772339Sabial } 28872339Sabial *e.linep = 0; 28972339Sabial if (*s) 29072339Sabial for (cp = s+1; *cp; cp++) 29172339Sabial if (any(*cp, "=-+?")) { 29272339Sabial c = *cp; 29372339Sabial *cp++ = 0; 29472339Sabial break; 29572339Sabial } 29672339Sabial if (s[1] == 0 && (*s == '*' || *s == '@')) { 29772339Sabial if (dolc > 1) { 29872339Sabial /* currently this does not distinguish $* and $@ */ 29972339Sabial /* should check dollar */ 30072339Sabial e.linep = s; 30172339Sabial PUSHIO(awordlist, dolv+1, dolchar); 30272339Sabial return(0); 30372339Sabial } else { /* trap the nasty ${=} */ 30472339Sabial s[0] = '1'; 30572339Sabial s[1] = 0; 30672339Sabial } 30772339Sabial } 30872339Sabial vp = lookup(s); 30972339Sabial if ((dolp = vp->value) == null) { 31072339Sabial switch (c) { 31172339Sabial case '=': 31272339Sabial if (digit(*s)) { 31372339Sabial err("cannot use ${...=...} with $n"); 31472339Sabial gflg++; 31572339Sabial break; 31672339Sabial } 31772339Sabial setval(vp, cp); 31872339Sabial dolp = vp->value; 31972339Sabial break; 32072339Sabial 32172339Sabial case '-': 32272339Sabial dolp = strsave(cp, areanum); 32372339Sabial break; 32472339Sabial 32572339Sabial case '?': 32672339Sabial if (*cp == 0) { 32772339Sabial prs("missing value for "); 32872339Sabial err(s); 32972339Sabial } else 33072339Sabial err(cp); 33172339Sabial gflg++; 33272339Sabial break; 33372339Sabial } 33472339Sabial } else if (c == '+') 33572339Sabial dolp = strsave(cp, areanum); 33672339Sabial if (flag['u'] && dolp == null) { 33772339Sabial prs("unset variable: "); 33872339Sabial err(s); 33972339Sabial gflg++; 34072339Sabial } 34172339Sabial e.linep = s; 34272339Sabial PUSHIO(aword, dolp, quoted ? qstrchar : strchar); 34372339Sabial return(0); 34472339Sabial} 34572339Sabial 34672339Sabial/* 34772339Sabial * Run the command in `...` and read its output. 34872339Sabial */ 34972339Sabialstatic int 35072339Sabialgrave(quoted) 35172339Sabialint quoted; 35272339Sabial{ 35372339Sabial register char *cp; 35472339Sabial register int i; 35572339Sabial int pf[2]; 35672339Sabial 35772339Sabial for (cp = e.iop->argp->aword; *cp != '`'; cp++) 35872339Sabial if (*cp == 0) { 35972339Sabial err("no closing `"); 36072339Sabial return(0); 36172339Sabial } 36272339Sabial if (openpipe(pf) < 0) 36372339Sabial return(0); 36472339Sabial if ((i = fork()) == -1) { 36572339Sabial closepipe(pf); 36672339Sabial err("try again"); 36772339Sabial return(0); 36872339Sabial } 36972339Sabial if (i != 0) { 37072339Sabial e.iop->argp->aword = ++cp; 37172339Sabial close(pf[1]); 37272339Sabial PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar); 37372339Sabial return(1); 37472339Sabial } 37572339Sabial *cp = 0; 37672339Sabial /* allow trapped signals */ 37772339Sabial for (i=0; i<=_NSIG; i++) 37872339Sabial if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN) 37972339Sabial signal(i, SIG_DFL); 38072339Sabial dup2(pf[1], 1); 38172339Sabial closepipe(pf); 38272339Sabial flag['e'] = 0; 38372339Sabial flag['v'] = 0; 38472339Sabial flag['n'] = 0; 38572339Sabial cp = strsave(e.iop->argp->aword, 0); 38672339Sabial areanum = 1; 38772339Sabial freehere(areanum); 38872339Sabial freearea(areanum); /* free old space */ 38972339Sabial e.oenv = NULL; 39072339Sabial e.iop = (e.iobase = iostack) - 1; 39172339Sabial unquote(cp); 39272339Sabial talking = 0; 39372339Sabial PUSHIO(aword, cp, nlchar); 39472339Sabial onecommand(); 39572339Sabial exit(1); 39672339Sabial} 39772339Sabial 39872339Sabialchar * 39972339Sabialunquote(as) 40072339Sabialregister char *as; 40172339Sabial{ 40272339Sabial register char *s; 40372339Sabial 40472339Sabial if ((s = as) != NULL) 40572339Sabial while (*s) 40672339Sabial *s++ &= ~QUOTE; 40772339Sabial return(as); 40872339Sabial} 40972339Sabial 41072339Sabial/* -------- glob.c -------- */ 41172339Sabial/* #include "sh.h" */ 41272339Sabial 41372339Sabial/* 41472339Sabial * glob 41572339Sabial */ 41672339Sabial 41772339Sabial#define scopy(x) strsave((x), areanum) 41872339Sabial#define BLKSIZ 512 41972339Sabial#define NDENT ((BLKSIZ+sizeof(struct dirent)-1)/sizeof(struct dirent)) 42072339Sabial 42172339Sabialstatic struct wdblock *cl, *nl; 42272339Sabialstatic char spcl[] = "[?*"; 42372339Sabial 42472339Sabialstruct wdblock * 42572339Sabialglob(cp, wb) 42672339Sabialchar *cp; 42772339Sabialstruct wdblock *wb; 42872339Sabial{ 42972339Sabial register i; 43072339Sabial register char *pp; 43172339Sabial 43272339Sabial if (cp == 0) 43372339Sabial return(wb); 43472339Sabial i = 0; 43572339Sabial for (pp = cp; *pp; pp++) 43672339Sabial if (any(*pp, spcl)) 43772339Sabial i++; 43872339Sabial else if (!any(*pp & ~QUOTE, spcl)) 43972339Sabial *pp &= ~QUOTE; 44072339Sabial if (i != 0) { 44172339Sabial for (cl = addword(scopy(cp), (struct wdblock *)0); anyspcl(cl); cl = nl) { 44272339Sabial nl = newword(cl->w_nword*2); 44372339Sabial for(i=0; i<cl->w_nword; i++) { /* for each argument */ 44472339Sabial for (pp = cl->w_words[i]; *pp; pp++) 44572339Sabial if (any(*pp, spcl)) { 44672339Sabial globname(cl->w_words[i], pp); 44772339Sabial break; 44872339Sabial } 44972339Sabial if (*pp == '\0') 45072339Sabial nl = addword(scopy(cl->w_words[i]), nl); 45172339Sabial } 45272339Sabial for(i=0; i<cl->w_nword; i++) 45372339Sabial DELETE(cl->w_words[i]); 45472339Sabial DELETE(cl); 45572339Sabial } 45672339Sabial for(i=0; i<cl->w_nword; i++) 45772339Sabial unquote(cl->w_words[i]); 45872339Sabial glob0((char *)cl->w_words, cl->w_nword, sizeof(char *), xstrcmp); 45972339Sabial if (cl->w_nword) { 46072339Sabial for (i=0; i<cl->w_nword; i++) 46172339Sabial wb = addword(cl->w_words[i], wb); 46272339Sabial DELETE(cl); 46372339Sabial return(wb); 46472339Sabial } 46572339Sabial } 46672339Sabial wb = addword(unquote(cp), wb); 46772339Sabial return(wb); 46872339Sabial} 46972339Sabial 47072339Sabialvoid 47172339Sabialglobname(we, pp) 47272339Sabialchar *we; 47372339Sabialregister char *pp; 47472339Sabial{ 47572339Sabial register char *np, *cp; 47672339Sabial char *name, *gp, *dp; 47772339Sabial int dn, j, n, k; 47872339Sabial DIR *dirp; 47972339Sabial struct dirent *de; 48072339Sabial char dname[NAME_MAX+1]; 48172339Sabial struct stat dbuf; 48272339Sabial 48372339Sabial for (np = we; np != pp; pp--) 48472339Sabial if (pp[-1] == '/') 48572339Sabial break; 48672339Sabial for (dp = cp = space((int)(pp-np)+3); np < pp;) 48772339Sabial *cp++ = *np++; 48872339Sabial *cp++ = '.'; 48972339Sabial *cp = '\0'; 49072339Sabial for (gp = cp = space(strlen(pp)+1); *np && *np != '/';) 49172339Sabial *cp++ = *np++; 49272339Sabial *cp = '\0'; 49372339Sabial dirp = opendir(dp); 49472339Sabial if (dirp == 0) { 49572339Sabial DELETE(dp); 49672339Sabial DELETE(gp); 49772339Sabial return; 49872339Sabial } 49972339Sabial dname[NAME_MAX] = '\0'; 50072339Sabial while ((de=readdir(dirp))!=NULL) { 50172339Sabial /* XXX Hmmm... What this could be? (abial) */ 50272339Sabial /* 50372339Sabial if (ent[j].d_ino == 0) 50472339Sabial continue; 50572339Sabial */ 50672339Sabial strncpy(dname, de->d_name, NAME_MAX); 50772339Sabial if (dname[0] == '.') 50872339Sabial if (*gp != '.') 50972339Sabial continue; 51072339Sabial for(k=0; k<NAME_MAX; k++) 51172339Sabial if (any(dname[k], spcl)) 51272339Sabial dname[k] |= QUOTE; 51372339Sabial if (gmatch(dname, gp)) { 51472339Sabial name = generate(we, pp, dname, np); 51572339Sabial if (*np && !anys(np, spcl)) { 51672339Sabial if (stat(name,&dbuf)) { 51772339Sabial DELETE(name); 51872339Sabial continue; 51972339Sabial } 52072339Sabial } 52172339Sabial nl = addword(name, nl); 52272339Sabial } 52372339Sabial } 52472339Sabial closedir(dirp); 52572339Sabial DELETE(dp); 52672339Sabial DELETE(gp); 52772339Sabial} 52872339Sabial 52972339Sabial/* 53072339Sabial * generate a pathname as below. 53172339Sabial * start..end1 / middle end 53272339Sabial * the slashes come for free 53372339Sabial */ 53472339Sabialstatic char * 53572339Sabialgenerate(start1, end1, middle, end) 53672339Sabialchar *start1; 53772339Sabialregister char *end1; 53872339Sabialchar *middle, *end; 53972339Sabial{ 54072339Sabial char *p; 54172339Sabial register char *op, *xp; 54272339Sabial 54372339Sabial p = op = space((int)(end1-start1)+strlen(middle)+strlen(end)+2); 54472339Sabial for (xp = start1; xp != end1;) 54572339Sabial *op++ = *xp++; 54672339Sabial for (xp = middle; (*op++ = *xp++) != '\0';) 54772339Sabial ; 54872339Sabial op--; 54972339Sabial for (xp = end; (*op++ = *xp++) != '\0';) 55072339Sabial ; 55172339Sabial return(p); 55272339Sabial} 55372339Sabial 55472339Sabialstatic int 55572339Sabialanyspcl(wb) 55672339Sabialregister struct wdblock *wb; 55772339Sabial{ 55872339Sabial register i; 55972339Sabial register char **wd; 56072339Sabial 56172339Sabial wd = wb->w_words; 56272339Sabial for (i=0; i<wb->w_nword; i++) 56372339Sabial if (anys(spcl, *wd++)) 56472339Sabial return(1); 56572339Sabial return(0); 56672339Sabial} 56772339Sabial 56872339Sabialstatic int 56972339Sabialxstrcmp(p1, p2) 57072339Sabialchar *p1, *p2; 57172339Sabial{ 57272339Sabial return(strcmp(*(char **)p1, *(char **)p2)); 57372339Sabial} 57472339Sabial 57572339Sabial/* -------- word.c -------- */ 57672339Sabial/* #include "sh.h" */ 57772339Sabial/* #include "word.h" */ 57872339Sabial 57972339Sabial#define NSTART 16 /* default number of words to allow for initially */ 58072339Sabial 58172339Sabialstruct wdblock * 58272339Sabialnewword(nw) 58372339Sabialregister int nw; 58472339Sabial{ 58572339Sabial register struct wdblock *wb; 58672339Sabial 58772339Sabial wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *)); 58872339Sabial wb->w_bsize = nw; 58972339Sabial wb->w_nword = 0; 59072339Sabial return(wb); 59172339Sabial} 59272339Sabial 59372339Sabialstruct wdblock * 59472339Sabialaddword(wd, wb) 59572339Sabialchar *wd; 59672339Sabialregister struct wdblock *wb; 59772339Sabial{ 59872339Sabial register struct wdblock *wb2; 59972339Sabial register nw; 60072339Sabial 60172339Sabial if (wb == NULL) 60272339Sabial wb = newword(NSTART); 60372339Sabial if ((nw = wb->w_nword) >= wb->w_bsize) { 60472339Sabial wb2 = newword(nw * 2); 60572339Sabial memcopy((char *)wb2->w_words, (char *)wb->w_words, nw*sizeof(char *)); 60672339Sabial wb2->w_nword = nw; 60772339Sabial DELETE(wb); 60872339Sabial wb = wb2; 60972339Sabial } 61072339Sabial wb->w_words[wb->w_nword++] = wd; 61172339Sabial return(wb); 61272339Sabial} 61372339Sabial 61472339Sabialchar ** 61572339Sabialgetwords(wb) 61672339Sabialregister struct wdblock *wb; 61772339Sabial{ 61872339Sabial register char **wd; 61972339Sabial register nb; 62072339Sabial 62172339Sabial if (wb == NULL) 62272339Sabial return((char **)NULL); 62372339Sabial if (wb->w_nword == 0) { 62472339Sabial DELETE(wb); 62572339Sabial return((char **)NULL); 62672339Sabial } 62772339Sabial wd = (char **) space(nb = sizeof(*wd) * wb->w_nword); 62872339Sabial memcopy((char *)wd, (char *)wb->w_words, nb); 62972339Sabial DELETE(wb); /* perhaps should done by caller */ 63072339Sabial return(wd); 63172339Sabial} 63272339Sabial 63372339Sabial_PROTOTYPE(int (*func), (char *, char *)); 63472339Sabialint globv; 63572339Sabial 63672339Sabialvoid 63772339Sabialglob0(a0, a1, a2, a3) 63872339Sabialchar *a0; 63972339Sabialunsigned a1; 64072339Sabialint a2; 64172339Sabial_PROTOTYPE(int (*a3), (char *, char *)); 64272339Sabial{ 64372339Sabial func = a3; 64472339Sabial globv = a2; 64572339Sabial glob1(a0, a0 + a1 * a2); 64672339Sabial} 64772339Sabial 64872339Sabialvoid 64972339Sabialglob1(base, lim) 65072339Sabialchar *base, *lim; 65172339Sabial{ 65272339Sabial register char *i, *j; 65372339Sabial int v2; 65472339Sabial char *lptr, *hptr; 65572339Sabial int c; 65672339Sabial unsigned n; 65772339Sabial 65872339Sabial 65972339Sabial v2 = globv; 66072339Sabial 66172339Sabialtop: 66272339Sabial if ((n=(int)(lim-base)) <= v2) 66372339Sabial return; 66472339Sabial n = v2 * (n / (2*v2)); 66572339Sabial hptr = lptr = base+n; 66672339Sabial i = base; 66772339Sabial j = lim-v2; 66872339Sabial for(;;) { 66972339Sabial if (i < lptr) { 67072339Sabial if ((c = (*func)(i, lptr)) == 0) { 67172339Sabial glob2(i, lptr -= v2); 67272339Sabial continue; 67372339Sabial } 67472339Sabial if (c < 0) { 67572339Sabial i += v2; 67672339Sabial continue; 67772339Sabial } 67872339Sabial } 67972339Sabial 68072339Sabialbegin: 68172339Sabial if (j > hptr) { 68272339Sabial if ((c = (*func)(hptr, j)) == 0) { 68372339Sabial glob2(hptr += v2, j); 68472339Sabial goto begin; 68572339Sabial } 68672339Sabial if (c > 0) { 68772339Sabial if (i == lptr) { 68872339Sabial glob3(i, hptr += v2, j); 68972339Sabial i = lptr += v2; 69072339Sabial goto begin; 69172339Sabial } 69272339Sabial glob2(i, j); 69372339Sabial j -= v2; 69472339Sabial i += v2; 69572339Sabial continue; 69672339Sabial } 69772339Sabial j -= v2; 69872339Sabial goto begin; 69972339Sabial } 70072339Sabial 70172339Sabial 70272339Sabial if (i == lptr) { 70372339Sabial if (lptr-base >= lim-hptr) { 70472339Sabial glob1(hptr+v2, lim); 70572339Sabial lim = lptr; 70672339Sabial } else { 70772339Sabial glob1(base, lptr); 70872339Sabial base = hptr+v2; 70972339Sabial } 71072339Sabial goto top; 71172339Sabial } 71272339Sabial 71372339Sabial 71472339Sabial glob3(j, lptr -= v2, i); 71572339Sabial j = hptr -= v2; 71672339Sabial } 71772339Sabial} 71872339Sabial 71972339Sabialvoid 72072339Sabialglob2(i, j) 72172339Sabialchar *i, *j; 72272339Sabial{ 72372339Sabial register char *index1, *index2, c; 72472339Sabial int m; 72572339Sabial 72672339Sabial m = globv; 72772339Sabial index1 = i; 72872339Sabial index2 = j; 72972339Sabial do { 73072339Sabial c = *index1; 73172339Sabial *index1++ = *index2; 73272339Sabial *index2++ = c; 73372339Sabial } while(--m); 73472339Sabial} 73572339Sabial 73672339Sabialvoid 73772339Sabialglob3(i, j, k) 73872339Sabialchar *i, *j, *k; 73972339Sabial{ 74072339Sabial register char *index1, *index2, *index3; 74172339Sabial int c; 74272339Sabial int m; 74372339Sabial 74472339Sabial m = globv; 74572339Sabial index1 = i; 74672339Sabial index2 = j; 74772339Sabial index3 = k; 74872339Sabial do { 74972339Sabial c = *index1; 75072339Sabial *index1++ = *index3; 75172339Sabial *index3++ = *index2; 75272339Sabial *index2++ = c; 75372339Sabial } while(--m); 75472339Sabial} 75572339Sabial 75672339Sabialchar * 75772339Sabialmemcopy(ato, from, nb) 75872339Sabialregister char *ato, *from; 75972339Sabialregister int nb; 76072339Sabial{ 76172339Sabial register char *to; 76272339Sabial 76372339Sabial to = ato; 76472339Sabial while (--nb >= 0) 76572339Sabial *to++ = *from++; 76672339Sabial return(ato); 76772339Sabial} 768