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--


Reply via email to