mod_export char * parse_subscript(char *s, int sub) { int l = strlen(s), err; char *t; if (!*s || *s == ']') return 0; lexsave(); untokenize(t = dupstring(s)); inpush(t, 0, NULL); strinbeg(0); len = 0; bptr = tokstr = s; bsiz = l + 1; err = dquote_parse(']', sub); if (err) { err = *bptr; *bptr = 0; untokenize(s); *bptr = err; s = 0; } else s = bptr; strinend(); inpop(); DPUTS(cmdsp, "BUG: parse_subscript: cmdstack not empty."); lexrestore(); return s; }
mod_export char * parse_subscript(char *s, int sub, int endchar) { int l = strlen(s), err; char *t; if (!*s || *s == endchar) return 0; zcontext_save(); untokenize(t = dupstring(s)); inpush(t, 0, NULL); strinbeg(0); lexbuf.len = 0; lexbuf.ptr = tokstr = s; lexbuf.siz = l + 1; err = dquote_parse(endchar, sub); if (err) { err = *lexbuf.ptr; *lexbuf.ptr = '\0'; untokenize(s); *lexbuf.ptr = err; s = NULL; } else { s = lexbuf.ptr; } strinend(); inpop(); DPUTS(cmdsp, "BUG: parse_subscript: cmdstack not empty."); zcontext_restore(); return s; }
mod_export char * parse_subscript(char *s, int sub, int endchar) { int l = strlen(s), err, toklen; char *t; if (!*s || *s == endchar) return 0; zcontext_save(); untokenize(t = dupstring(s)); inpush(t, 0, NULL); strinbeg(0); /* * Warning to Future Generations: * * This way of passing the subscript through the lexer is brittle. * Code above this for several layers assumes that when we tokenise * the input it goes into the same place as the original string. * However, the lexer may overwrite later bits of the string or * reallocate it, in particular when expanding aliaes. To get * around this, we copy the string and then copy it back. This is a * bit more robust but still relies on the underlying assumption of * length preservation. */ lexbuf.len = 0; lexbuf.ptr = tokstr = dupstring(s); lexbuf.siz = l + 1; err = dquote_parse(endchar, sub); toklen = (int)(lexbuf.ptr - tokstr); DPUTS(toklen > l, "Bad length for parsed subscript"); memcpy(s, tokstr, toklen); if (err) { char *strend = s + toklen; err = *strend; *strend = '\0'; untokenize(s); *strend = err; s = NULL; } else { s += toklen; } strinend(); inpop(); DPUTS(cmdsp, "BUG: parse_subscript: cmdstack not empty."); zcontext_restore(); return s; }
mod_export int parsestrnoerr(char *s) { int l = strlen(s), err; lexsave(); untokenize(s); inpush(dupstring(s), 0, NULL); strinbeg(0); len = 0; bptr = tokstr = s; bsiz = l + 1; err = dquote_parse('\0', 1); *bptr = '\0'; strinend(); inpop(); DPUTS(cmdsp, "BUG: parsestr: cmdstack not empty."); lexrestore(); return err; }
mod_export int parsestrnoerr(char **s) { int l = strlen(*s), err; zcontext_save(); untokenize(*s); inpush(dupstring(*s), 0, NULL); strinbeg(0); lexbuf.len = 0; lexbuf.ptr = tokstr = *s; lexbuf.siz = l + 1; err = dquote_parse('\0', 1); if (tokstr) *s = tokstr; *lexbuf.ptr = '\0'; strinend(); inpop(); DPUTS(cmdsp, "BUG: parsestr: cmdstack not empty."); zcontext_restore(); return err; }
mod_export int parse_subst_string(char *s) { int c, l = strlen(s), err, olen, lexstop_ret; if (!*s || !strcmp(s, nulstring)) return 0; lexsave(); untokenize(s); inpush(dupstring(s), 0, NULL); strinbeg(0); len = 0; bptr = tokstr = s; bsiz = l + 1; c = hgetc(); lexstop_ret = lexstop; c = gettokstr(c, 1); err = errflag; strinend(); inpop(); DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty."); olen = len; lexrestore(); errflag = err; if (c == LEXERR) { untokenize(s); return 1; } #ifdef DEBUG if (c != STRING || olen != l || errflag) { fprintf(stderr, "Oops. Bug in parse_subst_string: %s\n", olen < l ? "len < l" : errflag ? "errflag" : "c != STRING"); fflush(stderr); untokenize(s); return 1; } #endif return 0; }
mod_export int parse_subst_string(char *s) { int c, l = strlen(s), err; char *ptr; enum lextok ctok; if (!*s || !strcmp(s, nulstring)) return 0; zcontext_save(); untokenize(s); inpush(dupstring(s), 0, NULL); strinbeg(0); lexbuf.len = 0; lexbuf.ptr = tokstr = s; lexbuf.siz = l + 1; c = hgetc(); ctok = gettokstr(c, 1); err = errflag; strinend(); inpop(); DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty."); zcontext_restore(); /* Keep any interrupt error status */ errflag = err | (errflag & ERRFLAG_INT); if (ctok == LEXERR) { untokenize(s); return 1; } #ifdef DEBUG /* * Historical note: we used to check here for olen (the value of lexbuf.len * before zcontext_restore()) == l, but that's not necessarily the case if * we stripped an RCQUOTE. */ if (ctok != STRING || (errflag && !noerrs)) { fprintf(stderr, "Oops. Bug in parse_subst_string: %s\n", errflag ? "errflag" : "ctok != STRING"); fflush(stderr); untokenize(s); return 1; } #endif /* Check for $'...' quoting. This needs special handling. */ for (ptr = s; *ptr; ) { if (*ptr == String && ptr[1] == Snull) { char *t; int len, tlen, diff; t = getkeystring(ptr + 2, &len, GETKEYS_DOLLARS_QUOTE, NULL); len += 2; tlen = strlen(t); diff = len - tlen; /* * Yuk. * parse_subst_string() currently handles strings in-place. * That's not so easy to fix without knowing whether * additional memory should come off the heap or * otherwise. So we cheat by copying the unquoted string * into place, unless it's too long. That's not the * normal case, but I'm worried there are pathological * cases with converting metafied multibyte strings. * If someone can prove there aren't I will be very happy. */ if (diff < 0) { DPUTS(1, "$'...' subst too long: fix get_parse_string()"); return 1; } memcpy(ptr, t, tlen); ptr += tlen; if (diff > 0) { char *dptr = ptr; char *sptr = ptr + diff; while ((*dptr++ = *sptr++)) ; } } else ptr++; } return 0; }