Richard W.M. Jones
2023-May-09 09:51 UTC
[Libguestfs] [PATCH nbdkit v2 3/4] common/utils: Add C string quoting function
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
Laszlo Ersek
2023-May-09 12:28 UTC
[Libguestfs] [PATCH nbdkit v2 3/4] common/utils: Add C string quoting function
On 5/9/23 11:51, Richard W.M. Jones wrote:> 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) {For the controlling expression, do we like (c = str[i]) != '\0' more? Another question regarding brace style:> + 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); > + } > + } > + }In theory, we don't have to use any brace characters here except within the "switch" statement -- the "for" and "else" parts don't need braces. libnbd / nbdkit usually (?) forbids using braces unless we *must* braces. But this looks like an exception. What's the rule? (Sorry if I asked the same question before -- I don't remember exactly, but I might have. It just doesn't congeal into a consistent rule for me.) Looks OK otherwise of course. Thanks! Laszlo> +}