chiark / gitweb /
macro: increase VA_FORMAT_ADVANCE type array and hit assert when it is reached
[elogind.git] / src / shared / macro.h
index 4595750394d8a2a5d43c68d27d46eb0d1ec55a64..dbdf5b3fb00f2d83362ab9bd5f97f9cc699b64b4 100644 (file)
@@ -187,4 +187,55 @@ static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
         return k;
 }
 
+#define _cleanup_free_ __attribute__((cleanup(freep)))
+#define _cleanup_fclose_ __attribute__((cleanup(fclosep)))
+#define _cleanup_close_ __attribute__((cleanup(closep)))
+#define _cleanup_closedir_ __attribute__((cleanup(closedirp)))
+#define _cleanup_umask_ __attribute__((cleanup(umaskp)))
+
+#define VA_FORMAT_ADVANCE(format, ap)                                   \
+do {                                                                    \
+        int _argtypes[128];                                             \
+        size_t _i, _k;                                                  \
+        _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
+        assert(_k < ELEMENTSOF(_argtypes));                             \
+        for (_i = 0; _i < _k; _i++) {                                   \
+                if (_argtypes[_i] & PA_FLAG_PTR)  {                     \
+                        (void) va_arg(ap, void*);                       \
+                        continue;                                       \
+                }                                                       \
+                                                                        \
+                switch (_argtypes[_i]) {                                \
+                case PA_INT:                                            \
+                case PA_INT|PA_FLAG_SHORT:                              \
+                case PA_CHAR:                                           \
+                        (void) va_arg(ap, int);                         \
+                        break;                                          \
+                case PA_INT|PA_FLAG_LONG:                               \
+                        (void) va_arg(ap, long int);                    \
+                        break;                                          \
+                case PA_INT|PA_FLAG_LONG_LONG:                          \
+                        (void) va_arg(ap, long long int);               \
+                        break;                                          \
+                case PA_WCHAR:                                          \
+                        (void) va_arg(ap, wchar_t);                     \
+                        break;                                          \
+                case PA_WSTRING:                                        \
+                case PA_STRING:                                         \
+                case PA_POINTER:                                        \
+                        (void) va_arg(ap, void*);                       \
+                        break;                                          \
+                case PA_FLOAT:                                          \
+                case PA_DOUBLE:                                         \
+                        (void) va_arg(ap, double);                      \
+                        break;                                          \
+                case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:                     \
+                        (void) va_arg(ap, long double);                 \
+                        break;                                          \
+                default:                                                \
+                        assert_not_reached("Unknown format string argument."); \
+                }                                                       \
+        }                                                               \
+} while(false)
+
 #include "log.h"