Last active
August 29, 2015 14:13
-
-
Save rampion/0233cf60c96dcc0220d8 to your computer and use it in GitHub Desktop.
for some reason, I was tempted to play with dependency injection in C
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
#include "depinjex.h" | |
#include <stdlib.h> | |
#include <stdio.h> | |
#ifdef ENABLE_DEPENDENCY_INJECTION | |
depinjex_dependencies_t depinjex_dependencies = { | |
._atoi = atoi, | |
._fprintf = fprintf, | |
._fizzbuzz_main = fizzbuzz_main, | |
._fizzbuzz_loop = fizzbuzz_loop, | |
._fizzbuzz = fizzbuzz | |
}; | |
# define _(f, ...) depinjex_dependencies._ ## f __VA_ARGS__ | |
#else | |
# define _(f, ...) f __VA_ARGS__ | |
#endif // ENABLE_DEPENDENCY_INJECTION | |
int fizzbuzz_main(int argc, char **argv) { | |
int const max = (argc == 2 ? _( atoi,(argv[1]) ) : 100); | |
_( fizzbuzz_loop,(max) ) ; | |
return 0; | |
} | |
void fizzbuzz_loop(int max) { | |
for (int i = 1; i <= max; i++) { | |
_( fizzbuzz,(i) ); | |
} | |
} | |
void fizzbuzz(int n) { | |
static char * fmt[4] = { "%d\n", "fizz\n", "buzz\n", "fizzbuzz\n" }; | |
_( fprintf,(_(stdout), fmt[ 2 * (n % 5 == 0) + (n % 3 == 0) ], n) ); | |
} |
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
#ifndef DEPINJEX_H | |
#define DEPINJEX_H | |
int fizzbuzz_main(int argc, char **argv); | |
void fizzbuzz_loop(int max); | |
void fizzbuzz(int n); | |
#ifdef ENABLE_DEPENDENCY_INJECTION | |
#include <stdio.h> | |
typedef struct { | |
int (*_atoi)(const char *str); | |
int (*_fprintf)(FILE *out, char const *fmt, ...); | |
FILE *_stdout; // must be initialized at runtime | |
int (*_fizzbuzz_main)(int argc, char **argv); | |
void (*_fizzbuzz_loop)(int max); | |
void (*_fizzbuzz)(int n); | |
} depinjex_dependencies_t; | |
depinjex_dependencies_t depinjex_dependencies; | |
#endif // ENABLE_DEPENDENCY_INJECTION | |
#endif // DEPINJEX_H |
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
#include "depinjex.h" | |
int main(int argc, char **argv){ | |
return fizzbuzz_main(argc,argv); | |
} |
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
fizzbuzz: depinjex.c main.c | |
gcc -o $@ $^ | |
fizzbuzz-test: depinjex.c test.c | |
gcc -DENABLE_DEPENDENCY_INJECTION -o $@ $^ | |
test: fizzbuzz-test | |
./$^ | |
clean: | |
rm -f *.o fizzbuzz fizzbuzz-test |
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
#include "depinjex.h" | |
#include <unistd.h> | |
#include <assert.h> | |
#include <stdio.h> | |
int main(int argc, char**argv){ | |
// setup fake stdout | |
int stdout_pair[2] = {}; | |
pipe(stdout_pair); | |
FILE * stdout_read = fdopen(stdout_pair[0], "r"); | |
FILE * stdout_write = fdopen(stdout_pair[1], "w"); | |
// use fake stdout in fizzbuzz_main | |
depinjex_dependencies._stdout = stdout_write; | |
// check return status of fizzbuzz_main | |
char * test_argv[2] = { "fizzbuzz", "5" }; | |
assert( 0 == fizzbuzz_main(2, test_argv) ); | |
// check output from fizzbuzz_main | |
char const * expected = "1\n2\nfizz\n4\nbuzz\n"; | |
fclose(stdout_write); | |
for (;*expected;expected++) { | |
assert( *expected == fgetc(stdout_read) ); | |
} | |
assert( EOF == fgetc(stdout_read) ); | |
fclose(stdout_read); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment