diff options
Diffstat (limited to 'Src/subst.c')
-rw-r--r-- | Src/subst.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/Src/subst.c b/Src/subst.c index 1059508ef..4a5fe3a3c 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -169,7 +169,7 @@ stringsubst(LinkList list, LinkNode node, int pf_flags, int asssub) if (errflag) return NULL; if (!subst) - subst = ""; + rest = subst = ""; sublen = strlen(subst); restlen = strlen(rest); @@ -2878,6 +2878,67 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags) } break; } + } else if (inbrace && (*s == '^' || *s == Hat)) { + char **zip; + int shortest = 1; + ++s; + if (*s == '^' || *s == Hat) { + shortest = 0; + ++s; + } + if (*itype_end(s, IIDENT, 0)) { + untokenize(s); + zerr("not an identifier: %s", s); + return NULL; + } + if (vunset) { + if (unset(UNSET)) { + *idend = '\0'; + zerr("%s: parameter not set", idbeg); + return NULL; + } + val = dupstring(""); + } else { + char *sval; + zip = getaparam(s); + if (!zip) { + sval = getsparam(s); + if (sval) + zip = hmkarray(sval); + } + if (!isarr) aval = mkarray(val); + if (zip) { + char **out; + int alen, ziplen, outlen, i = 0; + alen = arrlen(aval); + ziplen = arrlen(zip); + outlen = shortest ^ (alen > ziplen) ? alen : ziplen; + if (!shortest && (alen == 0 || ziplen == 0)) { + if (ziplen) + aval = arrdup(zip); + } else { + out = zhalloc(sizeof(char *) * (2 * outlen + 1)); + while (i < outlen) { + if (copied) + out[i*2] = aval[i % alen]; + else + out[i*2] = dupstring(aval[i % alen]); + out[i*2+1] = dupstring(zip[i % ziplen]); + i++; + } + out[i*2] = NULL; + aval = out; + copied = 1; + isarr = 1; + } + } else { + if (unset(UNSET)) { + zerr("%s: parameter not set", s); + return NULL; + } + val = dupstring(""); + } + } } else if (inbrace && (*s == '|' || *s == Bar || *s == '*' || *s == Star)) { int intersect = (*s == '*' || *s == Star); @@ -2935,7 +2996,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags) */ if (!vunset) { if (isarr) { - aval = mkarray(NULL); + aval = hmkarray(NULL); } else { val = dupstring(""); } @@ -3754,19 +3815,19 @@ static char * arithsubst(char *a, char **bptr, char *rest) { char *s = *bptr, *t; - char buf[BDIGBUFSIZE], *b = buf; + char buf[BDIGBUFSIZE], *b; mnumber v; singsub(&a); v = matheval(a); if ((v.type & MN_FLOAT) && !outputradix) - b = convfloat(v.u.d, 0, 0, NULL); + b = convfloat_underscore(v.u.d, outputunderscore); else { if (v.type & MN_FLOAT) v.u.l = (zlong) v.u.d; - convbase(buf, v.u.l, outputradix); + b = convbase_underscore(buf, v.u.l, outputradix, outputunderscore); } - t = *bptr = (char *) hcalloc(strlen(*bptr) + strlen(b) + + t = *bptr = (char *) hcalloc(strlen(*bptr) + strlen(b) + strlen(rest) + 1); t--; while ((*++t = *s++)); |