* [PATCH] Teach for-each-ref about a little language called Tcl.
@ 2007-01-27 7:22 Shawn O. Pearce
2007-01-27 11:30 ` Sergey Vlasov
0 siblings, 1 reply; 2+ messages in thread
From: Shawn O. Pearce @ 2007-01-27 7:22 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
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.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
Documentation/git-for-each-ref.txt | 4 ++--
builtin-for-each-ref.c | 10 ++++++++++
quote.c | 16 ++++++++++++++++
quote.h | 1 +
4 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
index 06e7ab1..da52eba 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -7,7 +7,7 @@ git-for-each-ref - Output information on each ref
SYNOPSIS
--------
-'git-for-each-ref' [--count=<count>]\* [--shell|--perl|--python] [--sort=<key>]\* [--format=<format>] [<pattern>]
+'git-for-each-ref' [--count=<count>]\* [--shell|--perl|--python|--tcl] [--sort=<key>]\* [--format=<format>] [<pattern>]
DESCRIPTION
-----------
@@ -49,7 +49,7 @@ OPTIONS
using fnmatch(3). Refs that do not match the pattern
are not shown.
---shell, --perl, --python::
+--shell, --perl, --python, --tcl::
If given, strings that substitute `%(fieldname)`
placeholders are quoted as string literals suitable for
the specified host language. This is meant to produce
diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
index af72a12..9d5f266 100644
--- a/builtin-for-each-ref.c
+++ b/builtin-for-each-ref.c
@@ -12,6 +12,7 @@
#define QUOTE_SHELL 1
#define QUOTE_PERL 2
#define QUOTE_PYTHON 3
+#define QUOTE_TCL 4
typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;
@@ -723,6 +724,9 @@ static void print_value(struct refinfo *ref, int atom, int quote_style)
case QUOTE_PYTHON:
python_quote_print(stdout, v->s);
break;
+ case QUOTE_TCL:
+ tcl_quote_print(stdout, v->s);
+ break;
}
}
@@ -834,6 +838,12 @@ int cmd_for_each_ref(int ac, const char **av, char *prefix)
quote_style = QUOTE_PYTHON;
continue;
}
+ if (!strcmp(arg, "--tcl") ) {
+ if (0 <= quote_style)
+ die("more than one quoting style?");
+ quote_style = QUOTE_TCL;
+ continue;
+ }
if (!strncmp(arg, "--count=", 8)) {
if (maxcount)
die("more than one --count?");
diff --git a/quote.c b/quote.c
index a418a0f..ab0e971 100644
--- a/quote.c
+++ b/quote.c
@@ -387,3 +387,19 @@ void python_quote_print(FILE *stream, const char *src)
}
fputc(sq, stream);
}
+
+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);
+}
diff --git a/quote.h b/quote.h
index b55e699..bdc3610 100644
--- a/quote.h
+++ b/quote.h
@@ -55,5 +55,6 @@ extern void write_name_quoted(const char *prefix, int prefix_len,
/* quoting as a string literal for other languages */
extern void perl_quote_print(FILE *stream, const char *src);
extern void python_quote_print(FILE *stream, const char *src);
+extern void tcl_quote_print(FILE *stream, const char *src);
#endif
--
1.5.0.rc2.g8a816
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] Teach for-each-ref about a little language called Tcl.
2007-01-27 7:22 [PATCH] Teach for-each-ref about a little language called Tcl Shawn O. Pearce
@ 2007-01-27 11:30 ` Sergey Vlasov
0 siblings, 0 replies; 2+ messages in thread
From: Sergey Vlasov @ 2007-01-27 11:30 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git
[-- Attachment #1: Type: text/plain, Size: 2872 bytes --]
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.
[...]
> +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;
}
}
}
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-01-27 11:32 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-27 7:22 [PATCH] Teach for-each-ref about a little language called Tcl Shawn O. Pearce
2007-01-27 11:30 ` Sergey Vlasov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).