changeset 9698:2351f4d6d9f7

Quotearg part 2: add flag that can control NUL elision. * lib/quotearg.h (set_quoting_flags): New prototype. * lib/quotearg.c (struct quoting_options): Add flag field. (set_quoting_flags): New function. (quotearg_buffer_restyled): Add flags parameter. (quotearg_alloc_mem): Set the flag if length cannot be returned. (quotearg_n_options): Set the flag, since length cannot be returned. (quoting_options_from_style): Default flags correctly. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Thu, 07 Feb 2008 14:35:51 -0700
parents 6dd30e9cb2a1
children cdc5f14da027
files ChangeLog lib/quotearg.c lib/quotearg.h
diffstat 3 files changed, 86 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2008-02-07  Eric Blake  <ebb9@byu.net>
 
+	Quotearg part 2: add flag that can control NUL elision.
+	* lib/quotearg.h (set_quoting_flags): New prototype.
+	* lib/quotearg.c (struct quoting_options): Add flag field.
+	(set_quoting_flags): New function.
+	(quotearg_buffer_restyled): Add flags parameter.
+	(quotearg_alloc_mem): Set the flag if length cannot be returned.
+	(quotearg_n_options): Set the flag, since length cannot be
+	returned.
+	(quoting_options_from_style): Default flags correctly.
+
 	Quotearg part 1: more wrappers, restore quotearg_char state.
 	* lib/quotearg.h (quotearg_alloc_mem, quotearg_n_mem)
 	(quotearg_mem, quotearg_style_mem, quotearg_char_mem)
@@ -235,7 +245,7 @@
 	* lib/sha1.h: Likewise.
 
 2008-01-30  Andreas Schwab  <schwab@suse.de>
-            Bruno Haible  <bruno@clisp.org>
+	    Bruno Haible  <bruno@clisp.org>
 
 	* m4/frexpl.m4 (gl_FUNC_FREXPL_WORKS): Include <float.h> and ensure a
 	correct definition of LDBL_MIN_EXP.
@@ -340,7 +350,7 @@
 	* NEWS: Mention the change.
 
 2008-01-25  Paul Eggert  <eggert@cs.ucla.edu>
-            Bruno Haible  <bruno@clisp.org>
+	    Bruno Haible  <bruno@clisp.org>
 
 	* m4/signbit.m4 (gl_SIGNBIT): Require a macro definition. Test whether
 	the GCC builtins for signbits are present and set
@@ -476,7 +486,7 @@
 	here, since it is not a POSIX function.
 
 2008-01-14  Colin Watson  <cjwatson@debian.org>
-            Bruno Haible  <bruno@clisp.org>
+	    Bruno Haible  <bruno@clisp.org>
 
 	* m4/strsignal.m4 (gl_FUNC_STRSIGNAL): Also check whether strsignal
 	works fine; if not, set REPLACE_STRSIGNAL.
--- a/lib/quotearg.c
+++ b/lib/quotearg.c
@@ -65,6 +65,11 @@
   /* Basic quoting style.  */
   enum quoting_style style;
 
+  /* Additional flags.  Behavior is altered according to these bits:
+     0x01: Elide null bytes rather than embed them unquoted.
+   */
+  int flags;
+
   /* 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];
@@ -143,6 +148,22 @@
   return r;
 }
 
+/* In O (or in the default if O is null),
+   set the value of the quoting options flag to I.
+   Return the old value.  Currently, the only values defined for I are
+   0 (the default) and 1 (which means to elide null bytes from styles
+   that would otherwise output them unquoted).  */
+int
+set_quoting_flags (struct quoting_options *o, int i)
+{
+  int r;
+  if (!o)
+    o = &default_quoting_options;
+  r = o->flags;
+  o->flags = i;
+  return r;
+}
+
 /* MSGID approximates a quotation mark.  Return its translation if it
    has one; otherwise, return either it or "\"", depending on S.  */
 static char const *
@@ -155,8 +176,8 @@
 }
 
 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
-   argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
-   non-quoting-style part of O to control quoting.
+   argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and the
+   remaining part of O to control quoting.
    Terminate the output with a null character, and return the written
    size of the output, not counting the terminating null.
    If BUFFERSIZE is too small to store the output string, return the
@@ -164,13 +185,13 @@
    If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
 
    This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
-   ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
-   style specified by O, and O may not be null.  */
+   ARGSIZE, O), except it uses QUOTING_STYLE and FLAGS instead of the
+   quoting style specified by O, and O may not be null.  */
 
 static size_t
 quotearg_buffer_restyled (char *buffer, size_t buffersize,
 			  char const *arg, size_t argsize,
-			  enum quoting_style quoting_style,
+			  enum quoting_style quoting_style, int flags,
 			  struct quoting_options const *o)
 {
   size_t i;
@@ -267,6 +288,8 @@
 	      STORE ('0');
 	      c = '0';
 	    }
+	  else if (flags & 0x1)
+	    continue;
 	  break;
 
 	case '?':
@@ -504,7 +527,7 @@
 
  use_shell_always_quoting_style:
   return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
-				   shell_always_quoting_style, o);
+				   shell_always_quoting_style, flags, o);
 }
 
 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
@@ -524,7 +547,7 @@
   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);
+				       p->style, p->flags, p);
   errno = e;
   return r;
 }
