From: Jonathan Nieder <jrnieder@gmail.com>
To: git@vger.kernel.org
Cc: Christian Couder <chriscool@tuxfamily.org>,
Jeff King <peff@peff.net>, Dmitry Potapov <dpotapov@gmail.com>
Subject: [RFC/PATCH] Documentation/technical: document quoting API
Date: Mon, 3 Jan 2011 00:35:34 -0600 [thread overview]
Message-ID: <20110103063534.GA3661@burratino> (raw)
Briefly explain the zoo of quoting functions.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
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
next reply other threads:[~2011-01-03 6:35 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-03 6:35 Jonathan Nieder [this message]
2011-01-03 7:39 ` [RFC/PATCH] Documentation/technical: document quoting API Nguyen Thai Ngoc Duy
2011-01-04 19:21 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110103063534.GA3661@burratino \
--to=jrnieder@gmail.com \
--cc=chriscool@tuxfamily.org \
--cc=dpotapov@gmail.com \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).