On Tue, May 09, 2023 at 01:18:13PM -0500, Eric Blake wrote:
On Tue, May 09, 2023 at 03:51:18PM +0100, 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(+)
>
> +
> +/* 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);
ascii_isprint('\\') returns true, which means you output just one
backslash; but that's one where you really want to output two.
Otherwise, you can't tell the difference on the output from the
C-string input of one-byte "\a" vs. two-byte "\\a". :(
> + else {
> + switch (c) {
...
> + default:
> + fputc ('\\', fp);
> + fputc ('x', fp);
> + fputc (hexchar (c >> 4), fp);
> + fputc (hexchar (c), fp);
> + }
You mentioned in the commit message that not escaping " is
intentional; and I can live with that for this patch. But if we need
to add it in the future, it will be easier to rejigger the loop as
(abbreviated, but you get the idea):
for (i = 0; c = str[i], c != '\0'; ++i) {
switch (c) {
case '\\': fputc ('\\'); fputc ('\\'); break;
case '\a': fputc ('\\'); fputc ('a'); break;
...
default:
if (isprint (c)
fputc (c);
else {
// output \xXX
}
}
}
Yes this is a good idea anyway, I will make a change like this.
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html