Skip to content

Commit 5558e55

Browse files
spearceJunio C Hamano
authored andcommitted
Teach for-each-ref about a little language called Tcl.
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. Thanks to Sergey Vlasov for pointing out the horrible flaws in the first and second version of this patch, and steering me in the right direction for Tcl value quoting. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent cace16f commit 5558e55

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

Documentation/git-for-each-ref.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ git-for-each-ref - Output information on each ref
77

88
SYNOPSIS
99
--------
10-
'git-for-each-ref' [--count=<count>]\* [--shell|--perl|--python] [--sort=<key>]\* [--format=<format>] [<pattern>]
10+
'git-for-each-ref' [--count=<count>]\* [--shell|--perl|--python|--tcl] [--sort=<key>]\* [--format=<format>] [<pattern>]
1111

1212
DESCRIPTION
1313
-----------
@@ -49,7 +49,7 @@ OPTIONS
4949
using fnmatch(3). Refs that do not match the pattern
5050
are not shown.
5151

52-
--shell, --perl, --python::
52+
--shell, --perl, --python, --tcl::
5353
If given, strings that substitute `%(fieldname)`
5454
placeholders are quoted as string literals suitable for
5555
the specified host language. This is meant to produce

builtin-for-each-ref.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#define QUOTE_SHELL 1
1313
#define QUOTE_PERL 2
1414
#define QUOTE_PYTHON 3
15+
#define QUOTE_TCL 4
1516

1617
typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;
1718

@@ -723,6 +724,9 @@ static void print_value(struct refinfo *ref, int atom, int quote_style)
723724
case QUOTE_PYTHON:
724725
python_quote_print(stdout, v->s);
725726
break;
727+
case QUOTE_TCL:
728+
tcl_quote_print(stdout, v->s);
729+
break;
726730
}
727731
}
728732

@@ -834,6 +838,12 @@ int cmd_for_each_ref(int ac, const char **av, char *prefix)
834838
quote_style = QUOTE_PYTHON;
835839
continue;
836840
}
841+
if (!strcmp(arg, "--tcl") ) {
842+
if (0 <= quote_style)
843+
die("more than one quoting style?");
844+
quote_style = QUOTE_TCL;
845+
continue;
846+
}
837847
if (!strncmp(arg, "--count=", 8)) {
838848
if (maxcount)
839849
die("more than one --count?");

quote.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,37 @@ void python_quote_print(FILE *stream, const char *src)
387387
}
388388
fputc(sq, stream);
389389
}
390+
391+
void tcl_quote_print(FILE *stream, const char *src)
392+
{
393+
char c;
394+
395+
fputc('"', stream);
396+
while ((c = *src++)) {
397+
switch (c) {
398+
case '[': case ']':
399+
case '{': case '}':
400+
case '$': case '\\': case '"':
401+
fputc('\\', stream);
402+
default:
403+
fputc(c, stream);
404+
break;
405+
case '\f':
406+
fputs("\\f", stream);
407+
break;
408+
case '\r':
409+
fputs("\\r", stream);
410+
break;
411+
case '\n':
412+
fputs("\\n", stream);
413+
break;
414+
case '\t':
415+
fputs("\\t", stream);
416+
break;
417+
case '\v':
418+
fputs("\\v", stream);
419+
break;
420+
}
421+
}
422+
fputc('"', stream);
423+
}

quote.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ extern void write_name_quoted(const char *prefix, int prefix_len,
5555
/* quoting as a string literal for other languages */
5656
extern void perl_quote_print(FILE *stream, const char *src);
5757
extern void python_quote_print(FILE *stream, const char *src);
58+
extern void tcl_quote_print(FILE *stream, const char *src);
5859

5960
#endif

0 commit comments

Comments
 (0)