-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfixup.c
113 lines (96 loc) · 2.19 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "fixup.h"
#include "helpers/vector.h"
#include <string.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_fixups_count(struct fixup_system* system)
{
size_t c = 0;
fixup_start_iteration(system);
struct fixup* fixup = fixup_next(system);
while (fixup)
{
if (fixup->flags & FIXUP_FLAG_RESOLVED)
{
fixup = fixup_next(system);
continue;
}
c++;
fixup = fixup_next(system);
}
return c;
}
struct fixup* fixup_register(struct fixup_system* system, struct fixup_config* config)
{
struct fixup* fixup = calloc(1, sizeof(struct fixup));
memcpy(&fixup->config, config, sizeof(struct fixup_config));
fixup->system = system;
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_fixups_count(system) == 0;
}