wordlist * cp_bquote(wordlist *wlist) { wordlist *wl, *nwl; char *s, *t, buf[BSIZE_SP], wbuf[BSIZE_SP], tbuf[BSIZE_SP]; int i; for (wl = wlist; wl; wl = wl->wl_next) { t = wl->wl_word; if (!t) continue; i = 0; loop: s = strchr(t, cp_back); if (s == NULL) continue; while (t < s) wbuf[i++] = *t++; wbuf[i] = '\0'; t++; s = buf; /* Get s and t past the next backquote. */ while (*t && (*t != cp_back)) *s++ = *t++; /* What the heck, let "echo `foo" work... */ *s = '\0'; t++; /* Get past the second ` */ if ((nwl = backeval(buf)) == NULL) { wlist->wl_word = NULL; return (wlist); } (void) strcpy(buf, wbuf); if (nwl->wl_word) { (void) strcat(buf, nwl->wl_word); tfree(nwl->wl_word); } nwl->wl_word = copy(buf); (void) strcpy(tbuf, t); wl = wl_splice(wl, nwl); for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev) ; /* MW. We must move to the begging of new wordlist. */ (void) strcpy(buf, wl->wl_word); i = (int) strlen(buf); (void) strcat(buf, tbuf); tfree(wl->wl_word); wl->wl_word = copy(buf); t = &wl->wl_word[i]; s = wl->wl_word; for (i = 0; s < t; s++) wbuf[i++] = *s; goto loop; } return (wlist); }
/* Substitute variable name by its value and restore to wordlist */ wordlist * cp_variablesubst(wordlist *wlist) { wordlist *wl; for (wl = wlist; wl; wl = wl->wl_next) { char *s_dollar; int i = 0; while ((s_dollar = strchr(wl->wl_word + i, cp_dol)) != NULL) { int prefix_len = (int) (s_dollar - wl->wl_word); char *tail = span_var_expr(s_dollar + 1); char *var = copy_substring(s_dollar + 1, tail); wordlist *nwl = vareval(var); tfree(var); if (nwl) { char *x = nwl->wl_word; char *tail_ = copy(tail); nwl->wl_word = tprintf("%.*s%s", prefix_len, wl->wl_word, nwl->wl_word); free(x); if (wlist == wl) wlist = nwl; wl = wl_splice(wl, nwl); i = (int) strlen(wl->wl_word); x = wl->wl_word; wl->wl_word = tprintf("%s%s", wl->wl_word, tail_); free(x); free(tail_); } else if (prefix_len || *tail) { char *x = wl->wl_word; wl->wl_word = tprintf("%.*s%s", prefix_len, wl->wl_word, tail); i = prefix_len; free(x); } else { wordlist *next = wl->wl_next; if (wlist == wl) wlist = next; wl_delete_slice(wl, next); if (!next) return wlist; wl = next; i = 0; } } } return (wlist); }