Improve alloca_toprint() functions

Replace "..." quoting with `...` quoting in output, to avoid slosh-escaping the
common double-quote character (") in log output.

Introduce alloca_str_toprint() function that produces an entire null-terminated
string in printable form.

Change various toprint strbuf helper functions to take two optional quote chars
instead of one mandatory.
This commit is contained in:
Andrew Bettison 2012-09-28 17:46:40 +09:30
parent d8f06d0582
commit 62f8d223ea
4 changed files with 53 additions and 24 deletions

31
log.c
View File

@ -225,7 +225,7 @@ void logArgv(int level, struct __sourceloc where, const char *label, int argc, c
if (i) if (i)
strbuf_putc(&logbuf, ' '); strbuf_putc(&logbuf, ' ');
if (argv[i]) if (argv[i])
strbuf_toprint_quoted(&logbuf, '"', argv[i]); strbuf_toprint_quoted(&logbuf, "\"\"", argv[i]);
else else
strbuf_puts(&logbuf, "NULL"); strbuf_puts(&logbuf, "NULL");
} }
@ -326,10 +326,10 @@ unsigned int debugFlagMask(const char *flagname) {
in log messages. in log messages.
@author Andrew Bettison <andrew@servalproject.com> @author Andrew Bettison <andrew@servalproject.com>
*/ */
char *toprint(char *dstStr, ssize_t dstBufSiz, const char *srcBuf, size_t srcBytes) char *toprint(char *dstStr, ssize_t dstBufSiz, const char *srcBuf, size_t srcBytes, const char quotes[2])
{ {
strbuf b = strbuf_local(dstStr, dstBufSiz); strbuf b = strbuf_local(dstStr, dstBufSiz);
strbuf_toprint_quoted_len(b, '"', srcBuf, srcBytes); strbuf_toprint_quoted_len(b, quotes, srcBuf, srcBytes);
return dstStr; return dstStr;
} }
@ -338,9 +338,30 @@ char *toprint(char *dstStr, ssize_t dstBufSiz, const char *srcBuf, size_t srcByt
otherwise returns dstStrLen. otherwise returns dstStrLen.
@author Andrew Bettison <andrew@servalproject.com> @author Andrew Bettison <andrew@servalproject.com>
*/ */
size_t toprint_strlen(const char *srcBuf, size_t srcBytes) size_t toprint_len(const char *srcBuf, size_t srcBytes, const char quotes[2])
{ {
return strbuf_count(strbuf_toprint_quoted_len(strbuf_local(NULL, 0), '"', srcBuf, srcBytes)); return strbuf_count(strbuf_toprint_quoted_len(strbuf_local(NULL, 0), quotes, srcBuf, srcBytes));
}
/* Format a null-terminated string as a printable representation, eg: "Abc\x0b\n", for display
in log messages.
@author Andrew Bettison <andrew@servalproject.com>
*/
char *toprint_str(char *dstStr, ssize_t dstBufSiz, const char *srcStr, const char quotes[2])
{
strbuf b = strbuf_local(dstStr, dstBufSiz);
strbuf_toprint_quoted(b, quotes, srcStr);
return dstStr;
}
/* Compute the length of the string produced by toprint_str(). If dstStrLen == -1 then returns the
exact number of characters in the printable representation (excluding the terminating nul),
otherwise returns dstStrLen.
@author Andrew Bettison <andrew@servalproject.com>
*/
size_t toprint_str_len(const char *srcStr, const char quotes[2])
{
return strbuf_count(strbuf_toprint_quoted(strbuf_local(NULL, 0), quotes, srcStr));
} }
/* Read the symbolic link into the supplied buffer and add a terminating nul. Return -1 if the /* Read the symbolic link into the supplied buffer and add a terminating nul. Return -1 if the

9
log.h
View File

@ -78,13 +78,16 @@ void logMessage(int level, struct __sourceloc where, const char *fmt, ...);
void vlogMessage(int level, struct __sourceloc where, const char *fmt, va_list); void vlogMessage(int level, struct __sourceloc where, const char *fmt, va_list);
unsigned int debugFlagMask(const char *flagname); unsigned int debugFlagMask(const char *flagname);
int logDump(int level, struct __sourceloc where, char *name, unsigned char *addr, size_t len); int logDump(int level, struct __sourceloc where, char *name, unsigned char *addr, size_t len);
char *toprint(char *dstStr, ssize_t dstBufSiz, const char *srcBuf, size_t srcBytes); char *toprint(char *dstStr, ssize_t dstBufSiz, const char *srcBuf, size_t srcBytes, const char quotes[2]);
size_t toprint_strlen(const char *srcBuf, size_t srcBytes); char *toprint_str(char *dstStr, ssize_t dstBufSiz, const char *srcStr, const char quotes[2]);
size_t toprint_len(const char *srcBuf, size_t srcBytes, const char quotes[2]);
size_t toprint_str_len(const char *srcStr, const char quotes[2]);
ssize_t get_self_executable_path(char *buf, size_t len); ssize_t get_self_executable_path(char *buf, size_t len);
int log_backtrace(struct __sourceloc where); int log_backtrace(struct __sourceloc where);
void set_log_implementation(void (*log_function)(int level, struct strbuf *buf)); void set_log_implementation(void (*log_function)(int level, struct strbuf *buf));
#define alloca_toprint(dstlen,buf,len) toprint((char *)alloca((dstlen) == -1 ? toprint_strlen((buf),(len)) + 1 : (dstlen)), (dstlen), (buf), (len)) #define alloca_toprint(dstlen,buf,len) toprint((char *)alloca((dstlen) == -1 ? toprint_len((buf),(len), "``") + 1 : (dstlen)), (dstlen), (buf), (len), "``")
#define alloca_str_toprint(str) toprint_str((char *)alloca(toprint_str_len(str, "``") + 1), -1, (str), "``")
#define __HERE__ ((struct __sourceloc){ .file = __FILE__, .line = __LINE__, .function = __FUNCTION__ }) #define __HERE__ ((struct __sourceloc){ .file = __FILE__, .line = __LINE__, .function = __FUNCTION__ })
#define __NOWHERE__ ((struct __sourceloc){ .file = NULL, .line = 0, .function = NULL }) #define __NOWHERE__ ((struct __sourceloc){ .file = NULL, .line = 0, .function = NULL })

View File

@ -54,7 +54,8 @@ static strbuf inline _overrun(strbuf sb, const char *suffix)
static strbuf inline _overrun_quote(strbuf sb, char quote, const char *suffix) static strbuf inline _overrun_quote(strbuf sb, char quote, const char *suffix)
{ {
if (strbuf_overrun(sb)) { if (strbuf_overrun(sb)) {
strbuf_trunc(sb, -strlen(suffix) - 1); strbuf_trunc(sb, -strlen(suffix) - (quote ? 1 : 0));
if (quote)
strbuf_putc(sb, quote); strbuf_putc(sb, quote);
strbuf_puts(sb, suffix); strbuf_puts(sb, suffix);
} }
@ -75,30 +76,34 @@ strbuf strbuf_toprint(strbuf sb, const char *str)
return _overrun(sb, "..."); return _overrun(sb, "...");
} }
strbuf strbuf_toprint_quoted_len(strbuf sb, char quote, const char *buf, size_t len) strbuf strbuf_toprint_quoted_len(strbuf sb, const char quotes[2], const char *buf, size_t len)
{ {
strbuf_putc(sb, quote); if (quotes && quotes[0])
strbuf_putc(sb, quotes[0]);
for (; len && !strbuf_overrun(sb); ++buf, --len) for (; len && !strbuf_overrun(sb); ++buf, --len)
if (*buf == quote) { if (quotes && *buf == quotes[1]) {
strbuf_putc(sb, '\\'); strbuf_putc(sb, '\\');
strbuf_putc(sb, quote); strbuf_putc(sb, *buf);
} else } else
_toprint(sb, *buf); _toprint(sb, *buf);
strbuf_putc(sb, quote); if (quotes && quotes[1])
return _overrun_quote(sb, quote, "..."); strbuf_putc(sb, quotes[1]);
return _overrun_quote(sb, quotes ? quotes[1] : '\0', "...");
} }
strbuf strbuf_toprint_quoted(strbuf sb, char quote, const char *str) strbuf strbuf_toprint_quoted(strbuf sb, const char quotes[2], const char *str)
{ {
strbuf_putc(sb, quote); if (quotes && quotes[0])
strbuf_putc(sb, quotes[0]);
for (; *str && !strbuf_overrun(sb); ++str) for (; *str && !strbuf_overrun(sb); ++str)
if (*str == quote) { if (quotes && *str == quotes[1]) {
strbuf_putc(sb, '\\'); strbuf_putc(sb, '\\');
strbuf_putc(sb, quote); strbuf_putc(sb, *str);
} else } else
_toprint(sb, *str); _toprint(sb, *str);
strbuf_putc(sb, quote); if (quotes && quotes[1])
return _overrun_quote(sb, quote, "..."); strbuf_putc(sb, quotes[1]);
return _overrun_quote(sb, quotes ? quotes[1] : '\0', "...");
} }
strbuf strbuf_append_poll_events(strbuf sb, short events) strbuf strbuf_append_poll_events(strbuf sb, short events)

View File

@ -39,12 +39,12 @@ strbuf strbuf_toprint(strbuf sb, const char *str);
* backslash within the text. * backslash within the text.
* @author Andrew Bettison <andrew@servalproject.com> * @author Andrew Bettison <andrew@servalproject.com>
*/ */
strbuf strbuf_toprint_quoted_len(strbuf sb, char quote, const char *buf, size_t len); strbuf strbuf_toprint_quoted_len(strbuf sb, const char quotes[2], const char *buf, size_t len);
/* Equivalent to strbuf_toprint_quoted_len(sb, str, strlen(str)). /* Equivalent to strbuf_toprint_quoted_len(sb, str, strlen(str)).
* @author Andrew Bettison <andrew@servalproject.com> * @author Andrew Bettison <andrew@servalproject.com>
*/ */
strbuf strbuf_toprint_quoted(strbuf sb, char quote, const char *str); strbuf strbuf_toprint_quoted(strbuf sb, const char quotes[2], const char *str);
/* Append a symbolic representation of the poll(2) event flags. /* Append a symbolic representation of the poll(2) event flags.
* @author Andrew Bettison <andrew@servalproject.com> * @author Andrew Bettison <andrew@servalproject.com>