{"thread":{"id":"6568","subject":"[PATCH 1/1] Teach for-each-ref about a little language called Tcl.","startedAt":"2007-01-28T07:39:13Z","lastAt":"2007-01-29T09:51:22Z","messageCount":4,"participants":["Shawn O. Pearce","Sergey Vlasov","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":1},"messages":[{"id":"32901","messageId":"20070128073913.GA9915@spearce.org","threadId":"6568","inReplyTo":null,"subject":"[PATCH 1/1] Teach for-each-ref about a little language called Tcl.","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-01-28T07:39:13Z","receivedAt":"2007-01-28T07:39:13Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Love it or hate it, some people actually still program in Tcl.  Some\nof those programs are meant for interfacing with Git.  Programs such as\ngitk and git-gui.  It may be useful to have Tcl-safe output available\nfrom for-each-ref, just like shell, Perl and Python already enjoy.\n\nThanks to Sergey Vlasov for pointing out the horrible flaws in the\nfirst version of this patch, and steering me in the right direction\nfor Tcl value quoting.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n\n This replaces my prior patch.  As Sergey pointed out, it was\n horribly broken.\n\n Documentation/git-for-each-ref.txt |    4 ++--\n builtin-for-each-ref.c             |   10 ++++++++++\n quote.c                            |   36 ++++++++++++++++++++++++++++++++++++\n quote.h                            |    1 +\n 4 files changed, 49 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\nindex 06e7ab1..da52eba 100644\n--- a/Documentation/git-for-each-ref.txt\n+++ b/Documentation/git-for-each-ref.txt\n@@ -7,7 +7,7 @@ git-for-each-ref - Output information on each ref\n \n SYNOPSIS\n --------\n-'git-for-each-ref' [--count=<count>]\\* [--shell|--perl|--python] [--sort=<key>]\\* [--format=<format>] [<pattern>]\n+'git-for-each-ref' [--count=<count>]\\* [--shell|--perl|--python|--tcl] [--sort=<key>]\\* [--format=<format>] [<pattern>]\n \n DESCRIPTION\n -----------\n@@ -49,7 +49,7 @@ OPTIONS\n \tusing fnmatch(3).  Refs that do not match the pattern\n \tare not shown.\n \n---shell, --perl, --python::\n+--shell, --perl, --python, --tcl::\n \tIf given, strings that substitute `%(fieldname)`\n \tplaceholders are quoted as string literals suitable for\n \tthe specified host language.  This is meant to produce\ndiff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c\nindex af72a12..9d5f266 100644\n--- a/builtin-for-each-ref.c\n+++ b/builtin-for-each-ref.c\n@@ -12,6 +12,7 @@\n #define QUOTE_SHELL 1\n #define QUOTE_PERL 2\n #define QUOTE_PYTHON 3\n+#define QUOTE_TCL 4\n \n typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;\n \n@@ -723,6 +724,9 @@ static void print_value(struct refinfo *ref, int atom, int quote_style)\n \tcase QUOTE_PYTHON:\n \t\tpython_quote_print(stdout, v->s);\n \t\tbreak;\n+\tcase QUOTE_TCL:\n+\t\ttcl_quote_print(stdout, v->s);\n+\t\tbreak;\n \t}\n }\n \n@@ -834,6 +838,12 @@ int cmd_for_each_ref(int ac, const char **av, char *prefix)\n \t\t\tquote_style = QUOTE_PYTHON;\n \t\t\tcontinue;\n \t\t}\n+\t\tif (!strcmp(arg, \"--tcl\") ) {\n+\t\t\tif (0 <= quote_style)\n+\t\t\t\tdie(\"more than one quoting style?\");\n+\t\t\tquote_style = QUOTE_TCL;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!strncmp(arg, \"--count=\", 8)) {\n \t\t\tif (maxcount)\n \t\t\t\tdie(\"more than one --count?\");\ndiff --git a/quote.c b/quote.c\nindex a418a0f..01db5e2 100644\n--- a/quote.c\n+++ b/quote.c\n@@ -387,3 +387,39 @@ void python_quote_print(FILE *stream, const char *src)\n \t}\n \tfputc(sq, stream);\n }\n+\n+void tcl_quote_print(FILE *stream, const char *src)\n+{\n+\tchar c;\n+\n+\tfputc('\"', stream);\n+\twhile ((c = *src++)) {\n+\t\tswitch (c) {\n+\t\tcase '[':\n+\t\tcase ']':\n+\t\tcase '$':\n+\t\tcase '\\\\':\n+\t\tcase '\"':\n+\t\t\tfputc('\\\\', stream);\n+\t\tdefault:\n+\t\t\tfputc(c, stream);\n+\t\t\tbreak;\n+\t\tcase '\\f':\n+\t\t\tfputs(\"\\\\f\", stream);\n+\t\t\tbreak;\n+\t\tcase '\\r':\n+\t\t\tfputs(\"\\\\r\", stream);\n+\t\t\tbreak;\n+\t\tcase '\\n':\n+\t\t\tfputs(\"\\\\n\", stream);\n+\t\t\tbreak;\n+\t\tcase '\\t':\n+\t\t\tfputs(\"\\\\t\", stream);\n+\t\t\tbreak;\n+\t\tcase '\\v':\n+\t\t\tfputs(\"\\\\v\", stream);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tfputc('\"', stream);\n+}\ndiff --git a/quote.h b/quote.h\nindex b55e699..bdc3610 100644\n--- a/quote.h\n+++ b/quote.h\n@@ -55,5 +55,6 @@ extern void write_name_quoted(const char *prefix, int prefix_len,\n /* quoting as a string literal for other languages */\n extern void perl_quote_print(FILE *stream, const char *src);\n extern void python_quote_print(FILE *stream, const char *src);\n+extern void tcl_quote_print(FILE *stream, const char *src);\n \n #endif\n-- \n1.5.0.rc2.gf127\n"},{"id":"32909","messageId":"20070128094909.GA3740@procyon.home","threadId":"6568","inReplyTo":"20070128073913.GA9915@spearce.org","subject":"Re: [PATCH 1/1] Teach for-each-ref about a little language called Tcl.","fromName":"Sergey Vlasov","fromEmail":"vsu@altlinux.ru","sentAt":"2007-01-28T09:49:09Z","receivedAt":"2007-01-28T09:49:09Z","isPatch":true,"sender":{"key":"vsu@altlinux.ru","avatar":"https://avatars.githubusercontent.com/u/616082?v=4"},"body":"On Sun, Jan 28, 2007 at 02:39:13AM -0500, Shawn O. Pearce wrote:\n> Love it or hate it, some people actually still program in Tcl.  Some\n> of those programs are meant for interfacing with Git.  Programs such as\n> gitk and git-gui.  It may be useful to have Tcl-safe output available\n> from for-each-ref, just like shell, Perl and Python already enjoy.\n> \n> Thanks to Sergey Vlasov for pointing out the horrible flaws in the\n> first version of this patch, and steering me in the right direction\n> for Tcl value quoting.\n[...]\n> +void tcl_quote_print(FILE *stream, const char *src)\n> +{\n> +\tchar c;\n> +\n> +\tfputc('\"', stream);\n> +\twhile ((c = *src++)) {\n> +\t\tswitch (c) {\n> +\t\tcase '[':\n> +\t\tcase ']':\n> +\t\tcase '$':\n> +\t\tcase '\\\\':\n> +\t\tcase '\"':\n> +\t\t\tfputc('\\\\', stream);\n> +\t\tdefault:\n> +\t\t\tfputc(c, stream);\n> +\t\t\tbreak;\n> +\t\tcase '\\f':\n> +\t\t\tfputs(\"\\\\f\", stream);\n> +\t\t\tbreak;\n> +\t\tcase '\\r':\n> +\t\t\tfputs(\"\\\\r\", stream);\n> +\t\t\tbreak;\n> +\t\tcase '\\n':\n> +\t\t\tfputs(\"\\\\n\", stream);\n> +\t\t\tbreak;\n> +\t\tcase '\\t':\n> +\t\t\tfputs(\"\\\\t\", stream);\n> +\t\t\tbreak;\n> +\t\tcase '\\v':\n> +\t\t\tfputs(\"\\\\v\", stream);\n> +\t\t\tbreak;\n> +\t\t}\n> +\t}\n> +\tfputc('\"', stream);\n> +}\n\nThis is better; however, wrapping this format inside { ... } (which\nyou may want to do in the template for some uses) won't work if the\nstring contains unmatched braces.  Quoting '{' and '}' characters with\nbackslashes should fix this.\n\nBTW, escaping newline characters as done here is not strictly required\nfor a double-quoted string, but is very useful, because you may read\nthe output line by line with \"gets\" and get fields from each line with\n\"lindex\"; without this escaping you will need to read the whole output\nbefore trying to parse it as a single huge list.\n"},{"id":"32929","messageId":"7v4pqaeulw.fsf@assigned-by-dhcp.cox.net","threadId":"6568","inReplyTo":"20070128094909.GA3740@procyon.home","subject":"Re: [PATCH 1/1] Teach for-each-ref about a little language called Tcl.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-01-28T20:58:51Z","receivedAt":"2007-01-28T20:58:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sergey Vlasov <vsu@altlinux.ru> writes:\n\n> This is better; however, wrapping this format inside { ... } (which\n> you may want to do in the template for some uses) won't work if the\n> string contains unmatched braces.  Quoting '{' and '}' characters with\n> backslashes should fix this.\n\nThen I'd commit after applying this on top of Shawn's.  Ok?\n\ndiff --git a/quote.c b/quote.c\nindex 01db5e2..fb9e4ca 100644\n--- a/quote.c\n+++ b/quote.c\n@@ -395,11 +395,9 @@ void tcl_quote_print(FILE *stream, const char *src)\n \tfputc('\"', stream);\n \twhile ((c = *src++)) {\n \t\tswitch (c) {\n-\t\tcase '[':\n-\t\tcase ']':\n-\t\tcase '$':\n-\t\tcase '\\\\':\n-\t\tcase '\"':\n+\t\tcase '[': case ']':\n+\t\tcase '{': case '}':\n+\t\tcase '$': case '\\\\': case '\"':\n \t\t\tfputc('\\\\', stream);\n \t\tdefault:\n \t\t\tfputc(c, stream);\n"},{"id":"32952","messageId":"20070129095122.GB3375@master.mivlgu.local","threadId":"6568","inReplyTo":"7v4pqaeulw.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/1] Teach for-each-ref about a little language called Tcl.","fromName":"Sergey Vlasov","fromEmail":"vsu@altlinux.ru","sentAt":"2007-01-29T09:51:22Z","receivedAt":"2007-01-29T09:51:22Z","isPatch":true,"sender":{"key":"vsu@altlinux.ru","avatar":"https://avatars.githubusercontent.com/u/616082?v=4"},"body":"On Sun, Jan 28, 2007 at 12:58:51PM -0800, Junio C Hamano wrote:\n> Then I'd commit after applying this on top of Shawn's.  Ok?\n> \n> diff --git a/quote.c b/quote.c\n> index 01db5e2..fb9e4ca 100644\n> --- a/quote.c\n> +++ b/quote.c\n> @@ -395,11 +395,9 @@ void tcl_quote_print(FILE *stream, const char *src)\n>  \tfputc('\"', stream);\n>  \twhile ((c = *src++)) {\n>  \t\tswitch (c) {\n> -\t\tcase '[':\n> -\t\tcase ']':\n> -\t\tcase '$':\n> -\t\tcase '\\\\':\n> -\t\tcase '\"':\n> +\t\tcase '[': case ']':\n> +\t\tcase '{': case '}':\n> +\t\tcase '$': case '\\\\': case '\"':\n>  \t\t\tfputc('\\\\', stream);\n>  \t\tdefault:\n>  \t\t\tfputc(c, stream);\n\nLooks OK (still didn't have time to actually test this thing).\n"}]}