Skip to content

Commit a94e365

Browse files
committed
Added macros and started making pt into something more real.
This commit factors out the FOREACH macros into a separate header file and removes the simple support code from pt_test.c into pt.c.
1 parent eb2280b commit a94e365

File tree

5 files changed

+150
-78
lines changed

5 files changed

+150
-78
lines changed

macros/macros.h

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
2+
3+
#ifndef __MACROS_H__
4+
#define __MACROS_H__
5+
6+
/*
7+
* This is a collection of handy macros.
8+
*/
9+
10+
/* select one out of a list */
11+
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,NAME,...) NAME
12+
13+
#define FOREACH_PAIR_2(WHAT, WHAT_LAST, X, Y) WHAT_LAST(X,Y)
14+
#define FOREACH_PAIR_4(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FOREACH_PAIR_2(WHAT, WHAT_LAST, __VA_ARGS__)
15+
#define FOREACH_PAIR_6(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FOREACH_PAIR_4(WHAT, WHAT_LAST, __VA_ARGS__)
16+
#define FOREACH_PAIR_8(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FOREACH_PAIR_6(WHAT, WHAT_LAST, __VA_ARGS__)
17+
#define FOREACH_PAIR_10(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FOREACH_PAIR_8(WHAT, WHAT_LAST, __VA_ARGS__)
18+
#define FOREACH_PAIR_12(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FOREACH_PAIR_10(WHAT, WHAT_LAST, __VA_ARGS__)
19+
#define FOREACH_PAIR_14(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FOREACH_PAIR_12(WHAT, WHAT_LAST, __VA_ARGS__)
20+
#define FOREACH_PAIR_16(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FOREACH_PAIR_14(WHAT, WHAT_LAST, __VA_ARGS__)
21+
22+
/* run an action macro against all elements passed as arguments, handles arguments in PAIRS */
23+
#define FOREACH_PAIR(action, ...) \
24+
GET_MACRO(__VA_ARGS__,FOREACH_PAIR_16,OOPS15,FOREACH_PAIR_14,OOPS13,FOREACH_PAIR_12,OOPS11,FOREACH_PAIR_10,OOPS9,FOREACH_PAIR_8,OOPS7,FOREACH_PAIR_6,OOPS5,FOREACH_PAIR_4,OOPS3,FOREACH_PAIR_2,OOPS1,)(action,action,__VA_ARGS__)
25+
26+
/* as above, but run a second macro function against the last element in the list */
27+
#define FOREACH_PAIR_LAST(action, action_last, ...) \
28+
GET_MACRO(__VA_ARGS__,FOREACH_PAIR_16,OOPS15,FOREACH_PAIR_14,OOPS13,FOREACH_PAIR_12,OOPS11,FOREACH_PAIR_10,OOPS9,FOREACH_PAIR_8,OOPS7,FOREACH_PAIR_6,OOPS5,FOREACH_PAIR_4,OOPS3,FOREACH_PAIR_2,OOPS1,)(action,action_last,__VA_ARGS__)
29+
30+
31+
#define FOREACH_1(WHAT, WHAT_LAST, X) WHAT_LAST(X)
32+
#define FOREACH_2(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_1(WHAT, WHAT_LAST, __VA_ARGS__)
33+
#define FOREACH_3(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_2(WHAT, WHAT_LAST, __VA_ARGS__)
34+
#define FOREACH_4(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_3(WHAT, WHAT_LAST, __VA_ARGS__)
35+
#define FOREACH_5(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_4(WHAT, WHAT_LAST, __VA_ARGS__)
36+
#define FOREACH_6(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_5(WHAT, WHAT_LAST, __VA_ARGS__)
37+
#define FOREACH_7(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_6(WHAT, WHAT_LAST, __VA_ARGS__)
38+
#define FOREACH_8(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_7(WHAT, WHAT_LAST, __VA_ARGS__)
39+
#define FOREACH_9(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_8(WHAT, WHAT_LAST, __VA_ARGS__)
40+
#define FOREACH_10(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_9(WHAT, WHAT_LAST, __VA_ARGS__)
41+
#define FOREACH_11(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_10(WHAT, WHAT_LAST, __VA_ARGS__)
42+
#define FOREACH_12(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_11(WHAT, WHAT_LAST, __VA_ARGS__)
43+
#define FOREACH_13(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_12(WHAT, WHAT_LAST, __VA_ARGS__)
44+
#define FOREACH_14(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_13(WHAT, WHAT_LAST, __VA_ARGS__)
45+
#define FOREACH_15(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_14(WHAT, WHAT_LAST, __VA_ARGS__)
46+
#define FOREACH_16(WHAT, WHAT_LAST, X, ...) WHAT(X)FOREACH_15(WHAT, WHAT_LAST, __VA_ARGS__)
47+
48+
49+
/* run action macro against all elements in a list. */
50+
#define FOREACH(action, ...) \
51+
GET_MACRO(__VA_ARGS__,FOREACH_16,FOREACH_15,FOREACH_14,FOREACH_13,FOREACH_12,FOREACH_11,FOREACH_10,FOREACH_9,FOREACH_8,FOREACH_7,FOREACH_6,FOREACH_5,FOREACH_4,FOREACH_3,FOREACH_2,FOREACH_1,)(action,action,__VA_ARGS__)
52+
53+
/* run action macro against all elements in a list. Run a different macro against the last element. */
54+
#define FOREACH_LAST(action, action_last, ...) \
55+
GET_MACRO(__VA_ARGS__,FOREACH_16,FOREACH_15,FOREACH_14,FOREACH_13,FOREACH_12,FOREACH_11,FOREACH_10,FOREACH_9,FOREACH_8,FOREACH_7,FOREACH_6,FOREACH_5,FOREACH_4,FOREACH_3,FOREACH_2,FOREACH_1,)(action,action_last,__VA_ARGS__)
56+
57+
#endif