@@ -539,17 +562,22 @@
 
 /* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
    allocated storage containing the quoted string, and store the
-   resulting size into *SIZE, if non-NULL.  If SIZE is NULL, then
-   either ARGSIZE should be -1, or O should escape or elide any
-   embedded null bytes.  */
+   resulting size into *SIZE, if non-NULL.  The result can contain
+   embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
+   NULL, and set_quoting_flags has not set the null byte elision
+   flag.  */
 char *
 quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
 		    struct quoting_options const *o)
 {
+  struct quoting_options const *p = o ? o : &default_quoting_options;
   int e = errno;
-  size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1;
+  /* Elide embedded null bytes if we can't return a size.  */
+  int flags = p->flags | (size ? 0 : 0x1);
+  size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
+					     flags, p) + 1;
   char *buf = xcharalloc (bufsize);
-  quotearg_buffer (buf, bufsize, arg, argsize, o);
+  quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags, p);
   errno = e;
   if (size)
     *size = bufsize - 1;
@@ -634,7 +662,10 @@
   {
     size_t size = sv[n].size;
     char *val = sv[n].val;
-    size_t qsize = quotearg_buffer (val, size, arg, argsize, options);
+    /* Elide embedded null bytes since we don't return a size.  */
+    size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
+					     options->style,
+					     options->flags | 0x1, options);
 
     if (size <= qsize)
       {
@@ -642,7 +673,8 @@
 	if (val != slot0)
 	  free (val);
 	sv[n].val = val = xcharalloc (size);
-	quotearg_buffer (val, size, arg, argsize, options);
+	quotearg_buffer_restyled (val, size, arg, argsize, options->style,
+				  options->flags | 0x1, options);
       }
 
     errno = e;
@@ -680,6 +712,7 @@
 {
   struct quoting_options o;
   o.style = style;
+  o.flags = 0;
   memset (o.quote_these_too, 0, sizeof o.quote_these_too);
   return o;
 }
--- a/lib/quotearg.h
+++ b/lib/quotearg.h
@@ -26,15 +26,18 @@
 /* Basic quoting styles.  */
 enum quoting_style
   {
-    /* Output names as-is (ls --quoting-style=literal).  */
+    /* Output names as-is (ls --quoting-style=literal).  Can result in
+       embedded null bytes in some cases.  */
     literal_quoting_style,
 
     /* Quote names for the shell if they contain shell metacharacters
-       or would cause ambiguous output (ls --quoting-style=shell).  */
+       or would cause ambiguous output (ls --quoting-style=shell).
+       Can result in embedded null bytes in some cases.  */
     shell_quoting_style,
 
     /* Quote names for the shell, even if they would normally not
-       require quoting (ls --quoting-style=shell-always).  */
+       require quoting (ls --quoting-style=shell-always).  Can result
+       in embedded null bytes in some cases.  */
     shell_always_quoting_style,
 
     /* Quote names as for a C language string (ls --quoting-style=c).  */
@@ -86,6 +89,13 @@
    it would not otherwise be quoted).  */
 int set_char_quoting (struct quoting_options *o, char c, int i);
 
+/* In O (or in the default if O is null),
+   set the value of the quoting options flag to I.
+   Return the old value.  Currently, the only values defined for I are
+   0 (the default) and 1 (which means to elide null bytes from styles
+   that would otherwise output them unquoted).  */
+int set_quoting_flags (struct quoting_options *o, int i);
+
 /* 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.
@@ -93,22 +103,26 @@
    size of the output, not counting the terminating null.
    If BUFFERSIZE is too small to store the output string, return the
    value that would have been returned had BUFFERSIZE been large enough.
-   If ARGSIZE is -1, use the string length of the argument for ARGSIZE.  */
+   If ARGSIZE is -1, use the string length of the argument for ARGSIZE.
+   On output, BUFFER might contain embedded null bytes if ARGSIZE was
+   not -1, the style of O does not use backslash escapes, and the
+   flags of O do not request elision of null bytes.*/
 size_t quotearg_buffer (char *buffer, size_t buffersize,
 			char const *arg, size_t argsize,
 			struct quoting_options const *o);
 
 /* Like quotearg_buffer, except return the result in a newly allocated
-   buffer.  It is the caller's responsibility to free the result.
-   Either ARGSIZE should be -1, or O should not permit embedded null
-   bytes in the output.  */
+   buffer.  It is the caller's responsibility to free the result.  The
+   result will not contain embedded null bytes.  */
 char *quotearg_alloc (char const *arg, size_t argsize,
 		      struct quoting_options const *o);
 
 /* Like quotearg_alloc, except that the length of the result,
    excluding the terminating null byte, is stored into SIZE if it is
-   non-NULL.  Thus, this can be safe to use even when O specifies
-   embedded null bytes.  */
+   non-NULL.  The result might contain embedded null bytes if ARGSIZE
+   was not -1, SIZE was not NULL, the style of O does not use
+   backslash escapes, and the flags of O do not request elision of
+   null bytes.*/
 char *quotearg_alloc_mem (char const *arg, size_t argsize,
 			  size_t *size, struct quoting_options const *o);
 
@@ -116,7 +130,9 @@
    Use the default quoting options.
    The returned value points to static storage that can be
    reused by the next call to this function with the same value of N.
-   N must be nonnegative.  */
+   N must be nonnegative.  The output of all functions in the
+   quotearg_n family are guaranteed to not contain embedded null
+   bytes.*/
 char *quotearg_n (int n, char const *arg);
 
 /* Equivalent to quotearg_n (0, ARG).  */