-
Notifications
You must be signed in to change notification settings - Fork 1
/
fixup.c
95 lines (78 loc) · 2.18 KB
/
fixup.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "compiler.h"
#include "helpers/vector.h"
#include <stdlib.h>
struct fixup_system *fixup_sys_new() {
struct fixup_system *system = calloc(1, sizeof(struct fixup_system));
system->fixups = vector_create(sizeof(struct fixup));
return system;
}
struct fixup_config *fixup_config(struct fixup *fixup) {
return &fixup->config;
}
void fixup_free(struct fixup *fixup) {
fixup->config.end(fixup);
free(fixup);
}
void fixup_start_iteration(struct fixup_system *system) {
vector_set_peek_pointer(system->fixups, 0);
}
struct fixup *fixup_next(struct fixup_system *system) {
return vector_peek_ptr(system->fixups);
}
void fixup_sys_fixups_free(struct fixup_system *system) {
fixup_start_iteration(system);
struct fixup *fixup = fixup_next(system);
while (fixup) {
fixup_free(fixup);
fixup = fixup_next(system);
}
}
void fixup_sys_free(struct fixup_system *system) {
fixup_sys_fixups_free(system);
vector_free(system->fixups);
free(system);
}
int fixup_sys_unresolved_count(struct fixup_system *system) {
int count = 0;
fixup_start_iteration(system);
struct fixup *fixup = fixup_next(system);
while (fixup) {
if (fixup->flags & FIXUP_FLAG_RESOLVED) {
fixup = fixup_next(system);
continue;
}
count++;
fixup = fixup_next(system);
}
return count;
}
struct fixup *fixup_register(struct fixup_system *system,
struct fixup_config *config) {
struct fixup *fixup = calloc(1, sizeof(struct fixup));
fixup->system = system;
memcpy(&fixup->config, config, sizeof(struct fixup_config));
vector_push(system->fixups, fixup);
return fixup;
}
bool fixup_resolve(struct fixup *fixup) {
if (fixup_config(fixup)->fix(fixup)) {
fixup->flags |= FIXUP_FLAG_RESOLVED;
return true;
}
return false;
}
void *fixup_private(struct fixup *fixup) {
return fixup_config(fixup)->private;
}
bool fixups_resolve(struct fixup_system *system) {
fixup_start_iteration(system);
struct fixup *fixup = fixup_next(system);
while (fixup) {
if (fixup->flags & FIXUP_FLAG_RESOLVED) {
continue;
}
fixup_resolve(fixup);
fixup = fixup_next(system);
}
return fixup_sys_unresolved_count(system) == 0;
}