tools_common.h: add AOM_TOOLS_FORMAT_PRINTF
and use it to set the format attribute for printf like functions. this
allows the examples to be built with -Wformat-nonliteral without
producing warnings.
this is the same change that was applied in libvpx:
dd10ac8f6 tools_common.h: add VPX_TOOLS_FORMAT_PRINTF
Bug: webm:1744
Change-Id: I26b4c41c9a42790053b1ae0e4a678af8f2cd1d82
diff --git a/apps/aomenc.c b/apps/aomenc.c
index ad938d6..65a2684 100644
--- a/apps/aomenc.c
+++ b/apps/aomenc.c
@@ -64,8 +64,8 @@
static const char *exec_name;
-static void warn_or_exit_on_errorv(aom_codec_ctx_t *ctx, int fatal,
- const char *s, va_list ap) {
+static AOM_TOOLS_FORMAT_PRINTF(3, 0) void warn_or_exit_on_errorv(
+ aom_codec_ctx_t *ctx, int fatal, const char *s, va_list ap) {
if (ctx->err) {
const char *detail = aom_codec_error_detail(ctx);
@@ -78,7 +78,9 @@
}
}
-static void ctx_exit_on_error(aom_codec_ctx_t *ctx, const char *s, ...) {
+static AOM_TOOLS_FORMAT_PRINTF(2,
+ 3) void ctx_exit_on_error(aom_codec_ctx_t *ctx,
+ const char *s, ...) {
va_list ap;
va_start(ap, s);
@@ -86,8 +88,8 @@
va_end(ap);
}
-static void warn_or_exit_on_error(aom_codec_ctx_t *ctx, int fatal,
- const char *s, ...) {
+static AOM_TOOLS_FORMAT_PRINTF(3, 4) void warn_or_exit_on_error(
+ aom_codec_ctx_t *ctx, int fatal, const char *s, ...) {
va_list ap;
va_start(ap, s);
diff --git a/build/cmake/aom_configure.cmake b/build/cmake/aom_configure.cmake
index 43d60ae..d79cb90 100644
--- a/build/cmake/aom_configure.cmake
+++ b/build/cmake/aom_configure.cmake
@@ -275,6 +275,7 @@
add_compiler_flag_if_supported("-Wdisabled-optimization")
add_compiler_flag_if_supported("-Wextra")
add_compiler_flag_if_supported("-Wfloat-conversion")
+ add_compiler_flag_if_supported("-Wformat=2")
add_c_flag_if_supported("-Wimplicit-function-declaration")
add_compiler_flag_if_supported("-Wlogical-op")
add_compiler_flag_if_supported("-Wpointer-arith")
diff --git a/common/args.c b/common/args.c
index ed62294..e5b20e7 100644
--- a/common/args.c
+++ b/common/args.c
@@ -133,7 +133,7 @@
char err_msg[ARG_ERR_MSG_MAX_LEN];
int ret = arg_match_helper(arg_, def, argv, err_msg);
if (err_msg[0] != '\0') {
- die(err_msg);
+ die("%s", err_msg);
}
return ret;
}
@@ -194,7 +194,7 @@
char err_msg[ARG_ERR_MSG_MAX_LEN];
unsigned int ret = arg_parse_uint_helper(arg, err_msg);
if (err_msg[0] != '\0') {
- die(err_msg);
+ die("%s", err_msg);
}
return ret;
}
@@ -203,7 +203,7 @@
char err_msg[ARG_ERR_MSG_MAX_LEN];
int ret = arg_parse_int_helper(arg, err_msg);
if (err_msg[0] != '\0') {
- die(err_msg);
+ die("%s", err_msg);
}
return ret;
}
@@ -212,7 +212,7 @@
char err_msg[ARG_ERR_MSG_MAX_LEN];
struct aom_rational ret = arg_parse_rational_helper(arg, err_msg);
if (err_msg[0] != '\0') {
- die(err_msg);
+ die("%s", err_msg);
}
return ret;
}
@@ -221,7 +221,7 @@
char err_msg[ARG_ERR_MSG_MAX_LEN];
int ret = arg_parse_enum_helper(arg, err_msg);
if (err_msg[0] != '\0') {
- die(err_msg);
+ die("%s", err_msg);
}
return ret;
}
@@ -230,7 +230,7 @@
char err_msg[ARG_ERR_MSG_MAX_LEN];
int ret = arg_parse_enum_or_int_helper(arg, err_msg);
if (err_msg[0] != '\0') {
- die(err_msg);
+ die("%s", err_msg);
}
return ret;
}
@@ -241,7 +241,7 @@
char err_msg[ARG_ERR_MSG_MAX_LEN];
int ret = arg_parse_list_helper(arg, list, n, err_msg);
if (err_msg[0] != '\0') {
- die(err_msg);
+ die("%s", err_msg);
}
return ret;
}
diff --git a/common/tools_common.h b/common/tools_common.h
index f5b5b19..79348c2 100644
--- a/common/tools_common.h
+++ b/common/tools_common.h
@@ -131,12 +131,24 @@
#define AOM_NO_RETURN
#endif
+// Tells the compiler to perform `printf` format string checking if the
+// compiler supports it; see the 'format' attribute in
+// <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html>.
+#define AOM_TOOLS_FORMAT_PRINTF(string_index, first_to_check)
+#if defined(__has_attribute)
+#if __has_attribute(format)
+#undef AOM_TOOLS_FORMAT_PRINTF
+#define AOM_TOOLS_FORMAT_PRINTF(string_index, first_to_check) \
+ __attribute__((__format__(__printf__, string_index, first_to_check)))
+#endif
+#endif
+
/* Sets a stdio stream into binary mode */
FILE *set_binary_mode(FILE *stream);
-AOM_NO_RETURN void die(const char *fmt, ...);
-AOM_NO_RETURN void fatal(const char *fmt, ...);
-void aom_tools_warn(const char *fmt, ...);
+AOM_NO_RETURN void die(const char *fmt, ...) AOM_TOOLS_FORMAT_PRINTF(1, 2);
+AOM_NO_RETURN void fatal(const char *fmt, ...) AOM_TOOLS_FORMAT_PRINTF(1, 2);
+void aom_tools_warn(const char *fmt, ...) AOM_TOOLS_FORMAT_PRINTF(1, 2);
AOM_NO_RETURN void die_codec(aom_codec_ctx_t *ctx, const char *s);
diff --git a/common/warnings.c b/common/warnings.c
index 308cecd..a20531c 100644
--- a/common/warnings.c
+++ b/common/warnings.c
@@ -86,7 +86,7 @@
/* Count and print warnings. */
for (warning = warning_list.warning_node; warning != NULL;
warning = warning->next_warning, ++num_warnings) {
- aom_tools_warn(warning->warning_string);
+ aom_tools_warn("%s", warning->warning_string);
}
free_warning_list(&warning_list);
diff --git a/examples/noise_model.c b/examples/noise_model.c
index 2a40c12..27db41b 100644
--- a/examples/noise_model.c
+++ b/examples/noise_model.c
@@ -316,7 +316,7 @@
}
infile = fopen(args.input, "rb");
if (!infile) {
- die("Failed to open input file:", args.input);
+ die("Failed to open input file: %s", args.input);
}
fprintf(stderr, "Bit depth: %d stride:%d\n", args.bit_depth, raw.stride[0]);
diff --git a/examples/svc_encoder_rtc.c b/examples/svc_encoder_rtc.c
index eb8dda4..fdf8c52 100644
--- a/examples/svc_encoder_rtc.c
+++ b/examples/svc_encoder_rtc.c
@@ -1160,7 +1160,7 @@
// Y4M reader has its own allocation.
if (app_input.input_ctx.file_type != FILE_TYPE_Y4M) {
if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, width, height, 32)) {
- die("Failed to allocate image", width, height);
+ die("Failed to allocate image (%dx%d)", width, height);
}
}
diff --git a/examples/twopass_encoder.c b/examples/twopass_encoder.c
index 075eeae..b62e7a7 100644
--- a/examples/twopass_encoder.c
+++ b/examples/twopass_encoder.c
@@ -218,7 +218,7 @@
die("Invalid frame size: %dx%d", w, h);
if (!aom_img_alloc(&raw, AOM_IMG_FMT_I420, w, h, 1))
- die("Failed to allocate image", w, h);
+ die("Failed to allocate image (%dx%d)", w, h);
printf("Using %s\n", aom_codec_iface_name(encoder));
diff --git a/stats/aomstats.c b/stats/aomstats.c
index 8d59377..a006ec0 100644
--- a/stats/aomstats.c
+++ b/stats/aomstats.c
@@ -44,7 +44,7 @@
stats->buf.buf = malloc(stats->buf_alloc_sz);
if (!stats->buf.buf)
- fatal("Failed to allocate first-pass stats buffer (%lu bytes)",
+ fatal("Failed to allocate first-pass stats buffer (%u bytes)",
(unsigned int)stats->buf_alloc_sz);
nbytes = fread(stats->buf.buf, 1, stats->buf.sz, stats->file);
diff --git a/stats/rate_hist.c b/stats/rate_hist.c
index 71eb78b..d820d51 100644
--- a/stats/rate_hist.c
+++ b/stats/rate_hist.c
@@ -179,38 +179,38 @@
static void show_histogram(const struct hist_bucket *bucket, int buckets,
int total, int scale) {
- const char *pat1, *pat2;
+ int width1, width2;
int i;
switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) {
case 1:
case 2:
- pat1 = "%4d %2s: ";
- pat2 = "%4d-%2d: ";
+ width1 = 4;
+ width2 = 2;
break;
case 3:
- pat1 = "%5d %3s: ";
- pat2 = "%5d-%3d: ";
+ width1 = 5;
+ width2 = 3;
break;
case 4:
- pat1 = "%6d %4s: ";
- pat2 = "%6d-%4d: ";
+ width1 = 6;
+ width2 = 4;
break;
case 5:
- pat1 = "%7d %5s: ";
- pat2 = "%7d-%5d: ";
+ width1 = 7;
+ width2 = 5;
break;
case 6:
- pat1 = "%8d %6s: ";
- pat2 = "%8d-%6d: ";
+ width1 = 8;
+ width2 = 6;
break;
case 7:
- pat1 = "%9d %7s: ";
- pat2 = "%9d-%7d: ";
+ width1 = 9;
+ width2 = 7;
break;
default:
- pat1 = "%12d %10s: ";
- pat2 = "%12d-%10d: ";
+ width1 = 12;
+ width2 = 10;
break;
}
@@ -225,9 +225,10 @@
assert(len <= HIST_BAR_MAX);
if (bucket[i].low == bucket[i].high)
- fprintf(stderr, pat1, bucket[i].low, "");
+ fprintf(stderr, "%*d %*s: ", width1, bucket[i].low, width2, "");
else
- fprintf(stderr, pat2, bucket[i].low, bucket[i].high);
+ fprintf(stderr, "%*d-%*d: ", width1, bucket[i].low, width2,
+ bucket[i].high);
for (j = 0; j < HIST_BAR_MAX; j++) fprintf(stderr, j < len ? "=" : " ");
fprintf(stderr, "\t%5d (%6.2f%%)\n", bucket[i].count, pct);