macros/macros_test.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
#include "macros.h"
3+
4+
#define ADD_COMMA(X) ADD_COMMA_1(X)
5+
#define ADD_COMMA_1(X) X,
6+
#define IDENTITY(X) IDENTITY_1(X)
7+
#define IDENTITY_1(X) X
8+
9+
int foo[] = {FOREACH_LAST(ADD_COMMA,IDENTITY, a, b, c) };
10+
11+
FOREACH(ADD_COMMA, 1, 2, 3)
12+
FOREACH(ADD_COMMA, 1, 2)
13+
FOREACH(ADD_COMMA, 1)
14+
15+
16+
#define ADD_SPACESHIP(a,b) ADD_SPACESHIP_1(a,b)
17+
#define ADD_SPACESHIP_1(a,b) a<->b
18+
19+
FOREACH_PAIR(ADD_SPACESHIP, a, b, x, y, foo, bar)
20+
FOREACH_PAIR(ADD_SPACESHIP, a, b, x, y)
21+
FOREACH_PAIR(ADD_SPACESHIP, a, b)
22+

pt/pt.c

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include "pt.h"
2+
#include "stdlib.h"
3+
4+
5+
struct pt_entry {
6+
struct pt_entry *next;
7+
void *args;
8+
void *ctx;
9+
pt_func func;
10+
};
11+
12+
13+
static struct pt_entry *pt_list = NULL;
14+
15+
int pt_schedule(pt_func func, void *args)
16+
{
17+
struct pt_entry *entry = calloc(1,sizeof(struct pt_entry));
18+
if(!entry) {
19+
//fprintf(stderr,"oops, cannot allocate new pt entry!");
20+
return -1;
21+
}
22+
23+
entry->func = func;
24+
entry->args = args;
25+
26+
entry->next = pt_list;
27+
pt_list = entry;
28+
29+
return 1;
30+
}
31+
32+
int pt_run(void)
33+
{
34+
struct pt_entry *curr = pt_list;
35+
struct pt_entry *last = NULL;
36+
37+
while(pt_list) {
38+
if(curr->func(curr->args,&curr->ctx) == PT_TERMINATE) {
39+
struct pt_entry *next = curr->next;
40+
41+
if(curr->args) free(curr->args);
42+
if(curr->ctx) free(curr->ctx);
43+
free(curr);
44+
45+
if(!last) {
46+
pt_list = next;
47+
} else {
48+
last->next = next;
49+
}
50+
51+
curr = next;
52+
} else {
53+
last = curr;
54+
curr = curr->next;
55+
}
56+
57+
if(!curr) {
58+
curr = pt_list;
59+
last = NULL;
60+
}
61+
}
62+
63+
return 1;
64+
}
65+

pt/pt.h

+6-15
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,7 @@
88
#ifndef __PT_H__
99
#define __PT_H__
1010

