Last active
December 15, 2015 01:29
-
-
Save ramntry/5180798 to your computer and use it in GitHub Desktop.
true C style sample :)
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 <stdlib.h> | |
#include <stdio.h> | |
#define NUMOF_ACTIONS 16 | |
struct action { | |
void *(*a_action)(void *); | |
void *a_arg_vp; | |
void *a_res_vp; | |
struct action *a_next_p; | |
}; | |
static struct action actions[NUMOF_ACTIONS]; | |
static struct action *free_action; | |
void init_actions(void) | |
{ | |
int i; | |
for (i = 0; i < NUMOF_ACTIONS - 1; ++i) { | |
actions[i].a_next_p = &actions[i + 1]; | |
} | |
free_action = &actions[0]; | |
} | |
#define init_act_list(list) *(list) = NULL | |
void append_action(struct action **action_list, void *(*action)(void *), void *arg) | |
{ | |
struct action *next_free_action; | |
if (!free_action) { | |
fprintf(stderr, "actions pool overflow\n"); | |
exit(EXIT_FAILURE); | |
} | |
next_free_action = free_action; | |
free_action = free_action->a_next_p; | |
while (*action_list) | |
action_list = &(*action_list)->a_next_p; | |
next_free_action->a_action = action; | |
next_free_action->a_arg_vp = arg; | |
next_free_action->a_res_vp = NULL; | |
next_free_action->a_next_p = NULL; | |
*action_list = next_free_action; | |
} | |
#define add(list, action) append_action(&(list), (action), NULL) | |
void erase_act_list(struct action **action_list) | |
{ | |
struct action **last_action_pp = action_list; | |
while (*last_action_pp) | |
last_action_pp = &(*last_action_pp)->a_next_p; | |
*last_action_pp = free_action; | |
free_action = *action_list; | |
*action_list = NULL; | |
} | |
void perform_actions(struct action *action_list) | |
{ | |
while (action_list) { | |
action_list->a_res_vp = action_list->a_action(action_list->a_arg_vp); | |
action_list = action_list->a_next_p; | |
} | |
} | |
#define DECL_PRINT_ACTION(mess) \ | |
void *print_##mess(void *arg) \ | |
{ \ | |
printf(#mess); \ | |
return NULL; \ | |
} | |
#define add_prints_2(list, m1, m2) \ | |
add((list), print_##m1); \ | |
add((list), print_##m2) | |
#define add_prints_5(list, m1, m2, m3, m4, m5) \ | |
add_prints_2((list), m1, m2); \ | |
add_prints_2((list), m3, m4); \ | |
add((list), print_##m5) | |
DECL_PRINT_ACTION(hello) | |
DECL_PRINT_ACTION(world) | |
DECL_PRINT_ACTION(to) | |
DECL_PRINT_ACTION(be) | |
DECL_PRINT_ACTION(or) | |
DECL_PRINT_ACTION(not) | |
DECL_PRINT_ACTION(all) | |
DECL_PRINT_ACTION(right) | |
void *print_space(void *arg) | |
{ | |
printf(" "); | |
return arg; | |
} | |
void *print_line(void *arg) | |
{ | |
printf("\n"); | |
return arg; | |
} | |
void test(void) | |
{ | |
struct action *hw_acts; | |
struct action *hamlet_acts; | |
struct action *all_right; | |
init_act_list(&hw_acts); | |
init_act_list(&hamlet_acts); | |
init_act_list(&all_right); | |
add(hw_acts, print_hello); | |
add_prints_5(hamlet_acts, to, space, be, space, or); | |
add(hw_acts, print_space); | |
add(hamlet_acts, print_space); | |
add(hw_acts, print_world); | |
add(hamlet_acts, print_not); | |
add(hw_acts, print_line); | |
add(hamlet_acts, print_space); | |
add_prints_2(hamlet_acts, to, space); | |
add_prints_2(hamlet_acts, be, line); | |
perform_actions(hw_acts); | |
perform_actions(hamlet_acts); | |
erase_act_list(&hamlet_acts); | |
perform_actions(hw_acts); | |
perform_actions(hamlet_acts); | |
add_prints_2(all_right, all, space); | |
erase_act_list(&hamlet_acts); | |
add_prints_2(all_right, right, line); | |
perform_actions(all_right); | |
} | |
int main(void) | |
{ | |
init_actions(); | |
test(); | |
return 0; | |
} |
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
PROG_NAME = chain_of_actions | |
${PROG_NAME}: ${PROG_NAME}.c | |
cc -g -O2 -Wall -pedantic $^ -o $@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Начитался я тут что-то исходных кодов MINIX 3 и захотелось мне вбросить в мир кусок кода на няшной сишке как иллюстрацию некоторого подмножества традиций наших дедов. Что получилось - смотрите выше.
Можно пронаблюдать:
А что ещё заметили вы? (указать "программирование без пробелов" и "программирование под K&R-компиляторы" я как-то постеснялся, sorry)
UPD. Спецификаторы static перед глобальными переменными добавлены по замечанию пользователя habrahabr.ru