diff --git a/log.c b/log.c index 9d8508b8..a45a129b 100644 --- a/log.c +++ b/log.c @@ -235,15 +235,7 @@ void logArgv(int level, struct __sourceloc whence, const char *label, int argc, strbuf_puts(&logbuf, label); strbuf_putc(&logbuf, ' '); } - int i; - for (i = 0; i < argc; ++i) { - if (i) - strbuf_putc(&logbuf, ' '); - if (argv[i]) - strbuf_toprint_quoted(&logbuf, "\"\"", argv[i]); - else - strbuf_puts(&logbuf, "NULL"); - } + strbuf_append_argv(&logbuf, argc, argv); _log_finish(level); } } diff --git a/strbuf_helpers.c b/strbuf_helpers.c index a2f7f974..f66c25ed 100644 --- a/strbuf_helpers.c +++ b/strbuf_helpers.c @@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#include #include #ifdef HAVE_NETINET_IN_H #include @@ -112,6 +113,22 @@ strbuf strbuf_toprint_quoted(strbuf sb, const char quotes[2], const char *str) return _overrun_quote(sb, quotes ? quotes[1] : '\0', "..."); } +strbuf strbuf_path_join(strbuf sb, ...) +{ + va_list ap; + va_start(ap, sb); + const char *segment; + while ((segment = va_arg(ap, const char*))) { + if (segment[0] == '/') + strbuf_reset(sb); + else if (strbuf_len(sb) && *strbuf_substr(sb, -1) != '/') + strbuf_putc(sb, '/'); + strbuf_puts(sb, segment); + } + va_end(ap); + return sb; +} + strbuf strbuf_append_poll_events(strbuf sb, short events) { static struct { short flags; const char *name; } symbols[] = { @@ -186,6 +203,20 @@ strbuf strbuf_append_shell_quotemeta(strbuf sb, const char *word) return sb; } +strbuf strbuf_append_argv(strbuf sb, int argc, const char *const *argv) +{ + int i; + for (i = 0; i < argc; ++i) { + if (i) + strbuf_putc(sb, ' '); + if (argv[i]) + strbuf_toprint_quoted(sb, "\"\"", argv[i]); + else + strbuf_puts(sb, "NULL"); + } + return sb; +} + strbuf strbuf_append_exit_status(strbuf sb, int status) { if (WIFEXITED(status)) diff --git a/strbuf_helpers.h b/strbuf_helpers.h index 5fc49e81..12edbcc8 100644 --- a/strbuf_helpers.h +++ b/strbuf_helpers.h @@ -46,6 +46,14 @@ strbuf strbuf_toprint_quoted_len(strbuf sb, const char quotes[2], const char *bu */ strbuf strbuf_toprint_quoted(strbuf sb, const char quotes[2], const char *str); +/* Join Unix file path segments together with separator characters '/' to form + * a complete path. Any segment that starts with '/' is taken as the start of + * an absolute path, and all prior segments are discarded. + * + * @author Andrew Bettison + */ +strbuf strbuf_path_join(strbuf sb, ...); + /* Append a symbolic representation of the poll(2) event flags. * @author Andrew Bettison */ @@ -74,6 +82,13 @@ strbuf strbuf_append_shell_quote(strbuf sb, const char *word); */ strbuf strbuf_append_shell_quotemeta(strbuf sb, const char *word); +/* Append an array of nul-terminated strings as a space-separated sequence of + * quoted strings. Any NULL entry in argv[] is printed as unquoted "NULL". + * + * @author Andrew Bettison + */ +strbuf strbuf_append_argv(strbuf sb, int argc, const char *const *argv); + /* Append a textual description of a process exit status as produced by wait(2) * and waitpid(2). * @author Andrew Bettison