Re: [PATCH v3 7/8] update-ref: support multiple simultaneous updates
- From
Brad King <brad.king@kitware.com>
- Date
- Sep 2, 2013, 18:37 UTC
- Message-ID
- <5224DAFA.9000807@kitware.com>
- In-Reply-To
- <93efe58835dc2e569fe1e398a4cba5ec4d4b3771.1378142796.git.brad.king@kitware.com>
On 09/02/2013 01:48 PM, Brad King wrote:
Show 10 quoted lines
> + /* Parse the argument: */
> + strbuf_reset(arg);
> + if (*next == '"') {
> + if (unquote_c_style(arg, next, &next))
> + die("badly quoted argument: %s", next);
> + return next;
> + }
> + while (*next && !isspace(*next))
> + strbuf_addch(arg, *next++);
> + return next;This quoting proposal was written in response to $gmane/233479:
On 08/30/2013 06:51 PM, Junio C Hamano wrote:
> When we need to deal with arbitrary strings (like pathnames), other > parts of the system usually give the user two interfaces, --stdin > with and without -z, and the strings are C-quoted when run without > the -z option, and terminated with NUL when run with the -z option.
1. Do we want to allow arbitrary non-space characters in unquoted arguments (while loop above) or reserve some syntax for future use?
2. Thinking about how the -z variation might work, I ran:
$ git grep '\[0\] == '"'"'"' -- '*.c' builtin/check-attr.c: if (line_termination && buf.buf[0] == '"') { builtin/check-ignore.c: if (line_termination && buf.buf[0] == '"') { builtin/checkout-index.c: if (line_termination && buf.buf[0] == '"') { builtin/hash-object.c: if (buf.buf[0] == '"') { builtin/mktree.c: if (line_termination && path[0] == '"') { builtin/update-index.c: if (line_termination && path_name[0] == '"') { builtin/update-index.c: if (line_termination && buf.buf[0] == '"') {
All of these support quoting only in the non-z mode (the hash-object.c line follows a getline using hard-coded '\n'). However, they are all in cases looking for one value on a line or at the end of a line so their -z option allows NUL-terminated lines containing LF.
What distinguishes the "update-ref --stdin" case is that we want to represent multiple arguments on one line, each allowing arbitrary characters or an empty string. From a brief search a couple places I found that do something related are:
* apply: Read multiple paths from a diff header, using unquote_c_style for quoted paths and separated by spaces. There is no -z input mode.
* config: Output keyword=value\n becomes keyword\nvalue\0 in -z mode. This works because the first piece (keyword) cannot have a LF and there is at most one value so all LFs belong to it.
* quote.c: sq_dequote_to_argv handles single quotes like a shell would but allows only one space between arguments. No -z mode. This is similar to my v2 proposal.
If we use unquote_c_style and spaces to divide LF-terminated lines, how shall we divide arguments on NUL-terminated lines?
Thanks, -Brad