]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
config: typecheck initialization macros
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Fri, 1 Apr 2011 01:17:51 +0000 (18:17 -0700)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Fri, 1 Apr 2011 17:27:40 +0000 (10:27 -0700)
When initializing the config_options array, complain if the size of the
option field we're trying to initialize doesn't match the size of our
type. This will prevent careless type annotations from overwriting
neighboring option fields.

Also create a header called "static assert" which implements a
compile-time assert.

Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
src/Makefile.am
src/common/config.cc
src/common/static_assert.h [new file with mode: 0644]

index 65ba205a8a3db3279f44770381513db2f9e19673..2939ac1b8aeed69ed92cf0ae2a80d64da6559fe9 100644 (file)
@@ -776,6 +776,7 @@ noinst_HEADERS = \
        common/ceph_crypto.h\
        common/utf8.h\
        common/strtol.h\
+       common/static_assert.h\
         crush/CrushWrapper.h\
         crush/CrushWrapper.i\
         crush/builder.h\
index b7d327ffa0263a320dfce881201619f70fd9c14d..9a3a5015c85d21434425226206176212cfad36e1 100644 (file)
 
 #include "auth/Auth.h"
 #include "common/BackTrace.h"
-#include "common/ceph_argparse.h"
 #include "common/Clock.h"
 #include "common/ConfUtils.h"
 #include "common/ProfLogger.h"
+#include "common/ceph_argparse.h"
 #include "common/common_init.h"
-#include "common/dyn_snprintf.h"
-#include "common/version.h"
 #include "common/config.h"
+#include "common/dyn_snprintf.h"
+#include "common/static_assert.h"
 #include "common/strtol.h"
+#include "common/version.h"
 #include "include/atomic.h"
 #include "include/str_list.h"
 #include "include/types.h"
@@ -67,32 +68,54 @@ struct ceph_file_layout g_default_file_layout = {
 #define _STR(x) #x
 #define STRINGIFY(x) _STR(x)
 
+#define TYCHECK(x, ty) STATIC_ASSERT(sizeof(x) == sizeof(ty))
+
 #define OPTION_OPT_STR(section, name, type, def_val) \
-       { STRINGIFY(section), NULL, STRINGIFY(name), \
-     &g_conf.name, def_val, 0, 0, type }
+       { STRINGIFY(section) + TYCHECK(g_conf.name, std::string), \
+         NULL, STRINGIFY(name), \
+         &g_conf.name, def_val, 0, 0, type }
 
 #define OPTION_OPT_ADDR(section, name, type, def_val) \
-       { STRINGIFY(section), NULL, STRINGIFY(name), \
-     &g_conf.name, def_val, 0, 0, type }
+       { STRINGIFY(section) + TYCHECK(g_conf.name, entity_addr_t), \
+        NULL, STRINGIFY(name), \
+        &g_conf.name, def_val, 0, 0, type }
 
 #define OPTION_OPT_LONGLONG(section, name, type, def_val) \
-       { STRINGIFY(section), NULL, STRINGIFY(name), \
-     &g_conf.name, 0, def_val, 0, type }
-#define OPTION_OPT_U64 OPTION_OPT_LONGLONG
-#define OPTION_OPT_U32 OPTION_OPT_LONGLONG
-#define OPTION_OPT_INT OPTION_OPT_LONGLONG
-#define OPTION_OPT_BOOL OPTION_OPT_INT
+       { STRINGIFY(section) + TYCHECK(g_conf.name, long long), \
+        NULL, STRINGIFY(name), \
+         &g_conf.name, 0, def_val, 0, type }
+
+#define OPTION_OPT_INT(section, name, type, def_val) \
+       { STRINGIFY(section) + TYCHECK(g_conf.name, int), \
+        NULL, STRINGIFY(name), \
+         &g_conf.name, 0, def_val, 0, type }
+
+#define OPTION_OPT_BOOL(section, name, type, def_val) \
+       { STRINGIFY(section) + TYCHECK(g_conf.name, bool), \
+        NULL, STRINGIFY(name), \
+         &g_conf.name, 0, def_val, 0, type }
+
+#define OPTION_OPT_U32(section, name, type, def_val) \
+       { STRINGIFY(section) + TYCHECK(g_conf.name, uint32_t), \
+        NULL, STRINGIFY(name), \
+         &g_conf.name, 0, def_val, 0, type }
+
+#define OPTION_OPT_U64(section, name, type, def_val) \
+       { STRINGIFY(section) + TYCHECK(g_conf.name, uint64_t), \
+        NULL, STRINGIFY(name), \
+         &g_conf.name, 0, def_val, 0, type }
 
 #define OPTION_OPT_DOUBLE(section, name, type, def_val) \
-       { STRINGIFY(section), NULL, STRINGIFY(name), \
-     &g_conf.name, 0, 0, def_val, type }
-#define OPTION_OPT_FLOAT OPTION_OPT_DOUBLE
+       { STRINGIFY(section) + TYCHECK(g_conf.name, double), \
+        NULL, STRINGIFY(name), \
+        &g_conf.name, 0, 0, def_val, type }
 
-#define OPTION(name, type, def_val) OPTION_##type("global", name, type, def_val)
+#define OPTION_OPT_FLOAT(section, name, type, def_val) \
+       { STRINGIFY(section) + TYCHECK(g_conf.name, float), \
+        NULL, STRINGIFY(name), \
+        &g_conf.name, 0, 0, def_val, type }
 
-#define OPTION_ALT(section, conf_name, name, type, def_val) \
-       { STRINGIFY(section), NULL, STRINGIFY(conf_name), \
-         &g_conf.name, STRINGIFY(def_val), type }
+#define OPTION(name, type, def_val) OPTION_##type("global", name, type, def_val)
 
 struct config_option config_optionsp[] = {
   OPTION(host, OPT_STR, "localhost"),
diff --git a/src/common/static_assert.h b/src/common/static_assert.h
new file mode 100644 (file)
index 0000000..97f7bcb
--- /dev/null
@@ -0,0 +1,24 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#ifndef CEPH_COMMON_STATIC_ASSERT
+#define CEPH_COMMON_STATIC_ASSERT
+
+/* Create a compiler error if condition is false.
+ * Also produce a result of value 0 and type size_t.
+ * This expression can be used anywhere, even in structure initializers.
+ */
+#define STATIC_ASSERT(x) (sizeof(int[((x)==0) ? -1 : 0]))
+
+#endif