On Tue, Nov 19, 2019 at 04:02:48PM +1300, Thomas Munro wrote: > On Tue, Nov 19, 2019 at 12:09 PM Tom Lane <t...@sss.pgh.pa.us> wrote: > > You should follow the logic in pg_wcswidth: compute PQmblen() first, > > and bail out if it's more than the remaining string length, otherwise > > it's ok to apply PQdsplen(). > > Got it. I was worried that it wasn't safe to call even PQmblen(), > because I didn't know a fact about all encodings: as described in the > comment of pg_gb18030_mblen(), all implementations read only the first > byte to determine the length, except for GB18030 which reads the > second byte too, and that's OK because there's always a null > terminator. > > > It might be a good idea to explicitly initialize last_prompt1_width to > > zero, for clarity. > > > > Should the user docs explicitly say "of the same width as the most recent > > output of PROMPT1", as you have in the comments? That seems a more > > precise specification, and it will eliminate some questions people will > > otherwise ask. > > > > LGTM otherwise. > > Done, and pushed. I also skipped negative results from PQdsplen like > pg_wcswidth() does (that oversight explained why a non-readline build > showed the correct alignment for PROMPT1 '%[%033[1m%]%M > %n@%/%R%[%033[0m%]%# ' by strange concindence). > > Thanks all for the feedback. I think the new bikeshed colour looks good.
Please find attached some polka dots for the bike shed :) Best, David. -- David Fetter <david(at)fetter(dot)org> http://fetter.org/ Phone: +1 415 235 3778 Remember to vote! Consider donating to Postgres: http://www.postgresql.org/about/donate
>From fdbb6272338ed71f8cecf2a755ef53b037acc251 Mon Sep 17 00:00:00 2001 From: David Fetter <david.fet...@onelogin.com> Date: Tue, 19 Nov 2019 11:39:47 -0800 Subject: [PATCH v1] Make visible_length() available to the rest of psql To: hackers MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------2.23.0" This is a multi-part message in MIME format. --------------2.23.0 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 90f6380170..3245f3ebae 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -2443,3 +2443,50 @@ recognized_connection_string(const char *connstr) { return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL; } + +/* + * Return visible width of the string + */ +int +visible_length(char *string) +{ + int visible_length = 0; + char *p = string; + char *end = p + strlen(p); + bool visible = true; + + while(*string) + { +#if defined(USE_READLINE) && defined(RL_PROMPT_START_IGNORE) + if (*string == RL_PROMPT_START_IGNORE) + { + visible = false; + ++p; + } + else if (*p == RL_PROMPT_END_IGNORE) + { + visible = true; + ++p; + } + else +#endif + { + int chlen, + chwidth; + + chlen = PQmblen(p, pset.encoding); + if (p + chlen > end) + break; + + if (visible) + { + chwidth = PQdsplen(p, pset.encoding); + if (chwidth > 0) + visible_length += chwidth; + } + + p += chlen; + } + } + return visible_length; +} diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index 282a520116..56e28915ce 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -44,4 +44,5 @@ extern void expand_tilde(char **filename); extern bool recognized_connection_string(const char *connstr); +extern int visible_length(char *string); #endif /* COMMON_H */ diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c index 41c6f21ecf..9c0e2c7567 100644 --- a/src/bin/psql/prompt.c +++ b/src/bin/psql/prompt.c @@ -347,46 +347,7 @@ get_prompt(promptStatus_t status, ConditionalStack cstack) /* Compute the visible width of PROMPT1, for PROMPT2's %w */ if (prompt_string == pset.prompt1) - { - char *p = destination; - char *end = p + strlen(p); - bool visible = true; - - last_prompt1_width = 0; - while (*p) - { -#if defined(USE_READLINE) && defined(RL_PROMPT_START_IGNORE) - if (*p == RL_PROMPT_START_IGNORE) - { - visible = false; - ++p; - } - else if (*p == RL_PROMPT_END_IGNORE) - { - visible = true; - ++p; - } - else -#endif - { - int chlen, - chwidth; - - chlen = PQmblen(p, pset.encoding); - if (p + chlen > end) - break; /* Invalid string */ - - if (visible) - { - chwidth = PQdsplen(p, pset.encoding); - if (chwidth > 0) - last_prompt1_width += chwidth; - } - - p += chlen; - } - } - } + last_prompt1_width = visible_length(destination); return destination; } --------------2.23.0--