int readp( /* get human-readable primitive */ PRIMITIVE *p, FILE *fp ) { char inbuf[MAXARGS]; register int c, nargs; int tmp; if (fp == NULL) fp = stdin; restart: if ((c = getc(fp)) == EOF) { /* used to be fatal */ mcopy((char *)p, (char *)&peof, sizeof(PRIMITIVE)); return(0); } if (c == CDELIM) { /* skip user comment */ fgets(inbuf, MAXARGS, fp); goto restart; } else if (c == '\n') /* skip empty line */ goto restart; if (!iscom(c)) error(USER, "bad command in readp"); p->com = c; fscanf(fp, "%o", &tmp); p->arg0 = tmp & 0377; if (isglob(c)) p->xy[XMN] = p->xy[YMN] = p->xy[XMX] = p->xy[YMX] = -1; else if (fscanf(fp, "%d %d %d %d", &p->xy[XMN], &p->xy[YMN], &p->xy[XMX], &p->xy[YMX]) != 4) error(USER, "missing extent in readp"); while ((c = getc(fp)) != EOF && c != '\n' && c != ADELIM); nargs = 0; if (c == ADELIM) while ((c = getc(fp)) != EOF && c != '\n' && nargs < MAXARGS-1) inbuf[nargs++] = c; if (nargs >= MAXARGS) error(USER, "too many arguments in readp"); if (nargs) { inbuf[nargs] = '\0'; p->args = savestr(inbuf); } else p->args = NULL; return(p->com != PEOF); }
static void sendsort( /* send a sorted list */ PLIST *pl, int (*pcmp)() ) { static int nf = 0, intree = FALSE; if (isglob(pl->pbot->com)) { /* send sorted output to stdout */ if (intree && nf <= NFILES) treemerge(0, 0, nf, pl, pcmp, stdout); else if (nf%NFILES == 0) if (intree) { treemerge(0, nf/NFILES - 1, NFILES, pl, pcmp, NULL); treemerge(1, 0, nf/NFILES, NULL, pcmp, stdout); } else treemerge(1, 0, nf/NFILES, pl, pcmp, stdout); else { treemerge(0, nf/NFILES, nf%NFILES, pl, pcmp, NULL); treemerge(1, 0, nf/NFILES + 1, NULL, pcmp, stdout); } nf = 0; /* all done */ intree = FALSE; /* reset for next time */ } else if (intree && nf%NFILES == 0) { /* merge NFILES with list */ treemerge(0, nf/NFILES - 1, NFILES, pl, pcmp, NULL); intree = FALSE; } else { /* output straight to temp file */ treemerge(-1, nf++, 0, pl, pcmp, NULL); intree = TRUE; } }
int tglob(Char **t) { int gflag; const Char *p; gflag = 0; while ((p = *t++) != '\0') { if (*p == '~' || *p == '=') gflag |= G_CSH; else if (*p == '{' && (p[1] == '\0' || (p[1] == '}' && p[2] == '\0'))) continue; while (*p != '\0') { if (*p == '`') { gflag |= G_CSH; #ifdef notdef /* * We do want to expand echo `echo '*'`, so we don't\ * use this piece of code anymore. */ p++; while (*p && *p != '`') if (*p++ == '\\') { if (*p) /* Quoted chars */ p++; else break; } if (!*p) /* The matching ` */ break; #endif } else if (*p == '{') gflag |= G_CSH; else if (isglob(*p)) gflag |= G_GLOB; else if (symlinks == SYM_EXPAND && p[1] && ISDOTDOT(p) && (p == *(t-1) || *(p-1) == '/') ) gflag |= G_CSH; p++; } } return gflag; }
void sort( /* sort primitives according to pcmp */ FILE *infp, int (*pcmp)() /* compares pointers to pointers to primitives! */ ) { PRIMITIVE *prims[PBSIZE]; /* pointers to primitives */ PLIST primlist; /* our primitives list */ int nprims; short done; do { for (nprims = 0; nprims < PBSIZE; nprims++) { /* read to global */ if ((prims[nprims] = palloc()) == NULL) error(SYSTEM, "memory exhausted in sort"); readp(prims[nprims], infp); if (isglob(prims[nprims]->com)) break; } qsort(prims, nprims, sizeof(*prims), pcmp); /* sort pointer array */ if (nprims < PBSIZE) /* tack on global if one */ nprims++; order(prims, nprims, &primlist); /* make array into list */ sendsort(&primlist, pcmp); /* send to merge sorter */ done = primlist.pbot->com == PEOF; plfree(&primlist); /* free up array */ } while (!done); }
static int wordsplit_pathexpand (struct wordsplit *wsp) { struct wordsplit_node *p, *next; char *pattern = NULL; size_t patsize = 0; size_t slen; int flags = 0; #ifdef GLOB_PERIOD if (wsp->ws_options & WRDSO_DOTGLOB) flags = GLOB_PERIOD; #endif for (p = wsp->ws_head; p; p = next) { const char *str; next = p->next; if (p->flags & _WSNF_QUOTE) continue; str = wsnode_ptr (wsp, p); slen = wsnode_len (p); if (isglob (str, slen)) { int i; glob_t g; struct wordsplit_node *prev; if (slen + 1 > patsize) { char *p = realloc (pattern, slen + 1); if (!p) return _wsplt_nomem (wsp); pattern = p; patsize = slen + 1; } memcpy (pattern, str, slen); pattern[slen] = 0; switch (glob (pattern, flags, NULL, &g)) { case 0: break; case GLOB_NOSPACE: free (pattern); return _wsplt_nomem (wsp); case GLOB_NOMATCH: if (wsp->ws_options & WRDSO_NULLGLOB) { wsnode_remove (wsp, p); wsnode_free (p); } else if (wsp->ws_options & WRDSO_FAILGLOB) { char buf[128]; if (wsp->ws_errno == WRDSE_USERERR) free (wsp->ws_usererr); snprintf (buf, sizeof (buf), _("no files match pattern %s"), pattern); free (pattern); wsp->ws_usererr = strdup (buf); if (!wsp->ws_usererr) return _wsplt_nomem (wsp); else return _wsplt_seterr (wsp, WRDSE_USERERR); } continue; default: free (pattern); return _wsplt_seterr (wsp, WRDSE_GLOBERR); } prev = p; for (i = 0; i < g.gl_pathc; i++) { struct wordsplit_node *newnode; char *newstr; if (wsnode_new (wsp, &newnode)) return 1; newstr = strdup (g.gl_pathv[i]); if (!newstr) return _wsplt_nomem (wsp); newnode->v.word = newstr; newnode->flags |= _WSNF_WORD|_WSNF_QUOTE; wsnode_insert (wsp, newnode, prev, 0); prev = newnode; } globfree (&g); wsnode_remove (wsp, p); wsnode_free (p); } } free (pattern); return 0; }