static List *extractsinglematch(const char *subject, const char *pattern, const char *quoting, List *result) { int i; const char *s; if (!haswild(pattern, quoting) /* no wildcards, so no matches */ || !match(subject, pattern, quoting)) return NULL; for (s = subject, i = 0; pattern[i] != '\0'; s++) { if (ISQUOTED(quoting, i)) i++; else { int c = pattern[i++]; switch (c) { case '*': { const char *begin; if (pattern[i] == '\0') return mklist(mkstr(gcdup(s)), result); for (begin = s;; s++) { const char *q = TAILQUOTE(quoting, i); assert(*s != '\0'); if (match(s, pattern + i, q)) { result = mklist(mkstr(gcndup(begin, s - begin)), result); return haswild(pattern + i, q) ? extractsinglematch(s, pattern + i, q, result) : result; } } } case '[': { int j = rangematch(pattern + i, TAILQUOTE(quoting, i), *s); assert(j != RANGE_FAIL); if (j == RANGE_ERROR) { assert(*s == '['); break; } i += j; } /* FALLTHROUGH */ case '?': result = mklist(mkstr(str("%c", *s)), result); break; default: break; } } } return result; }
extern void splitstring(char *in, size_t len, Boolean endword) { Buffer *buf = buffer; unsigned char *s = (unsigned char *) in, *inend = s + len; if (splitchars) { assert(buf == NULL); while (s < inend) { Term *term = mkterm(gcndup((char *) s++, 1), NULL); value = mklist(term, value); } return; } if (!coalesce && buf == NULL) buf = openbuffer(0); while (s < inend) { int c = *s++; if (buf != NULL) if (isifs[c]) { Term *term = mkterm(sealcountedbuffer(buf), NULL); value = mklist(term, value); buf = coalesce ? NULL : openbuffer(0); } else buf = bufputc(buf, c); else if (!isifs[c]) buf = bufputc(openbuffer(0), c); } if (endword && buf != NULL) { Term *term = mkterm(sealcountedbuffer(buf), NULL); value = mklist(term, value); buf = NULL; } buffer = buf; }
/* expandhome -- do tilde expansion by calling fn %home */ static char *expandhome(char *s, StrList *qp) { int c; size_t slash; List *fn = varlookup("fn-%home", NULL); assert(*s == '~'); assert(qp->str == UNQUOTED || *qp->str == 'r'); if (fn == NULL) return s; for (slash = 1; (c = s[slash]) != '/' && c != '\0'; slash++) ; Ref(char *, string, s); Ref(StrList *, quote, qp); Ref(List *, list, NULL); RefAdd(fn); if (slash > 1) list = mklist(mkstr(gcndup(s + 1, slash - 1)), NULL); RefRemove(fn); list = eval(append(fn, list), NULL, 0); if (list != NULL) { if (list->next != NULL) fail("es:expandhome", "%%home returned more than one value"); Ref(char *, home, getstr(list->term)); if (c == '\0') { string = home; quote->str = QUOTED; } else { char *q; size_t pathlen = strlen(string); size_t homelen = strlen(home); size_t len = pathlen - slash + homelen; s = gcalloc(len + 1, &StringTag); memcpy(s, home, homelen); memcpy(&s[homelen], &string[slash], pathlen - slash); s[len] = '\0'; string = s; q = quote->str; if (q == UNQUOTED) { q = gcalloc(len + 1, &StringTag); memset(q, 'q', homelen); memset(&q[homelen], 'r', pathlen - slash); q[len] = '\0'; } else if (strchr(q, 'r') == NULL) q = QUOTED; else { q = gcalloc(len + 1, &StringTag); memset(q, 'q', homelen); memcpy(&q[homelen], "e->str[slash], pathlen - slash); q[len] = '\0'; } quote->str = q; } RefEnd(home); } RefEnd2(list, quote); RefReturn(string); }