From 02747bbbd37d81a2a2fff938e1cc94fb73980848 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 4 Apr 2022 15:34:40 +0100 Subject: 49989: Single byte versions of nice quoting. Align interfaces for "nice" printing of characters with those for multibyte to make more available in single-byte compilation. --- Src/Zle/compresult.c | 6 +- Src/utils.c | 171 +++++++++++++++++++++++++++++++++++++++++---------- Src/zsh.h | 5 +- 3 files changed, 142 insertions(+), 40 deletions(-) (limited to 'Src') diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c index 0fed297b5..57789c0f3 100644 --- a/Src/Zle/compresult.c +++ b/Src/Zle/compresult.c @@ -2248,15 +2248,13 @@ iprintm(Cmgroup g, Cmatch *mp, UNUSED(int mc), UNUSED(int ml), int lastc, int wi #ifdef MULTIBYTE_SUPPORT len = mb_niceformat(m->disp, shout, NULL, 0); #else - nicezputs(m->disp, shout); - len = niceztrlen(m->disp); + len = sb_niceformat(m->disp, shout, NULL, 0); #endif } else { #ifdef MULTIBYTE_SUPPORT len = mb_niceformat(m->str, shout, NULL, 0); #else - nicezputs(m->str, shout); - len = niceztrlen(m->str); + len = sb_niceformat(m->str, shout, NULL, 0); #endif if ((g->flags & CGF_FILES) && m->modec) { diff --git a/Src/utils.c b/Src/utils.c index ffa59eff8..62bd3e602 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -5196,26 +5196,11 @@ zputs(char const *s, FILE *stream) mod_export char * nicedup(char const *s, int heap) { - int c, len = strlen(s) * 5 + 1; - VARARR(char, buf, len); - char *p = buf, *n; + char *retstr; - while ((c = *s++)) { - if (itok(c)) { - if (c <= Comma) - c = ztokens[c - Pound]; - else - continue; - } - if (c == Meta) - c = *s++ ^ 32; - /* The result here is metafied */ - n = nicechar(c); - while(*n) - *p++ = *n++; - } - *p = '\0'; - return heap ? dupstring(buf) : ztrdup(buf); + (void)sb_niceformat(s, NULL, &retstr, heap ? NICEFLAG_HEAP : 0); + + return retstr; } #endif @@ -5234,20 +5219,7 @@ nicedupstring(char const *s) mod_export int nicezputs(char const *s, FILE *stream) { - int c; - - while ((c = *s++)) { - if (itok(c)) { - if (c <= Comma) - c = ztokens[c - Pound]; - else - continue; - } - if (c == Meta) - c = *s++ ^ 32; - if(zputs(nicechar(c), stream) < 0) - return EOF; - } + sb_niceformat(s, stream, NULL, 0); return 0; } @@ -5736,7 +5708,7 @@ mb_charlenconv(const char *s, int slen, wint_t *wcp) } /**/ -#else +#else /* MULTIBYTE_SUPPORT */ /* Simple replacement for mb_metacharlenconv */ @@ -5776,6 +5748,121 @@ charlenconv(const char *x, int len, int *c) return 1; } +/* + * Non-multibyte version of mb_niceformat() above. Same basic interface. + */ + +/**/ +mod_export size_t +sb_niceformat(const char *s, FILE *stream, char **outstrp, int flags) +{ + size_t l = 0, newl; + int umlen, outalloc, outleft; + char *ums, *ptr, *eptr, *fmt, *outstr, *outptr; + + if (outstrp) { + outleft = outalloc = 2 * strlen(s); + outptr = outstr = zalloc(outalloc); + } else { + outleft = outalloc = 0; + outptr = outstr = NULL; + } + + ums = ztrdup(s); + /* + * is this necessary at this point? niceztrlen does this + * but it's used in lots of places. however, one day this may + * be, too. + */ + untokenize(ums); + ptr = unmetafy(ums, ¨en); + eptr = ptr + umlen; + + while (ptr < eptr) { + int c = STOUC(*ptr); + if (c == '\'' && (flags & NICEFLAG_QUOTE)) { + fmt = "\\'"; + newl = 2; + } + else if (c == '\\' && (flags & NICEFLAG_QUOTE)) { + fmt = "\\\\"; + newl = 2; + } + else { + fmt = nicechar_sel(c, flags & NICEFLAG_QUOTE); + newl = 1; + } + + ++ptr; + l += newl; + + if (stream) + zputs(fmt, stream); + if (outstr) { + /* Append to output string */ + int outlen = strlen(fmt); + if (outlen >= outleft) { + /* Reallocate to twice the length */ + int outoffset = outptr - outstr; + + outleft += outalloc; + outalloc *= 2; + outstr = zrealloc(outstr, outalloc); + outptr = outstr + outoffset; + } + memcpy(outptr, fmt, outlen); + /* Update start position */ + outptr += outlen; + /* Update available bytes */ + outleft -= outlen; + } + } + + free(ums); + if (outstrp) { + *outptr = '\0'; + /* Use more efficient storage for returned string */ + if (flags & NICEFLAG_NODUP) + *outstrp = outstr; + else { + *outstrp = (flags & NICEFLAG_HEAP) ? dupstring(outstr) : + ztrdup(outstr); + free(outstr); + } + } + + return l; +} + +/* + * Return 1 if sb_niceformat() would reformat this string, else 0. + */ + +/**/ +mod_export int +is_sb_niceformat(const char *s) +{ + int umlen, ret = 0; + char *ums, *ptr, *eptr; + + ums = ztrdup(s); + untokenize(ums); + ptr = unmetafy(ums, ¨en); + eptr = ptr + umlen; + + while (ptr < eptr) { + if (is_nicechar(*ptr)) { + ret = 1; + break; + } + ++ptr; + } + + free(ums); + + return ret; +} + /**/ #endif /* MULTIBYTE_SUPPORT */ @@ -6309,6 +6396,22 @@ quotedzputs(char const *s, FILE *stream) return outstr; } } +#else + if (is_sb_niceformat(s)){ + if (stream) { + fputs("$'", stream); + sb_niceformat(s, stream, NULL, NICEFLAG_QUOTE); + fputc('\'', stream); + return NULL; + } else { + char *substr; + sb_niceformat(s, NULL, &substr, NICEFLAG_QUOTE|NICEFLAG_NODUP); + outstr = (char *)zhalloc(4 + strlen(substr)); + sprintf(outstr, "$'%s'", substr); + free(substr); + return outstr; + } + } #endif /* MULTIBYTE_SUPPORT */ if (!hasspecial(s)) { diff --git a/Src/zsh.h b/Src/zsh.h index 641d9c95c..40f9ea537 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -3277,14 +3277,15 @@ enum zexit_t { #define AFTERTRAPHOOK (zshhooks + 2) #define GETCOLORATTR (zshhooks + 3) -#ifdef MULTIBYTE_SUPPORT -/* Final argument to mb_niceformat() */ +/* Final argument to [ms]b_niceformat() */ enum { NICEFLAG_HEAP = 1, /* Heap allocation where needed */ NICEFLAG_QUOTE = 2, /* Result will appear in $'...' */ NICEFLAG_NODUP = 4, /* Leave allocated */ }; +#ifdef MULTIBYTE_SUPPORT + /* Metafied input */ #define nicezputs(str, outs) (void)mb_niceformat((str), (outs), NULL, 0) #define MB_METACHARINIT() mb_charinit() -- cgit 1.4.1