[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: quotearg: implement custom_quoting_style
From: |
Joel E. Denny |
Subject: |
Re: quotearg: implement custom_quoting_style |
Date: |
Sun, 23 Aug 2009 18:37:43 -0400 (EDT) |
User-agent: |
Alpine 1.00 (DEB 882 2007-12-20) |
On Sun, 23 Aug 2009, Bruno Haible wrote:
> > Ok to push the previous 4 patches followed by the one below?
>
> If you can do that, it would be preferable to merge the 3rd and 5th
> patch together before pushing, because the intermediate states of your
> work are hardly important for the future.
Ok.
> You can't do that any more
> once it's pushed. You know how to do that? If not, here's the recipe:
> 4. "git rebase -i HEAD~3" and in the editor change
> pick 3
> pick 4
> pick 5
> into
> pick 3
> squash 5
> pick 4
> (where the numbers 3, 4, 5 are more complicated than that).
Thanks. I had never used "git rebase -i" before. At the squash step, it
let me merge the git log entries but not the ChangeLog entries. Is there
a way to do that?
For now, I stuck with what I know:
git branch tmp
git reset --hard HEAD^^
git reset --soft HEAD^
git cherry-pick -n tmp
# Merge ChangeLog entries.
git commit -a
git cherry-pick tmp^
I pushed the result, shown below.
>From 3293597efd0255a347b8a71890f08f605ef267b4 Mon Sep 17 00:00:00 2001
From: Joel E. Denny <address@hidden>
Date: Sat, 22 Aug 2009 17:55:15 -0400
Subject: [PATCH] quotearg-tests: test escaping of embedded locale quotes
* tests/test-quotearg.c (struct result_strings): Add member for
new input.
(LQ_ENC, RQ_ENC, RQ_ESC): New macros.
(inputs): Add new input.
(results_g): Add expected results.
(flag_results): Likewise.
(locale_results): Likewise.
(compare_strings): Check those.
---
ChangeLog | 12 +++++
tests/test-quotearg.c | 115 ++++++++++++++++++++++++++++++-------------------
2 files changed, 83 insertions(+), 44 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 9c9e827..4698367 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-08-22 Joel E. Denny <address@hidden>
+
+ quotearg-tests: test escaping of embedded locale quotes
+ * tests/test-quotearg.c (struct result_strings): Add member for
+ new input.
+ (LQ_ENC, RQ_ENC, RQ_ESC): New macros.
+ (inputs): Add new input.
+ (results_g): Add expected results.
+ (flag_results): Likewise.
+ (locale_results): Likewise.
+ (compare_strings): Check those.
+
2009-08-23 Bruno Haible <address@hidden>
Tests for module 'dup3'.
diff --git a/tests/test-quotearg.c b/tests/test-quotearg.c
index 73bb1f9..ef91c80 100644
--- a/tests/test-quotearg.c
+++ b/tests/test-quotearg.c
@@ -52,6 +52,7 @@ struct result_strings {
char const *str4; /* Translation of " \t\n'\"\033?""?/\\". */
char const *str5; /* Translation of "a:b". */
char const *str6; /* Translation of "a\\b". */
+ char const *str7; /* Translation of LQ RQ. */
};
struct result_groups {
@@ -60,118 +61,140 @@ struct result_groups {
struct result_strings group3; /* Via quotearg_colon{,_mem}. */
};
+/* These quotes are borrowed from a pt_PT.utf8 translation. */
+# define LQ "\302\253"
+# define RQ "\302\273"
+# define LQ_ENC "\\302\\253"
+# define RQ_ENC "\\302\\273"
+# define RQ_ESC "\\\302\273"
+
static struct result_strings inputs = {
- "", "\0001\0", 3, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b"
+ "", "\0001\0", 3, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+ LQ RQ
};
static struct result_groups results_g[] = {
/* literal_quoting_style */
- { { "", "\0""1\0", 3, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b" },
- { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b" },
- { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b" } },
+ { { "", "\0""1\0", 3, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+ LQ RQ },
+ { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+ LQ RQ },
+ { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+ LQ RQ } },
/* shell_quoting_style */
{ { "''", "\0""1\0", 3, "simple", "' \t\n'\\''\"\033?""?/\\'", "a:b",
- "'a\\b'" },
+ "'a\\b'", LQ RQ },
{ "''", "1", 1, "simple", "' \t\n'\\''\"\033?""?/\\'", "a:b",
- "'a\\b'" },
+ "'a\\b'", LQ RQ },
{ "''", "1", 1, "simple", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
- "'a\\b'" } },
+ "'a\\b'", LQ RQ } },
/* shell_always_quoting_style */
{ { "''", "'\0""1\0'", 5, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
- "'a\\b'" },
+ "'a\\b'", "'" LQ RQ "'" },
{ "''", "'1'", 3, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
- "'a\\b'" },
+ "'a\\b'", "'" LQ RQ "'" },
{ "''", "'1'", 3, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
- "'a\\b'" } },
+ "'a\\b'", "'" LQ RQ "'" } },
/* c_quoting_style */
{ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
- "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"" },
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"" },
{ "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
- "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"" },
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"" },
{ "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
- "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"" } },
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"" } },
/* c_maybe_quoting_style */
{ { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
- "a:b", "a\\b" },
+ "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"" },
{ "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
- "a:b", "a\\b" },
+ "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"" },
{ "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
- "\"a:b\"", "a\\b" } },
+ "\"a:b\"", "a\\b", "\"" LQ_ENC RQ_ENC "\"" } },
/* escape_quoting_style */
{ { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a:b",
- "a\\\\b" },
+ "a\\\\b", LQ_ENC RQ_ENC },
{ "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a:b",
- "a\\\\b" },
+ "a\\\\b", LQ_ENC RQ_ENC },
{ "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a\\:b",
- "a\\\\b" } },
+ "a\\\\b", LQ_ENC RQ_ENC } },
/* locale_quoting_style */
{ { "`'", "`\\0001\\0'", 9, "`simple'", "` \\t\\n\\'\"\\033?""?/\\\\'",
- "`a:b'", "`a\\\\b'" },
+ "`a:b'", "`a\\\\b'", "`" LQ_ENC RQ_ENC "'" },
{ "`'", "`\\0001\\0'", 9, "`simple'", "` \\t\\n\\'\"\\033?""?/\\\\'",
- "`a:b'", "`a\\\\b'" },
+ "`a:b'", "`a\\\\b'", "`" LQ_ENC RQ_ENC "'" },
{ "`'", "`\\0001\\0'", 9, "`simple'", "` \\t\\n\\'\"\\033?""?/\\\\'",
- "`a\\:b'", "`a\\\\b'" } },
+ "`a\\:b'", "`a\\\\b'", "`" LQ_ENC RQ_ENC "'" } },
/* clocale_quoting_style */
{ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
- "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"" },
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"" },
{ "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
- "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"" },
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"" },
{ "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
- "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"" } }
+ "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"" } }
};
static struct result_groups flag_results[] = {
/* literal_quoting_style and QA_ELIDE_NULL_BYTES */
- { { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b" },
- { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b" },
- { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b" } },
+ { { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", LQ RQ },
+ { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", LQ RQ },
+ { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", LQ RQ } },
/* c_quoting_style and QA_ELIDE_OUTER_QUOTES */
{ { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
- "a:b", "a\\b" },
+ "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"" },
{ "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
- "a:b", "a\\b" },
+ "a:b", "a\\b", "\"" LQ_ENC RQ_ENC "\"" },
{ "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
- "\"a:b\"", "a\\b" } },
+ "\"a:b\"", "a\\b", "\"" LQ_ENC RQ_ENC "\"" } },
/* c_quoting_style and QA_SPLIT_TRIGRAPHS */
{ { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
- "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"" },
+ "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"" },
{ "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
- "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"" },
+ "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"" },
{ "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
- "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"" } }
+ "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
+ "\"" LQ_ENC RQ_ENC "\"" } }
};
#if ENABLE_NLS
-/* These quotes are borrowed from a pt_PT.utf8 translation. */
-# define LQ "\302\253"
-# define RQ "\302\273"
-
static struct result_groups locale_results[] = {
/* locale_quoting_style */
{ { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
- LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ },
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ },
{ LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
- LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ },
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ },
{ LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
- LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a\\:b" RQ, LQ "a\\\\b" RQ } },
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a\\:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ } },
/* clocale_quoting_style */
{ { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
- LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ },
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ },
{ LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
- LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ },
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ },
{ LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
- LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a\\:b" RQ, LQ "a\\\\b" RQ } }
+ LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a\\:b" RQ, LQ "a\\\\b" RQ,
+ LQ LQ RQ_ESC RQ } }
};
#endif /* ENABLE_NLS */
@@ -214,6 +237,10 @@ compare_strings (char *(func) (char const *, size_t *),
len = strlen (inputs.str6);
p = func (inputs.str6, &len);
compare (results->str6, strlen (results->str6), p, len);
+
+ len = strlen (inputs.str7);
+ p = func (inputs.str7, &len);
+ compare (results->str7, strlen (results->str7), p, len);
}
static char *
--
1.5.4.3
>From f6fe750d033c40b403688dc3eee9dbff468aa8f3 Mon Sep 17 00:00:00 2001
From: Joel E. Denny <address@hidden>
Date: Sat, 22 Aug 2009 20:26:46 -0400
Subject: [PATCH] quotearg: fix right quote escaping when it's in quote_these_too
* lib/quotearg.c (quotearg_buffer_restyled): Upon seeing a right
quote, be sure to prepend only one backslash.
* tests/test-quotearg.c (use_quote_double_quotes): New function.
(main): Test it.
---
ChangeLog | 8 ++++++++
lib/quotearg.c | 11 +++++++++--
tests/test-quotearg.c | 13 +++++++++++++
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 4698367..57f5f32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2009-08-22 Joel E. Denny <address@hidden>
+ quotearg: fix right quote escaping when it's in quote_these_too
+ * lib/quotearg.c (quotearg_buffer_restyled): Upon seeing a right
+ quote, be sure to prepend only one backslash.
+ * tests/test-quotearg.c (use_quote_double_quotes): New function.
+ (main): Test it.
+
+2009-08-22 Joel E. Denny <address@hidden>
+
quotearg-tests: test escaping of embedded locale quotes
* tests/test-quotearg.c (struct result_strings): Add member for
new input.
diff --git a/lib/quotearg.c b/lib/quotearg.c
index 339bf34..3f9e628 100644
--- a/lib/quotearg.c
+++ b/lib/quotearg.c
@@ -280,6 +280,7 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
{
unsigned char c;
unsigned char esc;
+ bool is_right_quote = false;
if (backslash_escapes
&& quote_string_len
@@ -288,7 +289,7 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
{
if (elide_outer_quotes)
goto force_outer_quoting_style;
- STORE ('\\');
+ is_right_quote = true;
}
c = arg[i];
@@ -521,6 +522,11 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
STORE ('0' + ((c >> 3) & 7));
c = '0' + (c & 7);
}
+ else if (is_right_quote)
+ {
+ STORE ('\\');
+ is_right_quote = false;
+ }
if (ilim <= i + 1)
break;
STORE (c);
@@ -534,7 +540,8 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
if (! ((backslash_escapes || elide_outer_quotes)
&& quote_these_too
- && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
+ && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
+ && !is_right_quote)
goto store_c;
store_escape:
diff --git a/tests/test-quotearg.c b/tests/test-quotearg.c
index ef91c80..2e2c56b 100644
--- a/tests/test-quotearg.c
+++ b/tests/test-quotearg.c
@@ -264,6 +264,15 @@ use_quotearg (const char *str, size_t *len)
}
static char *
+use_quote_double_quotes (const char *str, size_t *len)
+{
+ char *p = *len == SIZE_MAX ? quotearg_char (str, '"')
+ : quotearg_char_mem (str, *len, '"');
+ *len = strlen (p);
+ return p;
+}
+
+static char *
use_quotearg_colon (const char *str, size_t *len)
{
char *p = (*len == SIZE_MAX ? quotearg_colon (str)
@@ -287,6 +296,8 @@ main (int argc, char *argv[])
set_quoting_style (NULL, i);
compare_strings (use_quotearg_buffer, &results_g[i].group1);
compare_strings (use_quotearg, &results_g[i].group2);
+ if (i == c_quoting_style)
+ compare_strings (use_quote_double_quotes, &results_g[i].group2);
compare_strings (use_quotearg_colon, &results_g[i].group3);
}
@@ -301,12 +312,14 @@ main (int argc, char *argv[])
== QA_ELIDE_NULL_BYTES);
compare_strings (use_quotearg_buffer, &flag_results[1].group1);
compare_strings (use_quotearg, &flag_results[1].group2);
+ compare_strings (use_quote_double_quotes, &flag_results[1].group2);
compare_strings (use_quotearg_colon, &flag_results[1].group3);
ASSERT (set_quoting_flags (NULL, QA_SPLIT_TRIGRAPHS)
== QA_ELIDE_OUTER_QUOTES);
compare_strings (use_quotearg_buffer, &flag_results[2].group1);
compare_strings (use_quotearg, &flag_results[2].group2);
+ compare_strings (use_quote_double_quotes, &flag_results[2].group2);
compare_strings (use_quotearg_colon, &flag_results[2].group3);
ASSERT (set_quoting_flags (NULL, 0) == QA_SPLIT_TRIGRAPHS);
--
1.5.4.3
>From 12247f770487cd389e515a51d6bfeb250f26e519 Mon Sep 17 00:00:00 2001
From: Joel E. Denny <address@hidden>
Date: Sun, 23 Aug 2009 18:24:53 -0400
Subject: [PATCH] quotearg: implement custom_quoting_style
* lib/quotearg.c: (struct quoting_options): Add left_quote and
right_quote fields.
(set_custom_quoting): New public function.
(quotearg_buffer_restyled): Add left_quote and right_quote
arguments, handle them very much like locale quoting, and update
all uses.
(quotearg_n_custom): New public function.
(quotearg_n_custom_mem): New public function.
(quotearg_custom): New public function.
(quotearg_custom_mem): New public function.
* lib/quotearg.h: Prototype and document new public functions.
(enum quoting_style): For escape_quoting_style and
clocale_quoting_style, comment that QA_SPLIT_TRIGRAPHS is
ignored even though they're otherwise like c_quoting_style.
Add custom_quoting_style member and document with comparison to
clocale_quoting_style.
* tests/test-quotearg.c (custom_quotes): New array.
(custom_results): New array.
(main): Extend to test custom quoting.
---
ChangeLog | 23 ++++++++
lib/quotearg.c | 141 ++++++++++++++++++++++++++++++++++++++-----------
lib/quotearg.h | 87 +++++++++++++++++++++++++++++-
tests/test-quotearg.c | 98 ++++++++++++++++++++++++++++++++++
4 files changed, 314 insertions(+), 35 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 57f5f32..c71b417 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2009-08-23 Joel E. Denny <address@hidden>
+
+ quotearg: implement custom_quoting_style
+ * lib/quotearg.c: (struct quoting_options): Add left_quote and
+ right_quote fields.
+ (set_custom_quoting): New public function.
+ (quotearg_buffer_restyled): Add left_quote and right_quote
+ arguments, handle them very much like locale quoting, and update
+ all uses.
+ (quotearg_n_custom): New public function.
+ (quotearg_n_custom_mem): New public function.
+ (quotearg_custom): New public function.
+ (quotearg_custom_mem): New public function.
+ * lib/quotearg.h: Prototype and document new public functions.
+ (enum quoting_style): For escape_quoting_style and
+ clocale_quoting_style, comment that QA_SPLIT_TRIGRAPHS is
+ ignored even though they're otherwise like c_quoting_style.
+ Add custom_quoting_style member and document with comparison to
+ clocale_quoting_style.
+ * tests/test-quotearg.c (custom_quotes): New array.
+ (custom_results): New array.
+ (main): Extend to test custom quoting.
+
2009-08-22 Joel E. Denny <address@hidden>
quotearg: fix right quote escaping when it's in quote_these_too
diff --git a/lib/quotearg.c b/lib/quotearg.c
index 3f9e628..314c627 100644
--- a/lib/quotearg.c
+++ b/lib/quotearg.c
@@ -54,6 +54,12 @@ struct quoting_options
/* Quote the characters indicated by this bit vector even if the
quoting style would not normally require them to be quoted. */
unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
+
+ /* The left quote for custom_quoting_style. */
+ char const *left_quote;
+
+ /* The right quote for custom_quoting_style. */
+ char const *right_quote;
};
/* Names of quoting styles. */
@@ -146,6 +152,19 @@ set_quoting_flags (struct quoting_options *o, int i)
return r;
}
+void
+set_custom_quoting (struct quoting_options *o,
+ char const *left_quote, char const *right_quote)
+{
+ if (!o)
+ o = &default_quoting_options;
+ o->style = custom_quoting_style;
+ if (!left_quote || !right_quote)
+ abort ();
+ o->left_quote = left_quote;
+ o->right_quote = right_quote;
+}
+
/* Return quoting options for STYLE, with no extra quoting. */
static struct quoting_options
quoting_options_from_style (enum quoting_style style)
@@ -185,7 +204,9 @@ static size_t
quotearg_buffer_restyled (char *buffer, size_t buffersize,
char const *arg, size_t argsize,
enum quoting_style quoting_style, int flags,
- unsigned int const *quote_these_too)
+ unsigned int const *quote_these_too,
+ char const *left_quote,
+ char const *right_quote)
{
size_t i;
size_t len = 0;
@@ -225,34 +246,37 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
case locale_quoting_style:
case clocale_quoting_style:
+ case custom_quoting_style:
{
- /* TRANSLATORS:
- Get translations for open and closing quotation marks.
-
- The message catalog should translate "`" to a left
- quotation mark suitable for the locale, and similarly for
- "'". If the catalog has no translation,
- locale_quoting_style quotes `like this', and
- clocale_quoting_style quotes "like this".
-
- For example, an American English Unicode locale should
- translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and
- should translate "'" to U+201D (RIGHT DOUBLE QUOTATION
- MARK). A British English Unicode locale should instead
- translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and
- U+2019 (RIGHT SINGLE QUOTATION MARK), respectively.
-
- If you don't know what to put here, please see
- <http://en.wikipedia.org/wiki/Quotation_mark#Glyphs>
- and use glyphs suitable for your language. */
-
- char const *left = gettext_quote (N_("`"), quoting_style);
- char const *right = gettext_quote (N_("'"), quoting_style);
+ if (quoting_style != custom_quoting_style)
+ {
+ /* TRANSLATORS:
+ Get translations for open and closing quotation marks.
+
+ The message catalog should translate "`" to a left
+ quotation mark suitable for the locale, and similarly for
+ "'". If the catalog has no translation,
+ locale_quoting_style quotes `like this', and
+ clocale_quoting_style quotes "like this".
+
+ For example, an American English Unicode locale should
+ translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and
+ should translate "'" to U+201D (RIGHT DOUBLE QUOTATION
+ MARK). A British English Unicode locale should instead
+ translate these to U+2018 (LEFT SINGLE QUOTATION MARK)
+ and U+2019 (RIGHT SINGLE QUOTATION MARK), respectively.
+
+ If you don't know what to put here, please see
+ <http://en.wikipedia.org/wiki/Quotation_mark#Glyphs>
+ and use glyphs suitable for your language. */
+ left_quote = gettext_quote (N_("`"), quoting_style);
+ right_quote = gettext_quote (N_("'"), quoting_style);
+ }
if (!elide_outer_quotes)
- for (quote_string = left; *quote_string; quote_string++)
+ for (quote_string = left_quote; *quote_string; quote_string++)
STORE (*quote_string);
backslash_escapes = true;
- quote_string = right;
+ quote_string = right_quote;
quote_string_len = strlen (quote_string);
}
break;
@@ -301,6 +325,11 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
if (elide_outer_quotes)
goto force_outer_quoting_style;
STORE ('\\');
+ /* If quote_string were to begin with digits, we'd need to
+ test for the end of the arg as well. However, it's
+ hard to imagine any locale that would use digits in
+ quotes, and set_custom_quoting is documented not to
+ accept them. */
if (i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9')
{
STORE ('0');
@@ -426,7 +455,13 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
case 'o': case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
/* These characters don't cause problems, no matter what the
- quoting style is. They cannot start multibyte sequences. */
+ quoting style is. They cannot start multibyte sequences.
+ A digit or a special letter would cause trouble if it
+ appeared at the beginning of quote_string because we'd then
+ escape by prepending a backslash. However, it's hard to
+ imagine any locale that would use digits or letters as
+ quotes, and set_custom_quoting is documented not to accept
+ them. */
break;
default:
@@ -570,7 +605,8 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
sufficiently quotes the specified characters. */
return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
quoting_style,
- flags & ~QA_ELIDE_OUTER_QUOTES, NULL);
+ flags & ~QA_ELIDE_OUTER_QUOTES, NULL,
+ left_quote, right_quote);
}
/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
@@ -590,7 +626,8 @@ quotearg_buffer (char *buffer, size_t buffersize,
struct quoting_options const *p = o ? o : &default_quoting_options;
int e = errno;
size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
- p->style, p->flags, p->quote_these_too);
+ p->style, p->flags, p->quote_these_too,
+ p->left_quote, p->right_quote);
errno = e;
return r;
}
@@ -618,10 +655,13 @@ quotearg_alloc_mem (char const *arg, size_t argsize,
size_t *size,
/* Elide embedded null bytes if we can't return a size. */
int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
- flags, p->quote_these_too) + 1;
+ flags, p->quote_these_too,
+ p->left_quote,
+ p->right_quote) + 1;
char *buf = xcharalloc (bufsize);
quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
- p->quote_these_too);
+ p->quote_these_too,
+ p->left_quote, p->right_quote);
errno = e;
if (size)
*size = bufsize - 1;
@@ -710,7 +750,9 @@ quotearg_n_options (int n, char const *arg, size_t argsize,
int flags = options->flags | QA_ELIDE_NULL_BYTES;
size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
options->style, flags,
- options->quote_these_too);
+ options->quote_these_too,
+ options->left_quote,
+ options->right_quote);
if (size <= qsize)
{
@@ -719,7 +761,9 @@ quotearg_n_options (int n, char const *arg, size_t argsize,
free (val);
sv[n].val = val = xcharalloc (size);
quotearg_buffer_restyled (val, size, arg, argsize, options->style,
- flags, options->quote_these_too);
+ flags, options->quote_these_too,
+ options->left_quote,
+ options->right_quote);
}
errno = e;
@@ -804,3 +848,36 @@ quotearg_colon_mem (char const *arg, size_t argsize)
{
return quotearg_char_mem (arg, argsize, ':');
}
+
+char *
+quotearg_n_custom (int n, char const *left_quote,
+ char const *right_quote, char const *arg)
+{
+ return quotearg_n_custom_mem (n, left_quote, right_quote, arg,
+ SIZE_MAX);
+}
+
+char *
+quotearg_n_custom_mem (int n, char const *left_quote,
+ char const *right_quote,
+ char const *arg, size_t argsize)
+{
+ struct quoting_options o = default_quoting_options;
+ set_custom_quoting (&o, left_quote, right_quote);
+ return quotearg_n_options (n, arg, argsize, &o);
+}
+
+char *
+quotearg_custom (char const *left_quote, char const *right_quote,
+ char const *arg)
+{
+ return quotearg_n_custom (0, left_quote, right_quote, arg);
+}
+
+char *
+quotearg_custom_mem (char const *left_quote, char const *right_quote,
+ char const *arg, size_t argsize)
+{
+ return quotearg_n_custom_mem (0, left_quote, right_quote, arg,
+ argsize);
+}
diff --git a/lib/quotearg.h b/lib/quotearg.h
index 7700107..e9f6f56 100644
--- a/lib/quotearg.h
+++ b/lib/quotearg.h
@@ -100,7 +100,8 @@ enum quoting_style
c_maybe_quoting_style,
/* Like c_quoting_style except always omit the surrounding
- double-quote characters (ls --quoting-style=escape).
+ double-quote characters and ignore QA_SPLIT_TRIGRAPHS
+ (ls --quoting-style=escape).
quotearg_buffer:
"simple", "\\0 \\t\\n'\"\\033??/\\\\", "a:b"
@@ -136,7 +137,8 @@ enum quoting_style
locale_quoting_style,
/* Like c_quoting_style except use quotation marks appropriate for
- the locale (ls --quoting-style=clocale).
+ the locale and ignore QA_SPLIT_TRIGRAPHS
+ (ls --quoting-style=clocale).
LC_MESSAGES=C
quotearg_buffer:
@@ -157,7 +159,50 @@ enum quoting_style
"\302\253simple\302\273",
"\302\253\\0 \\t\\n'\"\\033??/\\\\\302\253", "\302\253a\\:b\302\273"
*/
- clocale_quoting_style
+ clocale_quoting_style,
+
+ /* Like clocale_quoting_style except use the custom quotation marks
+ set by set_custom_quoting. If custom quotation marks are not
+ set, the behavior is undefined.
+
+ left_quote = right_quote = "'"
+ quotearg_buffer:
+ "'simple'", "'\\0 \\t\\n\\'\"\\033??/\\\\'", "'a:b'"
+ quotearg:
+ "'simple'", "'\\0 \\t\\n\\'\"\\033??/\\\\'", "'a:b'"
+ quotearg_colon:
+ "'simple'", "'\\0 \\t\\n\\'\"\\033??/\\\\'", "'a\\:b'"
+
+ left_quote = "(" and right_quote = ")"
+ quotearg_buffer:
+ "(simple)", "(\\0 \\t\\n'\"\\033??/\\\\)", "(a:b)"
+ quotearg:
+ "(simple)", "(\\0 \\t\\n'\"\\033??/\\\\)", "(a:b)"
+ quotearg_colon:
+ "(simple)", "(\\0 \\t\\n'\"\\033??/\\\\)", "(a\\:b)"
+
+ left_quote = ":" and right_quote = " "
+ quotearg_buffer:
+ ":simple ", ":\\0\\ \\t\\n'\"\\033??/\\\\ ", ":a:b "
+ quotearg:
+ ":simple ", ":\\0\\ \\t\\n'\"\\033??/\\\\ ", ":a:b "
+ quotearg_colon:
+ ":simple ", ":\\0\\ \\t\\n'\"\\033??/\\\\ ", ":a\\:b "
+
+ left_quote = "\"'" and right_quote = "'\""
+ Notice that this is treated as a single level of quotes or two
+ levels where the outer quote need not be escaped within the inner
+ quotes. For two levels where the outer quote must be escaped
+ within the inner quotes, you must use separate quotearg
+ invocations.
+ quotearg_buffer:
+ "\"'simple'\"", "\"'\\0 \\t\\n\\'\"\\033??/\\\\'\"", "\"'a:b'\""
+ quotearg:
+ "\"'simple'\"", "\"'\\0 \\t\\n\\'\"\\033??/\\\\'\"", "\"'a:b'\""
+ quotearg_colon:
+ "\"'simple'\"", "\"'\\0 \\t\\n\\'\"\\033??/\\\\'\"", "\"'a\\:b'\""
+ */
+ custom_quoting_style
};
/* Flags for use in set_quoting_flags. */
@@ -219,6 +264,19 @@ int set_char_quoting (struct quoting_options *o, char c,
int i);
behavior. Return the old value. */
int set_quoting_flags (struct quoting_options *o, int i);
+/* In O (or in the default if O is null),
+ set the value of the quoting style to custom_quoting_style,
+ set the left quote to LEFT_QUOTE, and set the right quote to
+ RIGHT_QUOTE. Each of LEFT_QUOTE and RIGHT_QUOTE must be
+ null-terminated and can be the empty string. Because backslashes are
+ used for escaping, it does not make sense for RIGHT_QUOTE to contain
+ a backslash. RIGHT_QUOTE must not begin with a digit or a letter
+ that has special meaning after a backslash (for example, "\t" for
+ tab). */
+void set_custom_quoting (struct quoting_options *o,
+ char const *left_quote,
+ char const *right_quote);
+
/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
argument ARG (of size ARGSIZE), using O to control quoting.
If O is null, use the default.
@@ -299,6 +357,29 @@ char *quotearg_colon (char const *arg);
/* Like quotearg_colon (ARG), except it can quote null bytes. */
char *quotearg_colon_mem (char const *arg, size_t argsize);
+/* Like quotearg_n_style (N, S, ARG) but with S as custom_quoting_style
+ with left quote as LEFT_QUOTE and right quote as RIGHT_QUOTE. See
+ set_custom_quoting for a description of acceptable LEFT_QUOTE and
+ RIGHT_QUOTE values. */
+char *quotearg_n_custom (int n, char const *left_quote,
+ char const *right_quote, char const *arg);
+
+/* Like quotearg_n_custom (N, LEFT_QUOTE, RIGHT_QUOTE, ARG) except it
+ can quote null bytes. */
+char *quotearg_n_custom_mem (int n, char const *left_quote,
+ char const *right_quote,
+ char const *arg, size_t argsize);
+
+/* Equivalent to quotearg_n_custom (0, LEFT_QUOTE, RIGHT_QUOTE, ARG). */
+char *quotearg_custom (char const *left_quote, char const *right_quote,
+ char const *arg);
+
+/* Equivalent to quotearg_n_custom_mem (0, LEFT_QUOTE, RIGHT_QUOTE, ARG,
+ ARGSIZE). */
+char *quotearg_custom_mem (char const *left_quote,
+ char const *right_quote,
+ char const *arg, size_t argsize);
+
/* Free any dynamically allocated memory. */
void quotearg_free (void);
diff --git a/tests/test-quotearg.c b/tests/test-quotearg.c
index 2e2c56b..65779ad 100644
--- a/tests/test-quotearg.c
+++ b/tests/test-quotearg.c
@@ -199,6 +199,95 @@ static struct result_groups locale_results[] = {
#endif /* ENABLE_NLS */
+static char const *custom_quotes[][2] = {
+ { "", "" },
+ { "'", "'" },
+ { "(", ")" },
+ { ":", " " },
+ { " ", ":" },
+ { "# ", "\n" },
+ { "\"'", "'\"" }
+};
+
+static struct result_groups custom_results[] = {
+ /* left_quote = right_quote = "" */
+ { { "", "\\0001\\0", 7, "simple",
+ " \\t\\n'\"\\033?""?/\\\\", "a:b", "a\\\\b",
+ LQ_ENC RQ_ENC },
+ { "", "\\0001\\0", 7, "simple",
+ " \\t\\n'\"\\033?""?/\\\\", "a:b", "a\\\\b",
+ LQ_ENC RQ_ENC },
+ { "", "\\0001\\0", 7, "simple",
+ " \\t\\n'\"\\033?""?/\\\\", "a\\:b", "a\\\\b",
+ LQ_ENC RQ_ENC } },
+
+ /* left_quote = right_quote = "'" */
+ { { "''", "'\\0001\\0'", 9, "'simple'",
+ "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'",
+ "'" LQ_ENC RQ_ENC "'" },
+ { "''", "'\\0001\\0'", 9, "'simple'",
+ "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'",
+ "'" LQ_ENC RQ_ENC "'" },
+ { "''", "'\\0001\\0'", 9, "'simple'",
+ "' \\t\\n\\'\"\\033?""?/\\\\'", "'a\\:b'", "'a\\\\b'",
+ "'" LQ_ENC RQ_ENC "'" } },
+
+ /* left_quote = "(" and right_quote = ")" */
+ { { "()", "(\\0001\\0)", 9, "(simple)",
+ "( \\t\\n'\"\\033?""?/\\\\)", "(a:b)", "(a\\\\b)",
+ "(" LQ_ENC RQ_ENC ")" },
+ { "()", "(\\0001\\0)", 9, "(simple)",
+ "( \\t\\n'\"\\033?""?/\\\\)", "(a:b)", "(a\\\\b)",
+ "(" LQ_ENC RQ_ENC ")" },
+ { "()", "(\\0001\\0)", 9, "(simple)",
+ "( \\t\\n'\"\\033?""?/\\\\)", "(a\\:b)", "(a\\\\b)",
+ "(" LQ_ENC RQ_ENC ")" } },
+
+ /* left_quote = ":" and right_quote = " " */
+ { { ": ", ":\\0001\\0 ", 9, ":simple ",
+ ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a:b ", ":a\\\\b ",
+ ":" LQ_ENC RQ_ENC " " },
+ { ": ", ":\\0001\\0 ", 9, ":simple ",
+ ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a:b ", ":a\\\\b ",
+ ":" LQ_ENC RQ_ENC " " },
+ { ": ", ":\\0001\\0 ", 9, ":simple ",
+ ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a\\:b ", ":a\\\\b ",
+ ":" LQ_ENC RQ_ENC " " } },
+
+ /* left_quote = " " and right_quote = ":" */
+ { { " :", " \\0001\\0:", 9, " simple:",
+ " \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
+ " " LQ_ENC RQ_ENC ":" },
+ { " :", " \\0001\\0:", 9, " simple:",
+ " \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
+ " " LQ_ENC RQ_ENC ":" },
+ { " :", " \\0001\\0:", 9, " simple:",
+ " \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
+ " " LQ_ENC RQ_ENC ":" } },
+
+ /* left_quote = "# " and right_quote = "\n" */
+ { { "# \n", "# \\0001\\0\n", 10, "# simple\n",
+ "# \\t\\n'\"\\033?""?/\\\\\n", "# a:b\n", "# a\\\\b\n",
+ "# " LQ_ENC RQ_ENC "\n" },
+ { "# \n", "# \\0001\\0\n", 10, "# simple\n",
+ "# \\t\\n'\"\\033?""?/\\\\\n", "# a:b\n", "# a\\\\b\n",
+ "# " LQ_ENC RQ_ENC "\n" },
+ { "# \n", "# \\0001\\0\n", 10, "# simple\n",
+ "# \\t\\n'\"\\033?""?/\\\\\n", "# a\\:b\n", "# a\\\\b\n",
+ "# " LQ_ENC RQ_ENC "\n" } },
+
+ /* left_quote = "\"'" and right_quote = "'\"" */
+ { { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
+ "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a:b'\"", "\"'a\\\\b'\"",
+ "\"'" LQ_ENC RQ_ENC "'\"" },
+ { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
+ "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a:b'\"", "\"'a\\\\b'\"",
+ "\"'" LQ_ENC RQ_ENC "'\"" },
+ { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
+ "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a\\:b'\"", "\"'a\\\\b'\"",
+ "\"'" LQ_ENC RQ_ENC "'\"" } }
+};
+
static void
compare (char const *a, size_t la, char const *b, size_t lb)
{
@@ -324,6 +413,15 @@ main (int argc, char *argv[])
ASSERT (set_quoting_flags (NULL, 0) == QA_SPLIT_TRIGRAPHS);
+ for (i = 0; i < sizeof custom_quotes / sizeof *custom_quotes; ++i)
+ {
+ set_custom_quoting (NULL,
+ custom_quotes[i][0], custom_quotes[i][1]);
+ compare_strings (use_quotearg_buffer, &custom_results[i].group1);
+ compare_strings (use_quotearg, &custom_results[i].group2);
+ compare_strings (use_quotearg_colon, &custom_results[i].group3);
+ }
+
#if ENABLE_NLS
/* Clean up environment. */
unsetenv ("LANGUAGE");
--
1.5.4.3
>From 98bf7f3d50bbdf7f043938f754c50c7e467933bf Mon Sep 17 00:00:00 2001
From: Joel E. Denny <address@hidden>
Date: Sat, 22 Aug 2009 20:55:17 -0400
Subject: [PATCH] quotearg: document limitations of quote_these_too
* lib/quotearg.c (quotearg_buffer_restyled): Add comments where
those limitations are created.
* lib/quotearg.h (set_char_quoting): Document that digits and
letters that are special after backslash are not permitted.
(quotearg_char): Cross-reference set_char_quoting documentation.
---
ChangeLog | 9 +++++++++
lib/quotearg.c | 8 +++++++-
lib/quotearg.h | 7 +++++--
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c71b417..6fc1016 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-08-22 Joel E. Denny <address@hidden>
+
+ quotearg: document limitations of quote_these_too
+ * lib/quotearg.c (quotearg_buffer_restyled): Add comments where
+ those limitations are created.
+ * lib/quotearg.h (set_char_quoting): Document that digits and
+ letters that are special after backslash are not permitted.
+ (quotearg_char): Cross-reference set_char_quoting documentation.
+
2009-08-23 Joel E. Denny <address@hidden>
quotearg: implement custom_quoting_style
diff --git a/lib/quotearg.c b/lib/quotearg.c
index 314c627..8380e9d 100644
--- a/lib/quotearg.c
+++ b/lib/quotearg.c
@@ -336,6 +336,10 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
STORE ('0');
}
c = '0';
+ /* We don't have to worry that this last '0' will be
+ backslash-escaped because, again, quote_string should
+ not start with it and because quote_these_too is
+ documented as not accepting it. */
}
else if (flags & QA_ELIDE_NULL_BYTES)
continue;
@@ -461,7 +465,9 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
escape by prepending a backslash. However, it's hard to
imagine any locale that would use digits or letters as
quotes, and set_custom_quoting is documented not to accept
- them. */
+ them. Also, a digit or a special letter would cause
+ trouble if it appeared in quote_these_too, but that's also
+ documented as not accepting them. */
break;
default:
diff --git a/lib/quotearg.h b/lib/quotearg.h
index e9f6f56..63c47f1 100644
--- a/lib/quotearg.h
+++ b/lib/quotearg.h
@@ -255,7 +255,9 @@ void set_quoting_style (struct quoting_options *o, enum
quoting_style s);
set the value of the quoting options for character C to I.
Return the old value. Currently, the only values defined for I are
0 (the default) and 1 (which means to quote the character even if
- it would not otherwise be quoted). */
+ it would not otherwise be quoted). C must never be a digit or a
+ letter that has special meaning after a backslash (for example, "\t"
+ for tab). */
int set_char_quoting (struct quoting_options *o, char c, int i);
/* In O (or in the default if O is null),
@@ -345,7 +347,8 @@ char *quotearg_style (enum quoting_style s, char const
*arg);
char *quotearg_style_mem (enum quoting_style s,
char const *arg, size_t argsize);
-/* Like quotearg (ARG), except also quote any instances of CH. */
+/* Like quotearg (ARG), except also quote any instances of CH.
+ See set_char_quoting for a description of acceptable CH values. */
char *quotearg_char (char const *arg, char ch);
/* Like quotearg_char (ARG, CH), except it can quote null bytes. */
--
1.5.4.3