git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] Teach for-each-ref about a little language called Tcl.

From
Sergey Vlasov <vsu@altlinux.ru>
Date
Jan 27, 2007, 11:30 UTC
Message-ID
<20070127143056.d19e80da.vsu@altlinux.ru>
In-Reply-To
<20070127072258.GA10512@spearce.org>
On Sat, 27 Jan 2007 02:22:58 -0500 Shawn O. Pearce wrote:
> Love it or hate it, some people actually still program in Tcl.  Some
> of those programs are meant for interfacing with Git.  Programs such as
> gitk and git-gui.  It may be useful to have Tcl-safe output available
> from for-each-ref, just like shell, Perl and Python already enjoy.
[...]
Show 15 quoted lines
> +void tcl_quote_print(FILE *stream, const char *src)
> +{
> +	const char lb = '{';
> +	const char rb = '}';
> +	const char bq = '\\';
> +	char c;
> +
> +	fputc(lb, stream);
> +	while ((c = *src++)) {
> +		if (c == lb || c == rb || c == bq)
> +			fputc(bq, stream);
> +		fputc(c, stream);
> +	}
> +	fputc(rb, stream);
> +}

No, this is broken - backslashes cannot be used to quote special characters in braces.

      If  the  first character of a word is an open brace (``{'') then
      the word is terminated by  the  matching  close  brace  (``}'').
      Braces  nest  within  the  word:  for each additional open brace
      there must be an additional close brace  (however,  if  an  open
      brace  or close brace within the word is quoted with a backslash
      then it is not counted in locating the  matching  close  brace).
      No  substitutions  are  performed  on the characters between the
      braces  except  for  backslash-newline  substitutions  described
      below,  nor  do  semi-colons, newlines, close brackets, or white
      space receive any special interpretation.  The word will consist
      of  exactly the characters between the outer braces, not includ-
      ing the braces themselves.

The problem is that using '\{' will protect from nonmatching braces, but the backslash will stay in the resulting string - it will not be removed. Similarly for '\}' and '\\'.

Tcl itself checks whether using braces is safe (it could be safe if the text does not have nonmatching braces and does not have an odd number of backslash characters at end of line), and uses just backslashes if braces cannot be used. See tclUtil.c, Tcl_ScanCountedElement() and Tcl_ConvertCountedElement(). This code adds a backslash before ']', '[', '$', ';', ' ', '\\', '"', '{', '}', and also converts special characters '\f', '\n', '\r', '\t', '\v' to C-style escape sequences.

Untested code (output will not look very nice, but it is not intended for human consumption anyway):

void tcl_quote_print(FILE *stream, const char *src)
{
	char c;
	while ((c = *src++)) {
		switch (c) {
		case ']':
		case '[':
		case '$':
		case ';':
		case ' ':
		case '\\':
		case '"':
		case '{':
		case '}':
			fputc('\\', stream);
		default:
			fputc(c, stream);
			break;
		case '\f':
			fputs("\\f", stream);
			break;
		case '\n':
			fputs("\\n", stream);
			break;
		case '\r':
			fputs("\\r", stream);
			break;
		case '\t':
			fputs("\\t", stream);
			break;
		case '\v':
			fputs("\\v", stream);
			break;
		}
	}
}
Previous: Shawn O. Pearce
Message 2 of 2 in “Teach for-each-ref about a little language called Tcl.”
  1. Teach for-each-ref about a little language called Tcl.Shawn O. Pearce, Jan 27, 2007
  2. Sergey VlasovJan 27, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.