11-
#define FEP_2(WHAT, WHAT_LAST, X, Y) WHAT_LAST(X,Y)
12-
#define FEP_4(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FEP_2(WHAT, WHAT_LAST, __VA_ARGS__)
13-
#define FEP_6(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FEP_4(WHAT, WHAT_LAST, __VA_ARGS__)
14-
#define FEP_8(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FEP_6(WHAT, WHAT_LAST, __VA_ARGS__)
15-
#define FEP_10(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FEP_8(WHAT, WHAT_LAST, __VA_ARGS__)
16-
#define FEP_12(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FEP_10(WHAT, WHAT_LAST, __VA_ARGS__)
17-
#define FEP_14(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FEP_12(WHAT, WHAT_LAST, __VA_ARGS__)
18-
#define FEP_16(WHAT, WHAT_LAST, X, Y, ...) WHAT(X,Y)FEP_14(WHAT, WHAT_LAST, __VA_ARGS__)
19-
20-
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,NAME,...) NAME
21-
#define FOREACH_PAIR(action, ...) \
22-
GET_MACRO(__VA_ARGS__,FEP_16,OOPS15,FEP_14,OOPS13,FEP_12,OOPS11,FEP_10,OOPS9,FEP_8,OOPS7,FEP_6,OOPS5,FEP_4,OOPS3,FEP_2,OOPS1,)(action,action,__VA_ARGS__)
23-
#define FOREACH_PAIR_LAST(action, action_last, ...) \
24-
GET_MACRO(__VA_ARGS__,FEP_16,OOPS15,FEP_14,OOPS13,FEP_12,OOPS11,FEP_10,OOPS9,FEP_8,OOPS7,FEP_6,OOPS5,FEP_4,OOPS3,FEP_2,OOPS1,)(action,action_last,__VA_ARGS__)
25-
11+
#include "../macros/macros.h"
2612

2713
typedef void *pt_context_p;
2814

@@ -84,6 +70,11 @@ int PT_CONCAT(pt_func_,name)(void *args_arg, void **ctx_arg) { \
8470
#define PT_WAIT_WHILE(cond) do {ctx->pt_state = __LINE__; case __LINE__: if((cond)) return PT_RESUME; } while(0)
8571
#define PT_WAIT_UNTIL(cond) do {ctx->pt_state = __LINE__; case __LINE__: if(!(cond)) return PT_RESUME; } while(0)
8672

73+
typedef int (*pt_func)(void *, void **);
74+
75+
extern int pt_schedule(pt_func func, void *args);
76+
extern int pt_run(void);
77+
8778

8879

8980
#endif

pt/pt_test.c

-63
Original file line numberDiff line numberDiff line change
@@ -5,69 +5,6 @@
55
#include "pt.h"
66

77

8-
typedef int (*pt_func)(void *, void **);
9-
10-
struct pt_entry {
11-
struct pt_entry *next;
12-
void *args;
13-
void *ctx;
14-
pt_func func;
15-
};
16-
17-
18-
static struct pt_entry *pt_list = NULL;
19-
20-
int pt_schedule(pt_func func, void *args)
21-
{
22-
struct pt_entry *entry = calloc(1,sizeof(struct pt_entry));
23-
if(!entry) {
24-
fprintf(stderr,"oops, cannot allocate new pt entry!");
25-
return -1;
26-
}
27-
28-
entry->func = func;
29-
entry->args = args;
30-
31-
entry->next = pt_list;
32-
pt_list = entry;
33-
34-
return 1;
35-
}
36-
37-
int pt_run(void)
38-
{
39-
struct pt_entry *curr = pt_list;
40-
struct pt_entry *last = NULL;
41-
42-
while(pt_list) {
43-
if(curr->func(curr->args,&curr->ctx) == PT_TERMINATE) {
44-
struct pt_entry *next = curr->next;
45-
46-
if(curr->args) free(curr->args);
47-
if(curr->ctx) free(curr->ctx);
48-
free(curr);
49-
50-
if(!last) {
51-
pt_list = next;
52-
} else {
53-
last->next = next;
54-
}
55-
56-
curr = next;
57-
} else {
58-
last = curr;
59-
curr = curr->next;
60-
}
61-
62-
if(!curr) {
63-
curr = pt_list;
64-
last = NULL;
65-
}
66-
}
67-
68-
return 1;
69-
}
70-
718

729

7310

0 commit comments

Comments
 (0)