aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/src/main.c b/src/main.c
index 667a79f..c380dda 100644
--- a/src/main.c
+++ b/src/main.c
@@ -128,11 +128,45 @@ static void sanitize_sql_str(char **str)
*str = new_str;
}
-/* TODO: add a routine for safely creating formatted string
+/* Safely create a formatted string and write it to BUF. BUF shall be a buffer
+ * of size at least SIZE. BUF can be stack-allocated. If the formatting cannot
+ * be performed, exit(3) is called. This function is not meant to be called
+ * directly: the macro strbuild should be used. The code is adapted from the
+ * make_message function of the vsnprintf(3) manual page, section "examples". */
+static void __strbuild(char *buf, int size,
+ const char *file, int line,
+ const char *fmt, ...)
+{
+ va_list ap;
+ int len;
+
+ va_start(ap, fmt);
+ len = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+
+ if (len < 0) {
+ fprintf(stderr, "%s:%d: ", file, line);
+ perror("");
+ exit(EXIT_FAILURE);
+ }
+ if (len >= size) {
+ fprintf(stderr, "%s:%d: error: not enough space, "
+ "have %d, need at least %d\n",
+ file, line,
+ size, len + 1);
+ exit(EXIT_FAILURE);
+ }
+
+ va_start(ap, fmt);
+ len = vsnprintf(buf, size, fmt, ap);
+ va_end(ap);
+
+ assert(n >= 0);
+}
- Using stack-allocated space would be nice. Sketch:
- static void strbuild(char *buf, int size, char *fmt, ...)
- Advice: read the example at the end of the vsnprintf(3) manual page. */
+/* Convenience wrapper for __strbuild. */
+#define strbuild(buf, fmt, ...) \
+ __strbuild(buf, sizeof(buf), __FILE__, __LINE__, fmt, __VA_ARGS__)
/* Compute something that identifies the content of FILE. Algorithm by Dan
Bernstein from http://www.cse.yorku.ca/~oz/hash.html via