Sequential Function Names Using Preprocessor
I'm writing a simple unit-testing library in C to run some tests on code, and am curious if it is possible to make the process more efficient using macros/the preprocessor. Yes, I realize that I probably shouldn't be writing my own, but I would still like to know if this is possible.
Here's how I currently do it:
#include <stdio.h>
/* Each test exits with status 1 if fail */
void test_00() { ... }
void test_01() { ... }
...
void test_09() { ... }
#define NUM_TESTS 10
void (*TESTS[NUM_TESTS])() = {test_00, test_01, ..., test_09};
/* Only want to run the test number passed in on the command line */
int main(int argc, char *argv) {
int test_num = atoi(argv[1]); // Error checking in actual code
TESTS[test_num]();
}
In particular, I am interested in getting rid of the TESTS
array where I have to manually add in every new test that is made. Ideally, have it be automatically generated using NUM_TESTS
since it's honestly always repetitive.
It doesn't have to be particularly general, I won't have more than 100 tests cases so 2 digits for the test number is fine, and all the tests are named in exactly the same way.
Sorry if this question doesn't follow some guidelines. I have no reasonable attempt to show, and am at a loss for what exactly to even look for.
Answer
You could dynamically load and call the symbol at runtime by using dlsym()
.
// compile with `gcc -Wall -o test -Wl,--export-dynamic test.c -ldl`
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
/* Each test exits with status 1 if fail */
void test_00() { exit(10); }
void test_01() { exit(11); }
void test_09() { exit(19); }
/* Only want to run the test number passed in on the command line */
int main(int argc, char **argv)
{
void (*test)(void);
char symname[32];
snprintf(symname, sizeof(symname), "test_%s", argv[1]);
if ((test = dlsym(NULL, symname)) == NULL)
{
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
test();
}
Related Questions
- → OctoberCMS Backend Loging Hash Error
- → "failed to open stream" error when executing "migrate:make"
- → OctoberCMS - How to make collapsible list default to active only on non-mobile
- → Create plugin that makes objects from model in back-end
- → October CMS Plugin Routes.php not registering
- → OctoberCMS Migrate Table
- → How to install console for plugin development in October CMS
- → OctoberCMS Rain User plugin not working or redirecting
- → October CMS Custom Mail Layout
- → October CMS - How to correctly route
- → October CMS create a multi select Form field
- → How to update data attribute on Ajax complete
- → October CMS - Conditionally Load a Different Page