forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib/test_map_h: add new module to test map.h macros
Build test_map_h.ko to validate MAP & MAP_LIST To test include/linux/map.h, this adds lib/test_map_h.c and config TEST_MAP_H to build test_map_h.ko. It uses BUILD_BUG_DEBUG, so that failures of the macro just break the build. So this adds config TEST_MAP_H stanza into: menu "Compile-time checks and compiler options", and fixes endmenu comment to match. avoid __i386__, __builtin_memcmp ?? do runtime tests at modprobe, including a purposeful failure and warn. default m, to maximize robot coverage. builtin doesn't add anything more. Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
- Loading branch information
Showing
3 changed files
with
106 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* test include/linux/map.h macros: MAP_LIST & MAP | ||
* | ||
* Authors: | ||
* Jim Cromie <jim.cromie@gmail.com> | ||
*/ | ||
|
||
#include <linux/map.h> | ||
#include <linux/module.h> | ||
|
||
/* compile-time test MAP */ | ||
static int sum = MAP( +, 1, 2, 3); | ||
static char* caten = MAP(__stringify, YES, NO, MAYBE); | ||
|
||
/* client/user defines enum NAMES as source of truth */ | ||
enum client_categories { DRMx_CORE, DRMx_DRIVER, DRMx_KMS }; | ||
|
||
/* test MAP_LIST(__stringify, ...). others deemed equivalent */ | ||
#define DEFINE_SLIST_FROM_ENUM_VALS_(_vec_, ...) \ | ||
const char *_vec_##_names[] = { \ | ||
MAP_LIST(__stringify, ##__VA_ARGS__) } | ||
|
||
static DEFINE_SLIST_FROM_ENUM_VALS_(debug_cats, DRMx_CORE, DRMx_DRIVER, DRMx_KMS); | ||
|
||
#if defined(__i386__) | ||
/* avoid a "__compiletime_assert_" error */ | ||
#define BUILD_BUG_STREQ(_var, ref) BUILD_BUG_ON(0) | ||
#else | ||
/* test w 2 exprs, for now */ | ||
#define BUILD_BUG_STREQ(_var, ref) do { \ | ||
BUILD_BUG_ON(__builtin_memcmp(_var, ref, sizeof(ref))); \ | ||
BUILD_BUG_ON(__builtin_memcmp(_var, ref, __builtin_strlen(ref))); \ | ||
} while (0) | ||
#endif | ||
#define BUILD_BUG_STREQ_VI(_vec_, idx, ref) \ | ||
BUILD_BUG_STREQ(_vec_##_names[idx], ref) | ||
|
||
/* force compile, even if its not called */ | ||
static void __used MAPH_BUILD_BUG(void) | ||
{ | ||
BUILD_BUG_ON(sum != 6); | ||
BUILD_BUG_STREQ(caten, "YESNOMAYBE"); | ||
|
||
BUILD_BUG_STREQ_VI(debug_cats, 0, "DRMx_CORE"); | ||
BUILD_BUG_STREQ_VI(debug_cats, 1, "DRMx_DRIVER"); | ||
BUILD_BUG_STREQ_VI(debug_cats, 2, "DRMx_KMS"); | ||
|
||
#ifdef MAPH_FORCE_FAIL | ||
/* either breaks compile */ | ||
BUILD_BUG_ON(sum != 8); | ||
BUILD_BUG_STREQ(debug_cats, 1, "'not-in-map'"); | ||
#endif | ||
} | ||
|
||
#define rTEST_eq(_v_, _ref) \ | ||
({ \ | ||
if (strcmp(_v_, _ref)) { \ | ||
pr_warn("failed: %s eq %s\n", _v_, _ref); \ | ||
} else { \ | ||
pr_debug("ok: %s eq %s\n", _v_, _ref); \ | ||
} \ | ||
}) | ||
#define rTEST_eq_VI(_v_, _i, _ref) rTEST_eq(_v_##_names[_i], _ref) | ||
|
||
static int __init test_maph_init(void) | ||
{ | ||
pr_debug("init start\n"); | ||
|
||
MAPH_BUILD_BUG(); | ||
|
||
rTEST_eq(caten, "YESNOMAYBE"); | ||
rTEST_eq_VI(debug_cats, 0, "DRMx_CORE"); | ||
rTEST_eq_VI(debug_cats, 1, "DRMx_DRIVER"); | ||
rTEST_eq_VI(debug_cats, 2, "DRMx_KMS"); | ||
|
||
/* force fail and ignore */ | ||
rTEST_eq_VI(debug_cats, 1, "'not-in-map'"); | ||
return 0; | ||
} | ||
|
||
static void __exit test_maph_exit(void) | ||
{ | ||
pr_debug("exited\n"); | ||
} | ||
|
||
module_init(test_maph_init); | ||
module_exit(test_maph_exit); | ||
|
||
MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>"); | ||
MODULE_LICENSE("GPL"); |