Briefly explain the zoo of quoting functions. Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx> --- This is just a starting point, I fear. Not even compile-tested. Problems: - not very brief - not a great overview But I was happy to have the chance to read through the available functions. Suggestions and other improvements welcome. Documentation/technical/api-quote.txt | 124 ++++++++++++++++++++++++++++++--- quote.h | 14 ++-- 2 files changed, 121 insertions(+), 17 deletions(-) rewrite Documentation/technical/api-quote.txt (84%) diff --git a/Documentation/technical/api-quote.txt b/Documentation/technical/api-quote.txt dissimilarity index 84% index e8a1bce..18da370 100644 --- a/Documentation/technical/api-quote.txt +++ b/Documentation/technical/api-quote.txt @@ -1,10 +1,114 @@ -quote API -========= - -Talk about <quote.h>, things like - -* sq_quote and unquote -* c_style quote and unquote -* quoting for foreign languages - -(JC) +quote API +========= + +The quoting API can be used to replace unusual characters for +shell safety or for output readability and parseability. +It also can be used to perform the inverse operation and recover +the unusual characters again. + +C-style quoting +--------------- + +`quote_c_style` quotes a string in a manner that might be familiar +to C programmers. This can be used to quote newlines and tabs in +filenames for patches, for example. + +. if sb and fp are both NULL, it returns the number of bytes needed + to hold the quoted version of "name", counting the double quotes + around it but not terminating NUL. If "name" does not need quoting, + it returns 0. + +. otherwise, it emits the quoted version of "name" to a stream, + strbuf, or both. Output will have enclosing double quotes + suppressed if requested with the "no_dq" parameter. + +`quote_two_c_style`:: + Quote two paths (prefix + path) in C-style and concatenate them. + One should use this instead of calling `quote_c_style` twice + to avoid unsightly quotation marks in the middle. + +`unquote_c_style`:: + This unwraps what quote_c_style() produces in place, + but returns -1 and doesn't touch if the input does not start with + a double-quote or otherwise differs from what quote_c_style + would have produced. Though note that this function will + allocate memory in the strbuf, so calling `strbuf_release` + is mandatory regardless of the result `unquote_c_style` returns. ++ +Updates the endp pointer to point at one past the ending double quote +if given. + +`write_name_quoted`:: + `write_name_quoted` is like `quote_c_style` but takes a + different set of arguments. + Instead of asking for quotes or not, you pass a "terminator". + If it's \0 then we assume you don't want to escape, else C + escaping is performed. In any case, the terminator is also + appended to the stream. + +`write_name_quotedpfx`:: + `write_name_quotedpfx` works like `write_name_quoted` but takes + prefix/prefix_len arguments. The first "prefix_len" characters + of "prefix" will be prepended when emiting "name". + +`write_name_quoted_relative`:: + This is a sort of converse to `write_name_quotedpfx`. + The path "name" is made relative to the directory described by + prefix and prefix_len by stripping away path components and + prepending `../` when necessary before quoting. + +Quoting for the shell +--------------------- + +`sq_quote` copies its argument quoted for the shell safety. +Any single quote is replaced with '\'', any exclamation point +is replaced with '\!', and the whole thing is enclosed in a +single-quote pair. + +For example, if you are passing the result to `system()` as an +argument: +-------------- +sprintf(cmd, "foobar %s %s", sq_quote(arg0), sq_quote(arg1)) +-------------- +would be appropriate. If the `system()` is going to call 'ssh' to +run the command on the other side: +-------------- +sprintf(cmd, "git-diff-tree %s %s", sq_quote(arg0), sq_quote(arg1)); +sprintf(rcmd, "ssh %s %s", sq_quote(host), sq_quote(cmd)); +-------------- +Note that the above examples leak memory! Remember to free result from +`sq_quote()` in a real application. + +`sq_quote_print`:: + Writes to a stream instead of a new buffer. + +`sq_quote_buf`:: + Appends to a strbuf instead of allocating a new buffer. + +`sq_quote_argv`:: + Appends a list of command-line-ready arguments to "dst", + each preceded by a space character. This function is + available for scripted use as 'git rev-parse --sq-quote'. + +`sq_dequote`:: + This unwraps what sq_quote() produces in place, but returns + NULL if the input does not look like what sq_quote would have + produced. + +`sq_dequote_to_argv`:: + Like the above, but unwrap many arguments in the same string + separated by space. "*argv", "*nr", and "*alloc" should be a + pointer to a malloc-ed array (or NULL), its current number of + valid elements, and the number of allocated elements, for + example as managed with ALLOC_GROW. The result is appended + after the valid part of *argv. + +Quoting for other languages +--------------------------- + +`perl_quote_print`:: +`python_quote_print`:: +`tcl_quote_print`:: + Quote as a string literal for evaluation in the specified + language. This is used by 'git for-each-ref' to output + various aspects of objects for use by language bindings. diff --git a/quote.h b/quote.h index 38003bf..cec40b0 100644 --- a/quote.h +++ b/quote.h @@ -23,9 +23,8 @@ * Note that the above examples leak memory! Remember to free result from * sq_quote() in a real application. * - * sq_quote_buf() writes to an existing buffer of specified size; it - * will return the number of characters that would have been written - * excluding the final null regardless of the buffer size. + * sq_quote_buf() writes to the end of a strbuf instead of + * allocating a new buffer. */ extern void sq_quote_print(FILE *stream, const char *src); @@ -40,10 +39,11 @@ extern void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen); extern char *sq_dequote(char *); /* - * Same as the above, but can be used to unwrap many arguments in the - * same string separated by space. "next" is changed to point to the - * next argument that should be passed as first parameter. When there - * is no more argument to be dequoted, "next" is updated to point to NULL. + * Similar to the above, but unwraps many arguments in the + * same string separated by space. "*argv" is expanded to hold + * the dequoted arguments in positions (*argv)[*nr], *argv[*nr+1], etc + * and *nr and *alloc updated to hold the new number of entries + * and allocated size of the array. */ extern int sq_dequote_to_argv(char *arg, const char ***argv, int *nr, int *alloc); -- 1.7.4.rc0.580.g89dc.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html