Merge branch 'upstream'
[gnulib.git] / tests / test-quotearg.c
index 73bb1f9..65779ad 100644 (file)
@@ -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,122 +61,233 @@ 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 */
 
+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)
 {
@@ -214,6 +326,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 *
@@ -237,6 +353,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)
@@ -260,6 +385,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);
     }
 
@@ -274,16 +401,27 @@ 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);
 
+  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");