Fixed LOG_ASSERT() compilation errors in native debug builds.

Invoking LOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF variadic macros
without the printf format string arg caused compilation errors because the
variable arg list (__VA_ARGS__) was eventually passed to
__android_log_assert() func in place of a required parameter. This error
only occured in debug builds because LOG_ASSERT() is a no-op in release
builds.  This change allows debug builds to succeed.

Change-Id: I7e7b7de3e501133468ce083e0e0d6e699dd59667
Signed-off-by: Chris Pearson <christopherx.c.pearson@intel.com>
diff --git a/include/cutils/log.h b/include/cutils/log.h
index dd47c35..f602017 100644
--- a/include/cutils/log.h
+++ b/include/cutils/log.h
@@ -291,11 +291,11 @@
  */
 #define LOG_ALWAYS_FATAL_IF(cond, ...) \
     ( (CONDITION(cond)) \
-    ? ((void)android_printAssert(#cond, LOG_TAG, __VA_ARGS__)) \
+    ? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \
     : (void)0 )
 
 #define LOG_ALWAYS_FATAL(...) \
-    ( ((void)android_printAssert(NULL, LOG_TAG, __VA_ARGS__)) )
+    ( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) )
 
 /*
  * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
@@ -308,7 +308,7 @@
 
 #else
 
-#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, __VA_ARGS__)
+#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
 #define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
 
 #endif
@@ -317,7 +317,7 @@
  * Assertion that generates a log message when the assertion fails.
  * Stripped out of release builds.  Uses the current LOG_TAG.
  */
-#define LOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), __VA_ARGS__)
+#define LOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)
 //#define LOG_ASSERT(cond) LOG_FATAL_IF(!(cond), "Assertion failed: " #cond)
 
 // ---------------------------------------------------------------------
@@ -403,8 +403,24 @@
 #define android_vprintLog(prio, cond, tag, fmt...) \
     __android_log_vprint(prio, tag, fmt)
 
+/* XXX Macros to work around syntax errors in places where format string
+ * arg is not passed to LOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF
+ * (happens only in debug builds).
+ */
+
+/* Returns 2nd arg.  Used to substitute default value if caller's vararg list
+ * is empty.
+ */
+#define __android_second(dummy, second, ...)     second
+
+/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
+ * returns nothing.
+ */
+#define __android_rest(first, ...)               , ## __VA_ARGS__
+
 #define android_printAssert(cond, tag, fmt...) \
-    __android_log_assert(cond, tag, fmt)
+    __android_log_assert(cond, tag, \
+        __android_second(0, ## fmt, NULL) __android_rest(fmt))
 
 #define android_writeLog(prio, tag, text) \
     __android_log_write(prio, tag, text)
@@ -413,7 +429,7 @@
     __android_log_bwrite(tag, payload, len)
 #define android_btWriteLog(tag, type, payload, len) \
     __android_log_btwrite(tag, type, payload, len)
-	
+
 // TODO: remove these prototypes and their users
 #define android_testLog(prio, tag) (1)
 #define android_writevLog(vec,num) do{}while(0)
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index 9923bba..a0a753b 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -56,7 +56,7 @@
  * the simulator rather than a desktop tool and want to use the device.
  */
 static enum {
-    kLogUninitialized, kLogNotAvailable, kLogAvailable 
+    kLogUninitialized, kLogNotAvailable, kLogAvailable
 } g_log_status = kLogUninitialized;
 int __android_log_dev_available(void)
 {
@@ -189,7 +189,7 @@
 
 int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap)
 {
-    char buf[LOG_BUF_SIZE];    
+    char buf[LOG_BUF_SIZE];
 
     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
 
@@ -223,12 +223,23 @@
 void __android_log_assert(const char *cond, const char *tag,
 			  const char *fmt, ...)
 {
-    va_list ap;
-    char buf[LOG_BUF_SIZE];    
+    char buf[LOG_BUF_SIZE];
 
-    va_start(ap, fmt);
-    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
-    va_end(ap);
+    if (fmt) {
+        va_list ap;
+        va_start(ap, fmt);
+        vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
+        va_end(ap);
+    } else {
+        /* Msg not provided, log condition.  N.B. Do not use cond directly as
+         * format string as it could contain spurious '%' syntax (e.g.
+         * "%d" in "blocks%devs == 0").
+         */
+        if (cond)
+            snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
+        else
+            strcpy(buf, "Unspecified assertion failed");
+    }
 
     __android_log_write(ANDROID_LOG_FATAL, tag, buf);