sysdeps: Add support for vfprintf() logging am: 597efcd89c am: 921eca660f am: a0000e9544 am: de34939838

Original change: https://android-review.googlesource.com/c/platform/external/avb/+/2520439

Change-Id: I73bb2cffd90af80dba12eae359c3d95698b20856
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/libavb/avb_sysdeps.h b/libavb/avb_sysdeps.h
index cfc9355..b4a1e99 100644
--- a/libavb/avb_sysdeps.h
+++ b/libavb/avb_sysdeps.h
@@ -48,6 +48,7 @@
  */
 #define AVB_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
 #define AVB_ATTR_PACKED __attribute__((packed))
+#define AVB_ATTR_PRINTF(x, y) __attribute__((format(printf, x, y)))
 #define AVB_ATTR_NO_RETURN __attribute__((noreturn))
 #define AVB_ATTR_SENTINEL __attribute__((__sentinel__))
 
@@ -99,6 +100,12 @@
  */
 void avb_printv(const char* message, ...) AVB_ATTR_SENTINEL;
 
+/* Prints out a formatted string.
+ *
+ * Replaces avb_printv when AVB_USE_PRINTF_LOGS is enabled.
+ */
+void avb_printf(const char* fmt, ...) AVB_ATTR_PRINTF(1, 2);
+
 /* Aborts the program or reboots the device. */
 void avb_abort(void) AVB_ATTR_NO_RETURN;
 
diff --git a/libavb/avb_sysdeps_posix.c b/libavb/avb_sysdeps_posix.c
index e26c3ef..a954869 100644
--- a/libavb/avb_sysdeps_posix.c
+++ b/libavb/avb_sysdeps_posix.c
@@ -58,6 +58,13 @@
   abort();
 }
 
+void avb_printf(const char* fmt, ...) {
+  va_list ap;
+  va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+  va_end(ap);
+}
+
 void avb_print(const char* message) {
   fprintf(stderr, "%s", message);
 }
diff --git a/libavb/avb_util.h b/libavb/avb_util.h
index 671d39a..da638fc 100644
--- a/libavb/avb_util.h
+++ b/libavb/avb_util.h
@@ -35,9 +35,34 @@
 extern "C" {
 #endif
 
+#define AVB_CONCAT(x, y) x##y
 #define AVB_STRINGIFY(x) #x
 #define AVB_TO_STRING(x) AVB_STRINGIFY(x)
 
+#define AVB__COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, x, ...) x
+#define AVB_COUNT_ARGS(...) \
+  AVB__COUNT_ARGS(, ##__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
+
+#define AVB__REPEAT0(x)
+#define AVB__REPEAT1(x) x
+#define AVB__REPEAT2(x) AVB__REPEAT1(x) x
+#define AVB__REPEAT3(x) AVB__REPEAT2(x) x
+#define AVB__REPEAT4(x) AVB__REPEAT3(x) x
+#define AVB__REPEAT5(x) AVB__REPEAT4(x) x
+#define AVB__REPEAT6(x) AVB__REPEAT5(x) x
+#define AVB__REPEAT7(x) AVB__REPEAT6(x) x
+#define AVB__REPEAT(n, x) AVB_CONCAT(AVB__REPEAT, n)(x)
+#define AVB_REPEAT(n, x) AVB__REPEAT(n, x)
+
+#ifdef AVB_USE_PRINTF_LOGS
+#define AVB_LOG(level, message, ...)                                        \
+  avb_printf("%s:%d: " level                                                \
+             ": " AVB_REPEAT(AVB_COUNT_ARGS(message, ##__VA_ARGS__), "%s"), \
+             avb_basename(__FILE__),                                        \
+             __LINE__,                                                      \
+             message,                                                       \
+             ##__VA_ARGS__)
+#else
 #define AVB_LOG(level, message, ...)  \
   avb_printv(avb_basename(__FILE__),  \
              ":",                     \
@@ -46,6 +71,7 @@
              message,                 \
              ##__VA_ARGS__,           \
              NULL)
+#endif
 
 #ifdef AVB_ENABLE_DEBUG
 /* Aborts the program if |expr| is false.
@@ -105,11 +131,13 @@
     avb_abort();                              \
   } while (0)
 
+#ifndef AVB_USE_PRINTF_LOGS
 /* Deprecated legacy logging functions -- kept for client compatibility.
  */
 #define avb_debugv(message, ...) avb_debug(message, ##__VA_ARGS__)
 #define avb_errorv(message, ...) avb_error(message, ##__VA_ARGS__)
 #define avb_fatalv(message, ...) avb_fatal(message, ##__VA_ARGS__)
+#endif
 
 /* Converts a 16-bit unsigned integer from big-endian to host byte order. */
 uint16_t avb_be16toh(uint16_t in) AVB_ATTR_WARN_UNUSED_RESULT;
diff --git a/test/avb_sysdeps_posix_testing.cc b/test/avb_sysdeps_posix_testing.cc
index 0a6ac13..6b1f210 100644
--- a/test/avb_sysdeps_posix_testing.cc
+++ b/test/avb_sysdeps_posix_testing.cc
@@ -77,6 +77,13 @@
   va_end(ap);
 }
 
+void avb_printf(const char* fmt, ...) {
+  va_list ap;
+  va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+  va_end(ap);
+}
+
 typedef struct {
   size_t size;
   base::debug::StackTrace stack_trace;