summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-05-06 21:33:10 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-05-06 21:33:10 +0000
commit0ef4ecefc73f2813ae60bb787dee5c2cbffc0234 (patch)
treee23589b885bf4ce764133d440b0ac0c3d4fdcbaf
parent85810b7b8eafa0412953c9f890135ffcd40d12c5 (diff)
downloadzsh-0ef4ecefc73f2813ae60bb787dee5c2cbffc0234.tar.gz
zsh-0ef4ecefc73f2813ae60bb787dee5c2cbffc0234.tar.xz
zsh-0ef4ecefc73f2813ae60bb787dee5c2cbffc0234.zip
24957: better sanity checking of colour ranges
always use termcap for numeric ranges where available
-rw-r--r--ChangeLog4
-rw-r--r--Doc/Zsh/zle.yo14
-rw-r--r--Src/Zle/zle_refresh.c35
3 files changed, 41 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 323466fb4..676aa1f56 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2008-05-06  Peter Stephenson  <p.w.stephenson@ntlworld.com>
 
+	* 24957: Doc/Zsh/zle.yo, Src/Zle/zle_refresh.c: better sanity
+	checking of colour ranges, always use termcap for numeric
+	colours where available.
+
 	* 24911 (tweaked): Doc/Zsh/zle.yo: missed this bit, somehow.
 
 2008-05-06  Peter Stephenson  <pws@csr.com>
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 95d1d7ae9..b7b4676a7 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -2180,18 +2180,16 @@ or the name of one of the eight most widely-supported colours.
 
 Not all terminals support this and, of those that do, not all provide
 facilities to test the support, hence the user should decide based on the
-terminal type.  Most terminals with colour support accept the numbers 0 to
-7, and may generate additional colours if the tt(bold) attributes is also
-present.  Most terminals also have a standard range of colours for those
-numbers (though the interpretation of the colour can vary); these colours
-can be set by one of the names tt(black), tt(red), tt(green), tt(yellow),
-tt(blue), tt(magenta), tt(cyan) and tt(white).  Abbreviations are
-allowed; tt(b) or tt(bl) selects black.
+terminal type.  Most terminals support the colours tt(black), tt(red),
+tt(green), tt(yellow), tt(blue), tt(magenta), tt(cyan) and tt(white),
+which can be set by name.  Abbreviations are allowed; tt(b) or tt(bl)
+selects black.  Some terminals may generate additional colours if the
+tt(bold) attribute is also present.
 
 On recent terminals and on systems with an up-to-date terminal database the
 number of colours supported may be tested by with the command `tt(echotc
 Co)'; if this succeeds, it indicates a limit on the number of colours which
-will be enforced by the line editor.  The number of colours is in case
+will be enforced by the line editor.  The number of colours is in any case
 limited to 256 (i.e. the range 0 to 255).
 
 Colour is also known as color.
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 6275d2cf3..6127c1248 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -460,10 +460,10 @@ match_highlight(const char *teststr, int *on_var)
 	found = 0;
 	if (strpfx("fg=", teststr) || strpfx("bg=", teststr)) {
 	    int is_fg = (teststr[0] == 'f');
-	    int colour, shft, on;
+	    int colour, shft, on, named, tc;
 
 	    teststr += 3;
-	    if (ialpha(*teststr))
+	    if ((named = ialpha(*teststr)))
 		colour = match_colour(&teststr);
 	    else
 		colour = (int)zstrtol(teststr, (char **)&teststr, 10);
@@ -478,9 +478,33 @@ match_highlight(const char *teststr, int *on_var)
 	    if (is_fg) {
 		shft = TXT_ATTR_FG_COL_SHIFT;
 		on = TXTFGCOLOUR;
+		tc = TCFGCOLOUR;
 	    } else {
 		shft = TXT_ATTR_BG_COL_SHIFT;
 		on = TXTBGCOLOUR;
+		tc = TCBGCOLOUR;
+	    }
+	    /*
+	     * Try termcap for numbered characters if posible.
+	     * Don't for named characters, since our best bet
+	     * of getting the names right is with ANSI sequences.
+	     */
+	    if (!named && tccan(tc)) {
+		if (tccolours >= 0 && colour >= tccolours) {
+		    /*
+		     * Out of range of termcap colours.
+		     * Can we assume ANSI colours work?
+		     */
+		    if (colour > 7)
+			continue; /* No. */
+		} else {
+		    /*
+		     * We can handle termcap colours and the number
+		     * is in range, so use termcap.
+		     */
+		    *on_var |= is_fg ? TXT_ATTR_FG_TERMCAP :
+			TXT_ATTR_BG_TERMCAP;
+		}
 	    }
 	    *on_var |= on | (colour << shft);
 	} else {
@@ -1137,8 +1161,11 @@ setcolourattribute(int colour, int fg_bg, int tc, int def,
     /*
      * If we're not restoring the default, and either have a
      * colour value that is too large for ANSI, or have been told
-     * to use the termcap sequence (which at the time of writing
-     * we never are), try to use the termcap sequence.
+     * to use the termcap sequence, try to use the termcap sequence.
+     *
+     * We have already sanitised the values we allow from the
+     * highlighting variables, so much of this shouldn't be
+     * necessary at this point, but we might as well be safe.
      */
     if (!def && (colour > 7 || use_termcap)) {
 	/*