X-Git-Url: http://ncurses.scripts.mit.edu/?a=blobdiff_plain;f=ncurses%2Ftinfo%2Fcomp_expand.c;h=e971384f52f29099068d6ca99c46129892dd76b0;hb=6fd6dd99d32385a01ca639d1d56b90b13e9c1d33;hp=742fa7c248b256ec8f61596ddd94a7a12be9c5ab;hpb=1b84471a41759a95861aebcf4ef3db0a457b183a;p=ncurses.git diff --git a/ncurses/tinfo/comp_expand.c b/ncurses/tinfo/comp_expand.c index 742fa7c2..e971384f 100644 --- a/ncurses/tinfo/comp_expand.c +++ b/ncurses/tinfo/comp_expand.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2012,2016 Free Software Foundation, Inc. * + * Copyright 2020-2021,2023 Thomas E. Dickey * + * Copyright 1998-2016,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -27,7 +28,7 @@ ****************************************************************************/ /**************************************************************************** - * Author: Thomas E. Dickey 1998 * + * Author: Thomas E. Dickey 1998 * ****************************************************************************/ #include @@ -35,7 +36,13 @@ #include #include -MODULE_ID("$Id: comp_expand.c,v 1.26 2016/09/24 21:15:51 tom Exp $") +MODULE_ID("$Id: comp_expand.c,v 1.35 2023/04/28 20:59:06 tom Exp $") + +#if 0 +#define DEBUG_THIS(p) DEBUG(9, p) +#else +#define DEBUG_THIS(p) /* nothing */ +#endif static int trailing_spaces(const char *src) @@ -46,7 +53,6 @@ trailing_spaces(const char *src) } /* this deals with differences over whether 0x7f and 0x80..0x9f are controls */ -#define REALCTL(s) (UChar(*(s)) < 127 && iscntrl(UChar(*(s)))) #define REALPRINT(s) (UChar(*(s)) < 127 && isprint(UChar(*(s)))) #define P_LIMIT(p) (length - (size_t)(p)) @@ -59,9 +65,13 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers) int bufp; const char *str = VALID_STRING(srcp) ? srcp : "\0\0"; - bool islong = (strlen(str) > 3); size_t need = (2 + strlen(str)) * 4; int ch; + int octals = 0; + struct { + int ch; + int offset; + } fixups[MAX_TC_FIXUPS]; if (srcp == 0) { #if NO_LEAKS @@ -77,6 +87,10 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers) return 0; } + DEBUG_THIS(("_nc_tic_expand %s:%s:%s", + tic_format ? "ti" : "tc", + numbers ? "#" : "", + _nc_visbuf(srcp))); bufp = 0; while ((ch = UChar(*str)) != 0) { if (ch == '%' && REALPRINT(str + 1)) { @@ -115,7 +129,6 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers) if (dst != 0 && *dst == R_BRACE && value < 127 - && value != '\\' /* FIXME */ && isprint((int) value)) { ch = (int) value; buffer[bufp++] = S_QUOTE; @@ -151,43 +164,37 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers) trailing_spaces(str))) { buffer[bufp++] = '\\'; buffer[bufp++] = 's'; - } else if ((ch == ',' || ch == ':' || ch == '^') && tic_format) { + } else if ((ch == ',' || ch == '^') && tic_format) { buffer[bufp++] = '\\'; buffer[bufp++] = (char) ch; } else if (REALPRINT(str) && (ch != ',' - && ch != ':' + && !(ch == ':' && !tic_format) && !(ch == '!' && !tic_format) && ch != '^')) buffer[bufp++] = (char) ch; -#if 0 /* FIXME: this would be more readable (in fact the whole 'islong' logic should be removed) */ - else if (ch == '\b') { - buffer[bufp++] = '\\'; - buffer[bufp++] = 'b'; - } else if (ch == '\f') { - buffer[bufp++] = '\\'; - buffer[bufp++] = 'f'; - } else if (ch == '\t' && islong) { - buffer[bufp++] = '\\'; - buffer[bufp++] = 't'; - } -#endif - else if (ch == '\r' && (islong || (strlen(srcp) > 2 && str[1] == '\0'))) { + else if (ch == '\r') { buffer[bufp++] = '\\'; buffer[bufp++] = 'r'; - } else if (ch == '\n' && islong) { + } else if (ch == '\n') { buffer[bufp++] = '\\'; buffer[bufp++] = 'n'; } #define UnCtl(c) ((c) + '@') - else if (REALCTL(str) && ch != '\\' - && (!islong || isdigit(UChar(str[1])))) { + else if (UChar(ch) < 32 + && isdigit(UChar(str[1]))) { _nc_SPRINTF(&buffer[bufp], _nc_SLIMIT(P_LIMIT(bufp)) "^%c", UnCtl(ch)); bufp += 2; } else { _nc_SPRINTF(&buffer[bufp], _nc_SLIMIT(P_LIMIT(bufp)) "\\%03o", ch); + if ((octals < MAX_TC_FIXUPS) && + ((tic_format && (ch == 127)) || ch < 32)) { + fixups[octals].ch = UChar(ch); + fixups[octals].offset = bufp; + ++octals; + } bufp += 4; } @@ -195,5 +202,26 @@ _nc_tic_expand(const char *srcp, bool tic_format, int numbers) } buffer[bufp] = '\0'; + + /* + * If most of a short string is ASCII control characters, reformat the + * string to show those in up-arrow format. For longer strings, it is + * more likely that the characters are just binary coding. + * + * If we're formatting termcap, just use the shorter format (up-arrows). + */ + if (octals != 0 && (!tic_format || (bufp - (4 * octals)) < MIN_TC_FIXUPS)) { + while (--octals >= 0) { + char *p = buffer + fixups[octals].offset; + *p++ = '^'; + *p++ = (char) ((fixups[octals].ch == 127) + ? '?' + : (fixups[octals].ch + (int) '@')); + while ((p[0] = p[2]) != 0) { + ++p; + } + } + } + DEBUG_THIS(("... %s", _nc_visbuf(buffer))); return (buffer); }