static List *mkcmdarg(Node *n) { char *name; List *ret = nnew(List); Estack *e = nnew(Estack); Edata efd; int p[2]; if (pipe(p) < 0) { uerror("pipe"); return NULL; } if (rc_fork() == 0) { setsigdefaults(FALSE); if (mvfd(p[n->u[0].i == rFrom], n->u[0].i == rFrom) < 0) /* stupid hack */ exit(1); close(p[n->u[0].i != rFrom]); redirq = NULL; walk(n->u[2].p, FALSE); exit(getstatus()); } #if HAVE_DEV_FD name = nprint("/dev/fd/%d", p[n->u[0].i != rFrom]); #else name = nprint("/proc/self/fd/%d", p[n->u[0].i != rFrom]); #endif efd.fd = p[n->u[0].i != rFrom]; except(eFd, efd, e); close(p[n->u[0].i == rFrom]); ret->w = name; ret->m = NULL; ret->n = NULL; return ret; }
extern List *glob(List *s) { List *top, *r; bool meta; s = expandtilde(s); for (r = s, meta = FALSE; r != NULL; r = r->n) if (r->m != NULL) meta = TRUE; if (!meta) return s; /* don't copy lists with no metacharacters in them */ for (top = r = NULL; s != NULL; s = s->n) { if (s->m == NULL) { /* no metacharacters; just tack on to the return list */ if (top == NULL) top = r = nnew(List); else r = r->n = nnew(List); r->w = s->w; } else { if (top == NULL) top = r = sort(doglob(s->w, s->m)); else r->n = sort(doglob(s->w, s->m)); while (r->n != NULL) r = r->n; } } r->n = NULL; return top; }
static List *dmatch(char *d, char *p, char *m) { bool matched = FALSE; List *top, *r; static DIR *dirp; static struct dirent *dp; static struct stat s; /* prototypes for XXXdir functions. comment out if necessary */ extern DIR *opendir(const char *); extern struct dirent *readdir(DIR *); /*extern int closedir(DIR *);*/ top = r = NULL; /* opendir succeeds on regular files on some systems, so the stat() call is necessary (sigh) */ if (stat(d, &s) < 0 || (s.st_mode & S_IFMT) != S_IFDIR || (dirp = opendir(d)) == NULL) return NULL; while ((dp = readdir(dirp)) != NULL) if ((*dp->d_name != '.' || *p == '.') && match(p, m, dp->d_name)) { /* match ^. explicitly */ matched = TRUE; if (top == NULL) top = r = nnew(List); else r = r->n = nnew(List); r->w = ncpy(dp->d_name); r->m = NULL; } closedir(dirp); if (!matched) return NULL; r->n = NULL; return top; }
static List *dmatch(char *d, char *p, char *m) { bool matched; List *top, *r; static DIR *dirp; static struct dirent *dp; static struct stat s; int i; /* return a match if there are no metacharacters; allows globbing through directories with no read permission. make sure the file exists, though. */ matched = TRUE; if (m != NULL) for (i = 0; p[i] != '\0'; i++) if (m[i]) { matched = FALSE; break; } if (matched) { char *path = nprint("%s/%s", d, p); if (lstat(path, &s) < 0) return NULL; r = nnew(List); r->w = ncpy(p); r->m = NULL; r->n = NULL; return r; } top = r = NULL; if (*d == '\0') d = "/"; if ((dirp = opendir(d)) == NULL) return NULL; /* opendir succeeds on regular files on some systems, so the stat() call is necessary (sigh) */ if (stat(d, &s) < 0 || (s.st_mode & S_IFMT) != S_IFDIR) { closedir(dirp); return NULL; } while ((dp = readdir(dirp)) != NULL) if ((*dp->d_name != '.' || *p == '.') && match(p, m, dp->d_name)) { /* match ^. explicitly */ matched = TRUE; if (top == NULL) top = r = nnew(List); else r = r->n = nnew(List); r->w = ncpy(dp->d_name); r->m = NULL; } closedir(dirp); if (!matched) return NULL; r->n = NULL; return top; }
extern void qredir(Node *n) { Rq *next; if (redirq == NULL) { next = redirq = nnew(Rq); } else { for (next = redirq; next->n != NULL; next = next->n) ; next->n = nnew(Rq); next = next->n; } next->r = n; next->n = NULL; }
static List *expandtilde(List *s) { List *top, *r, *var; char *home; size_t i, j, hsize, psize; bool tilde; for (r = s, tilde = FALSE; r != NULL; r = r->n) if (r->m != NULL && r->m[0] && r->w[0] == '~') tilde = TRUE; if (!tilde) return s; for (top = NULL; s != NULL; s = s->n) { if (top == NULL) top = r = nnew(List); else r = r->n = nnew(List); r->w = s->w; r->m = s->m; if (s->m == NULL || !s->m[0] || s->w[0] != '~') continue; for (i = 1; s->w[i] != '/' && s->w[i] != '\0'; i++); home = NULL; if (i == 1) { if ((var = varlookup("HOME")) != NULL) home = var->w; } else { char c = s->w[i]; struct passwd *pw; s->w[i] = '\0'; if ((pw = getpwnam(s->w + 1)) != NULL) home = pw->pw_dir; s->w[i] = c; } if (home == NULL || (hsize = strlen(home)) == 0) continue; psize = strlen(s->w + i) + 1; r->w = nalloc(psize + hsize); memcpy(r->w, home, hsize); memcpy(r->w + hsize, s->w + i, psize); for (j = i; s->w[j] != '\0'; j++) if (s->m[j]) break; if (s->w[j] != '\0') { r->m = nalloc(psize + hsize); memset(r->m, 0, hsize); memcpy(r->m + hsize, s->m + i, psize); } else r->m = NULL; } r->n = NULL; return top; }
extern List *append(List *s1, List *s2) { List *r, *top; if (s1 == NULL) return s2; if (s2 == NULL) return s1; for (r = top = nnew(List); 1; r = r->n = nnew(List)) { r->w = s1->w; r->m = s1->m; if ((s1 = s1->n) == NULL) break; } r->n = s2; return top; }
static List *count(List *l) { List *s = nnew(List); s->w = nprint("%d", listnel(l)); s->n = NULL; s->m = NULL; return s; }
static List *mkcmdarg(Node *n) { int fd; char *name; Edata efifo; Estack *e = enew(Estack); List *ret = nnew(List); static int fifonumber = 0; name = nprint("/tmp/rc%d.%d", getpid(), fifonumber++); if (mkfifo(name, 0666) < 0) { uerror("mkfifo"); return NULL; } if (rc_fork() == 0) { setsigdefaults(FALSE); fd = rc_open(name, (n->u[0].i != rFrom) ? rFrom : rCreate); /* stupid hack */ if (fd < 0) { uerror("open"); exit(1); } if (mvfd(fd, (n->u[0].i == rFrom)) < 0) /* same stupid hack */ exit(1); redirq = NULL; walk(n->u[2].p, FALSE); exit(getstatus()); } efifo.name = name; except(eFifo, efifo, e); ret->w = name; ret->m = NULL; ret->n = NULL; return ret; }
extern List *word(char *w, char *m) { List *s = NULL; if (w != NULL) { s = nnew(List); s->w = w; s->m = m; s->n = NULL; } return s; }
extern List *concat(List *s1, List *s2) { int n1, n2; List *r, *top; if (s1 == NULL) return s2; if (s2 == NULL) return s1; if ((n1 = listnel(s1)) != (n2 = listnel(s2)) && n1 != 1 && n2 != 1) rc_error("bad concatenation"); for (r = top = nnew(List); 1; r = r->n = nnew(List)) { size_t x = strlen(s1->w); size_t y = strlen(s2->w); size_t z = x + y + 1; r->w = nalloc(z); strcpy(r->w, s1->w); strcat(r->w, s2->w); if (s1->m == NULL && s2->m == NULL) { r->m = NULL; } else { r->m = nalloc(z); if (s1->m == NULL) memzero(r->m, x); else memcpy(r->m, s1->m, x); if (s2->m == NULL) memzero(&r->m[x], y); else memcpy(&r->m[x], s2->m, y); r->m[z] = 0; } if (n1 > 1) s1 = s1->n; if (n2 > 1) s2 = s2->n; if (s1 == NULL || s2 == NULL || (n1 == 1 && n2 == 1)) break; } r->n = NULL; return top; }
extern List *sgetstatus() { List *r = NULL; int i; for (i = 0; i < pipelength; i++) { List *q = nnew(List); q->w = strstatus(statuses[i]); q->m = NULL; q->n = r; r = q; } return r; }
extern List *varsub(List *var, List *subs) { List *r, *top; int n = listnel(var); for (top = r = NULL; subs != NULL; subs = subs->n) { int i = a2u(subs->w); if (i < 1) rc_error("bad subscript"); if (i <= n) { List *sub = var; while (--i) sub = sub->n; /* loop until sub == var(i) */ if (top == NULL) top = r = nnew(List); else r = r->n = nnew(List); r->w = sub->w; r->m = sub->m; } } if (top != NULL) r->n = NULL; return top; }
void ladd(list *list, void *val) { node *link = nnew(val); if(list->head == NULL) { list->head = link; } else { node *iter = list->head; while(iter->next != NULL) { iter = iter->next; } iter->next = link; } list->size++; }
static inline void split(const X& x, size_t minsubs, XX& xx, L & pathlen) { // Split subintervals in the interval vector X so that, to working // precision, no subinterval is longer than 1/minsubs times the // total path length. Removes subintervals of zero length, except // that the resulting X will always has at least two elements on // return, i.e., if the total path length is zero, X will be // collapsed into a single interval of zero length. Also returns // the integration path length. typedef typename X::value_type itype_t; typedef typename meta::as_logical<itype_t> btype_t; typedef typename meta::as_integer<itype_t, signed> iitype_t; typedef typename container::table<itype_t> itab_t; typedef typename meta::as_real<itype_t>::type rtype_t; typedef typename container::table<rtype_t> rtab_t; typedef typename container::table<ptrdiff_t> ptab_t; rtab_t absdx = nt2::abs(nt2::diff(x)); pathlen = nt2::globalasum1(absdx); xx = x; if (pathlen > 0) { rtype_t udelta = minsubs/pathlen; rtab_t tmp_nnew = nt2::minusone(nt2::ceil(absdx*udelta)); //BOOST_AUTO_TPL(tmp_nnew, nt2::minusone(nt2::ceil(absdx*udelta))); ptab_t idxnew = nt2::rowvect(nt2::find(is_gtz(tmp_nnew))); rtab_t nnew = tmp_nnew(idxnew); for (size_t j = nt2::numel(idxnew); j >= 1; --j) { ptrdiff_t k = idxnew(j); rtype_t nnj = nnew(j); //Calculate new points. itab_t newpts = x(k)+(nt2::_(One<rtype_t>(), nnj)/oneplus(nnj))*(x(k+1)-x(k)); // newpts = newpts+x(k); // Insert the new points. itab_t xx1 = nt2::cath(nt2::cath(xx(nt2::_(begin_, k)),newpts),xx(nt2::_(k+1, end_))); xx = xx1; } } // Remove useless subintervals. itab_t xx1 = xx(nt2::cath(nt2::One<ptrdiff_t>(), nt2::oneplus(nt2::rowvect(nt2::find(nt2::is_nez(nt2::diff(xx))))))); if (nt2::isscalar(xx1)) xx = nt2::repnum(xx(begin_), 2, 1); else xx = xx1; }
extern List *sgetstatus() { List *r; int i; for (r = NULL, i = 0; i < pipelength; i++) { List *q = nnew(List); int s = statuses[i]; int t; q->n = r; r = q; if ((t = s & 0x7f) != 0) { const char *core = (s & 0x80) ? "+core" : ""; if (t < NUMOFSIGNALS && *signals[t].name != '\0') r->w = nprint("%s%s", signals[t].name, core); else r->w = nprint("-%d%s", t, core); /* unknown signals are negated */ } else r->w = nprint("%d", (s >> 8) & 0xff); r->m = NULL; } return r; }
extern List *flatten(List *s) { List *r; size_t step; char *f; if (s == NULL || s->n == NULL) return s; r = nnew(List); f = r->w = nalloc(listlen(s) + 1); r->m = NULL; /* flattened lists come from variables, so no meta */ r->n = NULL; strcpy(f, s->w); f += strlen(s->w); do { *f++ = ' '; s = s->n; step = strlen(s->w); memcpy(f, s->w, step); f += step; } while (s->n != NULL); *f = '\0'; return r; }
static List *doglob(char *w, char *m) { static char *dir = NULL, *pattern = NULL, *metadir = NULL, *metapattern = NULL; static size_t dsize = 0; char *d, *p, *md, *mp; size_t psize; char *s = w; List firstdir; List *matched; if ((psize = strlen(w) + 1) > dsize || dir == NULL) { efree(dir); efree(pattern); efree(metadir); efree(metapattern); dir = ealloc(psize); pattern = ealloc(psize); metadir = ealloc(psize); metapattern = ealloc(psize); dsize = psize; } d = dir; p = pattern; md = metadir; mp = metapattern; while (*s != '/' && *s != '\0') { *d++ = *s++; /* get first directory component */ *md++ = *m++; } *d = '\0'; /* Special case: no slashes in the pattern, i.e., open the current directory. Remember that w cannot consist of slashes alone (the other way *s could be zero) since doglob gets called iff there's a metacharacter to be matched */ if (*s == '\0') { matched = dmatch(".", dir, metadir); goto end; } if (*w == '/') { firstdir.w = dir; firstdir.m = metadir; firstdir.n = NULL; matched = &firstdir; } else { /* we must glob against current directory, since the first character is not a slash. */ matched = dmatch(".", dir, metadir); } do { size_t slashcount; sigchk(); for (slashcount = 0; *s == '/'; s++, m++) slashcount++; /* skip slashes */ while (*s != '/' && *s != '\0') *p++ = *s++, *mp++ = *m++; /* get pattern */ *p = '\0'; matched = lglob(matched, pattern, metapattern, slashcount); p = pattern, mp = metapattern; } while (*s != '\0'); end: if (matched == NULL) { matched = nnew(List); matched->w = w; matched->m = NULL; matched->n = NULL; } return matched; }
static List *bqinput(List *ifs, int fd) { char *end, *bufend, *s; List *r, *top, *prev; size_t remain, bufsize; char isifs[256]; int n, state; /* a simple FSA is used to read in data */ memzero(isifs, sizeof isifs); for (isifs['\0'] = TRUE; ifs != NULL; ifs = ifs->n) for (s = ifs->w; *s != '\0'; s++) isifs[*(unsigned char *)s] = TRUE; remain = bufsize = BUFSIZE; top = r = nnew(List); r->w = end = nalloc(bufsize + 1); r->m = NULL; state = 0; prev = NULL; while (1) { if (remain == 0) { /* is the string bigger than the buffer? */ size_t m = end - r->w; char *buf; while (bufsize < m + BUFSIZE) bufsize *= 2; buf = nalloc(bufsize + 1); memcpy(buf, r->w, m); r->w = buf; end = &buf[m]; remain = bufsize - m; } if ((n = rc_read(fd, end, remain)) <= 0) { if (n == 0) /* break */ break; else if (errno == EINTR) return NULL; /* interrupted, wait for subproc */ else { uerror("backquote read"); rc_error(NULL); } } remain -= n; for (bufend = &end[n]; end < bufend; end++) if (state == 0) { if (!isifs[*(unsigned char *)end]) { state = 1; r->w = end; r->m = NULL; } } else { if (isifs[*(unsigned char *)end]) { state = 0; *end = '\0'; prev = r; r = r->n = nnew(List); r->w = end+1; r->m = NULL; } } } if (state == 1) { /* terminate last string */ *end = '\0'; r->n = NULL; } else { if (prev == NULL) /* no input at all? */ top = NULL; else prev->n = NULL; /* else terminate list */ } return top; }