[Libguestfs] [PATCH nbdkit v3 3/6] common/utils: Add C string quoting function

Richard W.M. Jones
Tue, 09 May 2023 14:51:18 -0000

eg. { '\r', '\n' } -> { '\\', 'n',
'\\', 'r' }
---
 common/utils/utils.h |  1 +
 common/utils/quote.c | 58 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/common/utils/utils.h b/common/utils/utils.h
index 42288a5cd..1e6d8972b 100644
--- a/common/utils/utils.h
+++ b/common/utils/utils.h
@@ -35,6 +35,7 @@

 extern void shell_quote (const char *str, FILE *fp);
 extern void uri_quote (const char *str, FILE *fp);
+extern void c_string_quote (const char *str, FILE *fp);
 extern int exit_status_to_nbd_error (int status, const char *cmd);
 extern int set_cloexec (int fd);
 extern int set_nonblock (int fd);
diff --git a/common/utils/quote.c b/common/utils/quote.c
index 863e08a8e..877035387 100644
--- a/common/utils/quote.c
+++ b/common/utils/quote.c
@@ -37,6 +37,9 @@
 #include <string.h>
 #include <unistd.h>

+#include "ascii-ctype.h"
+#include "hexdigit.h"
+
 /* Print str to fp, shell quoting if necessary.  This comes from
  * libguestfs, but was written by me so I'm relicensing it to a BSD
  * license for nbdkit.
@@ -98,3 +101,58 @@ uri_quote (const char *str, FILE *fp)
       fprintf (fp, "%%%02X", str[i] & 0xff);
   }
 }
+
+/* Print str to fp, quoting in a way similar to C strings, for example
+ * '\n' -> "\n".
+ *
+ * Note that we do not emit quotes around the string, and double
+ * quotes within the string are not escaped.
+ */
+void
+c_string_quote (const char *str, FILE *fp)
+{
+  size_t i;
+  char c;
+
+  for (i = 0; c = str[i], c != '\0'; ++i) {
+    if (ascii_isprint (c))
+      fputc (c, fp);
+    else {
+      switch (c) {
+      case '\a':
+        fputc ('\\', fp);
+        fputc ('a', fp);
+        break;
+      case '\b':
+        fputc ('\\', fp);
+        fputc ('b', fp);
+        break;
+      case '\f':
+        fputc ('\\', fp);
+        fputc ('f', fp);
+        break;
+      case '\n':
+        fputc ('\\', fp);
+        fputc ('n', fp);
+        break;
+      case '\r':
+        fputc ('\\', fp);
+        fputc ('r', fp);
+        break;
+      case '\t':
+        fputc ('\\', fp);
+        fputc ('t', fp);
+        break;
+      case '\v':
+        fputc ('\\', fp);
+        fputc ('v', fp);
+        break;
+      default:
+        fputc ('\\', fp);
+        fputc ('x', fp);
+        fputc (hexchar (c >> 4), fp);
+        fputc (hexchar (c), fp);
+      }
+    }
+  }
+}
--
2.39.2