herb 0.7.4-aarch64-linux-gnu → 0.8.0-aarch64-linux-gnu
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +8 -5
- data/config.yml +40 -20
- data/ext/herb/error_helpers.c +57 -3
- data/ext/herb/error_helpers.h +1 -1
- data/ext/herb/extconf.rb +1 -0
- data/ext/herb/extension.c +10 -24
- data/ext/herb/extension_helpers.c +12 -18
- data/ext/herb/extension_helpers.h +4 -4
- data/ext/herb/nodes.c +72 -37
- data/herb.gemspec +0 -2
- data/lib/herb/3.0/herb.so +0 -0
- data/lib/herb/3.1/herb.so +0 -0
- data/lib/herb/3.2/herb.so +0 -0
- data/lib/herb/3.3/herb.so +0 -0
- data/lib/herb/3.4/herb.so +0 -0
- data/lib/herb/ast/helpers.rb +11 -0
- data/lib/herb/ast/node.rb +15 -6
- data/lib/herb/ast/nodes.rb +609 -392
- data/lib/herb/cli.rb +31 -0
- data/lib/herb/colors.rb +82 -0
- data/lib/herb/engine/compiler.rb +140 -14
- data/lib/herb/engine/debug_visitor.rb +1 -5
- data/lib/herb/engine/parser_error_overlay.rb +1 -1
- data/lib/herb/engine.rb +18 -20
- data/lib/herb/errors.rb +166 -56
- data/lib/herb/location.rb +2 -2
- data/lib/herb/project.rb +86 -21
- data/lib/herb/token.rb +14 -2
- data/lib/herb/version.rb +1 -1
- data/lib/herb.rb +1 -0
- data/sig/herb/ast/helpers.rbs +3 -0
- data/sig/herb/ast/node.rbs +12 -5
- data/sig/herb/ast/nodes.rbs +124 -62
- data/sig/herb/colors.rbs +35 -0
- data/sig/herb/engine/compiler.rbs +23 -1
- data/sig/herb/errors.rbs +74 -20
- data/sig/herb/token.rbs +8 -0
- data/sig/herb_c_extension.rbs +1 -1
- data/sig/serialized_ast_errors.rbs +8 -0
- data/src/analyze.c +461 -249
- data/src/analyze_helpers.c +5 -0
- data/src/analyze_missing_end.c +147 -0
- data/src/analyze_transform.c +196 -0
- data/src/analyzed_ruby.c +23 -2
- data/src/ast_node.c +14 -17
- data/src/ast_nodes.c +179 -181
- data/src/ast_pretty_print.c +232 -232
- data/src/element_source.c +7 -6
- data/src/errors.c +272 -152
- data/src/extract.c +92 -34
- data/src/herb.c +37 -49
- data/src/html_util.c +34 -96
- data/src/include/analyze.h +10 -2
- data/src/include/analyze_helpers.h +3 -0
- data/src/include/analyzed_ruby.h +4 -2
- data/src/include/ast_node.h +4 -4
- data/src/include/ast_nodes.h +68 -67
- data/src/include/ast_pretty_print.h +2 -2
- data/src/include/element_source.h +3 -1
- data/src/include/errors.h +42 -26
- data/src/include/extract.h +4 -4
- data/src/include/herb.h +6 -7
- data/src/include/html_util.h +4 -5
- data/src/include/lexer.h +1 -3
- data/src/include/lexer_peek_helpers.h +21 -19
- data/src/include/lexer_struct.h +12 -10
- data/src/include/location.h +10 -13
- data/src/include/macros.h +4 -0
- data/src/include/parser.h +12 -6
- data/src/include/parser_helpers.h +26 -16
- data/src/include/position.h +3 -14
- data/src/include/pretty_print.h +38 -28
- data/src/include/prism_helpers.h +1 -1
- data/src/include/range.h +4 -13
- data/src/include/token.h +5 -11
- data/src/include/token_struct.h +2 -2
- data/src/include/utf8.h +3 -2
- data/src/include/util/hb_arena.h +31 -0
- data/src/include/util/hb_arena_debug.h +8 -0
- data/src/include/util/hb_array.h +33 -0
- data/src/include/util/hb_buffer.h +34 -0
- data/src/include/util/hb_string.h +29 -0
- data/src/include/util/hb_system.h +9 -0
- data/src/include/util.h +3 -14
- data/src/include/version.h +1 -1
- data/src/include/visitor.h +1 -1
- data/src/io.c +7 -4
- data/src/lexer.c +62 -88
- data/src/lexer_peek_helpers.c +42 -38
- data/src/location.c +9 -37
- data/src/main.c +19 -23
- data/src/parser.c +373 -313
- data/src/parser_helpers.c +60 -54
- data/src/parser_match_tags.c +316 -0
- data/src/pretty_print.c +88 -117
- data/src/prism_helpers.c +7 -7
- data/src/range.c +2 -35
- data/src/token.c +36 -87
- data/src/utf8.c +4 -4
- data/src/util/hb_arena.c +179 -0
- data/src/util/hb_arena_debug.c +237 -0
- data/src/{array.c → util/hb_array.c} +26 -27
- data/src/util/hb_buffer.c +203 -0
- data/src/util/hb_string.c +85 -0
- data/src/util/hb_system.c +30 -0
- data/src/util.c +29 -99
- data/src/visitor.c +54 -54
- data/templates/ext/herb/error_helpers.c.erb +3 -3
- data/templates/ext/herb/error_helpers.h.erb +1 -1
- data/templates/ext/herb/nodes.c.erb +11 -6
- data/templates/java/error_helpers.c.erb +75 -0
- data/templates/java/error_helpers.h.erb +20 -0
- data/templates/java/nodes.c.erb +97 -0
- data/templates/java/nodes.h.erb +23 -0
- data/templates/java/org/herb/ast/Errors.java.erb +121 -0
- data/templates/java/org/herb/ast/NodeVisitor.java.erb +14 -0
- data/templates/java/org/herb/ast/Nodes.java.erb +220 -0
- data/templates/java/org/herb/ast/Visitor.java.erb +56 -0
- data/templates/javascript/packages/core/src/visitor.ts.erb +29 -1
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +8 -8
- data/templates/javascript/packages/node/extension/error_helpers.h.erb +1 -1
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +9 -9
- data/templates/javascript/packages/node/extension/nodes.h.erb +1 -1
- data/templates/lib/herb/ast/nodes.rb.erb +28 -16
- data/templates/lib/herb/errors.rb.erb +17 -12
- data/templates/rust/src/ast/nodes.rs.erb +220 -0
- data/templates/rust/src/errors.rs.erb +216 -0
- data/templates/rust/src/nodes.rs.erb +374 -0
- data/templates/src/analyze_missing_end.c.erb +36 -0
- data/templates/src/analyze_transform.c.erb +24 -0
- data/templates/src/ast_nodes.c.erb +14 -16
- data/templates/src/ast_pretty_print.c.erb +36 -36
- data/templates/src/errors.c.erb +36 -38
- data/templates/src/include/ast_nodes.h.erb +11 -10
- data/templates/src/include/ast_pretty_print.h.erb +2 -2
- data/templates/src/include/errors.h.erb +9 -9
- data/templates/src/parser_match_tags.c.erb +38 -0
- data/templates/src/visitor.c.erb +4 -4
- data/templates/template.rb +22 -3
- data/templates/wasm/error_helpers.cpp.erb +9 -9
- data/templates/wasm/error_helpers.h.erb +1 -1
- data/templates/wasm/nodes.cpp.erb +9 -9
- data/templates/wasm/nodes.h.erb +1 -1
- data/vendor/prism/Rakefile +4 -1
- data/vendor/prism/config.yml +2 -1
- data/vendor/prism/include/prism/ast.h +31 -1
- data/vendor/prism/include/prism/diagnostic.h +1 -0
- data/vendor/prism/include/prism/version.h +3 -3
- data/vendor/prism/src/diagnostic.c +3 -1
- data/vendor/prism/src/prism.c +130 -71
- data/vendor/prism/src/util/pm_string.c +6 -8
- data/vendor/prism/templates/include/prism/ast.h.erb +2 -0
- data/vendor/prism/templates/java/org/prism/Loader.java.erb +2 -2
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +2 -2
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +2 -2
- data/vendor/prism/templates/sig/prism.rbs.erb +4 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +1 -0
- metadata +34 -21
- data/lib/herb/libherb/array.rb +0 -51
- data/lib/herb/libherb/ast_node.rb +0 -50
- data/lib/herb/libherb/buffer.rb +0 -56
- data/lib/herb/libherb/extract_result.rb +0 -20
- data/lib/herb/libherb/lex_result.rb +0 -32
- data/lib/herb/libherb/libherb.rb +0 -52
- data/lib/herb/libherb/parse_result.rb +0 -20
- data/lib/herb/libherb/token.rb +0 -46
- data/lib/herb/libherb.rb +0 -35
- data/src/buffer.c +0 -232
- data/src/include/array.h +0 -33
- data/src/include/buffer.h +0 -39
- data/src/include/json.h +0 -28
- data/src/include/memory.h +0 -12
- data/src/json.c +0 -205
- data/src/memory.c +0 -53
- data/src/position.c +0 -33
data/src/util/hb_arena.c
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#include "../include/util/hb_arena.h"
|
|
2
|
+
#include "../include/macros.h"
|
|
3
|
+
#include "../include/util/hb_system.h"
|
|
4
|
+
|
|
5
|
+
#include <assert.h>
|
|
6
|
+
#include <stdbool.h>
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
#include <string.h>
|
|
9
|
+
|
|
10
|
+
#define hb_arena_for_each_page(allocator, page) \
|
|
11
|
+
for (hb_arena_page_T* page = (allocator)->head; page != NULL; page = page->next)
|
|
12
|
+
|
|
13
|
+
static inline size_t hb_arena_align_size(size_t size, size_t alignment) {
|
|
14
|
+
assert(size <= SIZE_MAX - (alignment - 1));
|
|
15
|
+
|
|
16
|
+
return ((size + (alignment - 1)) / alignment) * alignment;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static inline bool hb_arena_page_has_capacity(hb_arena_page_T* page, size_t required_size) {
|
|
20
|
+
assert(page->position <= page->capacity);
|
|
21
|
+
|
|
22
|
+
return page->position + required_size <= page->capacity;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static inline void* hb_arena_page_alloc_from(hb_arena_page_T* page, size_t size) {
|
|
26
|
+
assert(size > 0);
|
|
27
|
+
assert(page->position + size <= page->capacity);
|
|
28
|
+
|
|
29
|
+
void* result = &page->memory[page->position];
|
|
30
|
+
page->position += size;
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static inline void hb_arena_page_reset(hb_arena_page_T* page) {
|
|
36
|
+
page->position = 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static inline void hb_arena_reset_pages_after(hb_arena_page_T* start_page) {
|
|
40
|
+
for (hb_arena_page_T* page = start_page; page != NULL; page = page->next) {
|
|
41
|
+
hb_arena_page_reset(page);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static bool hb_arena_append_page(hb_arena_T* allocator, size_t minimum_size) {
|
|
46
|
+
assert(minimum_size > 0);
|
|
47
|
+
|
|
48
|
+
size_t page_size = MAX(allocator->default_page_size, minimum_size);
|
|
49
|
+
|
|
50
|
+
assert(page_size <= SIZE_MAX - sizeof(hb_arena_page_T));
|
|
51
|
+
size_t total_size = page_size + sizeof(hb_arena_page_T);
|
|
52
|
+
|
|
53
|
+
hb_arena_page_T* page = hb_system_allocate_memory(total_size);
|
|
54
|
+
if (page == NULL) { return false; }
|
|
55
|
+
|
|
56
|
+
*page = (hb_arena_page_T) { .next = NULL, .capacity = page_size, .position = 0 };
|
|
57
|
+
|
|
58
|
+
if (allocator->head == NULL) {
|
|
59
|
+
allocator->head = page;
|
|
60
|
+
allocator->tail = page;
|
|
61
|
+
} else {
|
|
62
|
+
hb_arena_page_T* last = allocator->head;
|
|
63
|
+
|
|
64
|
+
while (last->next != NULL) {
|
|
65
|
+
last = last->next;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
last->next = page;
|
|
69
|
+
allocator->tail = page;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
bool hb_arena_init(hb_arena_T* allocator, size_t initial_size) {
|
|
76
|
+
assert(initial_size > 0);
|
|
77
|
+
|
|
78
|
+
allocator->head = NULL;
|
|
79
|
+
allocator->tail = NULL;
|
|
80
|
+
allocator->default_page_size = initial_size;
|
|
81
|
+
allocator->allocation_count = 0;
|
|
82
|
+
|
|
83
|
+
return hb_arena_append_page(allocator, initial_size);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
void* hb_arena_alloc(hb_arena_T* allocator, size_t size) {
|
|
87
|
+
assert(allocator->tail != NULL);
|
|
88
|
+
assert(size > 0);
|
|
89
|
+
|
|
90
|
+
size_t required_size = hb_arena_align_size(size, 8);
|
|
91
|
+
|
|
92
|
+
allocator->allocation_count++;
|
|
93
|
+
|
|
94
|
+
if (hb_arena_page_has_capacity(allocator->tail, required_size)) {
|
|
95
|
+
return hb_arena_page_alloc_from(allocator->tail, required_size);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (hb_arena_page_T* page = allocator->tail->next; page != NULL; page = page->next) {
|
|
99
|
+
if (hb_arena_page_has_capacity(page, required_size)) {
|
|
100
|
+
allocator->tail = page;
|
|
101
|
+
return hb_arena_page_alloc_from(allocator->tail, required_size);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
bool allocated = hb_arena_append_page(allocator, required_size);
|
|
106
|
+
|
|
107
|
+
if (!allocated) { return NULL; }
|
|
108
|
+
|
|
109
|
+
return hb_arena_page_alloc_from(allocator->tail, required_size);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
size_t hb_arena_position(hb_arena_T* allocator) {
|
|
113
|
+
size_t total = 0;
|
|
114
|
+
|
|
115
|
+
hb_arena_for_each_page(allocator, page) {
|
|
116
|
+
total += page->position;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return total;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
size_t hb_arena_capacity(hb_arena_T* allocator) {
|
|
123
|
+
size_t total = 0;
|
|
124
|
+
|
|
125
|
+
hb_arena_for_each_page(allocator, page) {
|
|
126
|
+
total += page->capacity;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return total;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
void hb_arena_reset(hb_arena_T* allocator) {
|
|
133
|
+
hb_arena_for_each_page(allocator, page) {
|
|
134
|
+
hb_arena_page_reset(page);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
allocator->tail = allocator->head;
|
|
138
|
+
allocator->allocation_count = 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
void hb_arena_reset_to(hb_arena_T* allocator, size_t target_position) {
|
|
142
|
+
if (target_position == 0) {
|
|
143
|
+
hb_arena_reset(allocator);
|
|
144
|
+
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
size_t accumulated = 0;
|
|
149
|
+
|
|
150
|
+
hb_arena_for_each_page(allocator, page) {
|
|
151
|
+
if (accumulated + page->capacity >= target_position) {
|
|
152
|
+
page->position = target_position - accumulated;
|
|
153
|
+
allocator->tail = page;
|
|
154
|
+
|
|
155
|
+
hb_arena_reset_pages_after(page->next);
|
|
156
|
+
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
accumulated += page->capacity;
|
|
161
|
+
page->position = page->capacity;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
void hb_arena_free(hb_arena_T* allocator) {
|
|
166
|
+
if (allocator->head == NULL) { return; }
|
|
167
|
+
|
|
168
|
+
for (hb_arena_page_T* current = allocator->head; current != NULL;) {
|
|
169
|
+
hb_arena_page_T* next = current->next;
|
|
170
|
+
size_t total_size = sizeof(hb_arena_page_T) + current->capacity;
|
|
171
|
+
hb_system_free_memory(current, total_size);
|
|
172
|
+
|
|
173
|
+
current = next;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
allocator->head = NULL;
|
|
177
|
+
allocator->tail = NULL;
|
|
178
|
+
allocator->default_page_size = 0;
|
|
179
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#include <stdarg.h>
|
|
2
|
+
#include <stdio.h>
|
|
3
|
+
#include <string.h>
|
|
4
|
+
|
|
5
|
+
#include "../include/util/hb_arena.h"
|
|
6
|
+
|
|
7
|
+
#define ANSI_COLOR_GREEN "\033[32m"
|
|
8
|
+
#define ANSI_COLOR_YELLOW "\033[33m"
|
|
9
|
+
#define ANSI_COLOR_RED "\033[31m"
|
|
10
|
+
#define ANSI_COLOR_RESET "\033[0m"
|
|
11
|
+
|
|
12
|
+
#define UTF8_BULLET_OVERHEAD 2
|
|
13
|
+
#define BOX_WIDTH 100
|
|
14
|
+
|
|
15
|
+
static const char* get_usage_color(double percentage) {
|
|
16
|
+
if (percentage >= 90.0) {
|
|
17
|
+
return ANSI_COLOR_RED;
|
|
18
|
+
} else if (percentage >= 70.0) {
|
|
19
|
+
return ANSI_COLOR_YELLOW;
|
|
20
|
+
} else {
|
|
21
|
+
return ANSI_COLOR_GREEN;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static void format_bytes(size_t bytes, char* buffer, size_t buffer_size) {
|
|
26
|
+
if (bytes >= 1024 * 1024) {
|
|
27
|
+
snprintf(buffer, buffer_size, "%.2f MB", bytes / (1024.0 * 1024.0));
|
|
28
|
+
} else if (bytes >= 1024) {
|
|
29
|
+
snprintf(buffer, buffer_size, "%zu KB", bytes / 1024);
|
|
30
|
+
} else {
|
|
31
|
+
snprintf(buffer, buffer_size, "%zu B", bytes);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static void print_progress_bar(size_t used, size_t capacity, int width, const char* color) {
|
|
36
|
+
int filled = (int) ((double) used / (double) capacity * width);
|
|
37
|
+
|
|
38
|
+
printf("%s[", color);
|
|
39
|
+
|
|
40
|
+
for (int i = 0; i < width; i++) {
|
|
41
|
+
if (i < filled) {
|
|
42
|
+
printf("█");
|
|
43
|
+
} else {
|
|
44
|
+
printf("░");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
printf("]%s", ANSI_COLOR_RESET);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static void print_box_top(void) {
|
|
52
|
+
printf("╔");
|
|
53
|
+
for (int i = 0; i < BOX_WIDTH; i++) {
|
|
54
|
+
printf("═");
|
|
55
|
+
}
|
|
56
|
+
printf("╗\n");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static void print_box_separator(void) {
|
|
60
|
+
printf("╠");
|
|
61
|
+
for (int i = 0; i < BOX_WIDTH; i++) {
|
|
62
|
+
printf("═");
|
|
63
|
+
}
|
|
64
|
+
printf("╣\n");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static void print_box_bottom(void) {
|
|
68
|
+
printf("╚");
|
|
69
|
+
for (int i = 0; i < BOX_WIDTH; i++) {
|
|
70
|
+
printf("═");
|
|
71
|
+
}
|
|
72
|
+
printf("╝\n");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static void print_box_line(const char* format, ...) {
|
|
76
|
+
char line[256];
|
|
77
|
+
va_list args;
|
|
78
|
+
va_start(args, format);
|
|
79
|
+
int length = vsnprintf(line, sizeof(line), format, args);
|
|
80
|
+
va_end(args);
|
|
81
|
+
|
|
82
|
+
printf("║%s%*s║\n", line, BOX_WIDTH - length, "");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static void print_box_line_centered(const char* format, ...) {
|
|
86
|
+
char line[256];
|
|
87
|
+
va_list args;
|
|
88
|
+
va_start(args, format);
|
|
89
|
+
int length = vsnprintf(line, sizeof(line), format, args);
|
|
90
|
+
va_end(args);
|
|
91
|
+
|
|
92
|
+
int total_padding = BOX_WIDTH - length;
|
|
93
|
+
int left_padding = total_padding / 2;
|
|
94
|
+
int right_padding = total_padding - left_padding;
|
|
95
|
+
|
|
96
|
+
printf("║%*s%s%*s║\n", left_padding, "", line, right_padding, "");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static void print_box_line_with_bullet(const char* format, ...) {
|
|
100
|
+
char line[256];
|
|
101
|
+
va_list args;
|
|
102
|
+
va_start(args, format);
|
|
103
|
+
int length = vsnprintf(line, sizeof(line), format, args);
|
|
104
|
+
va_end(args);
|
|
105
|
+
|
|
106
|
+
printf("║%s%*s║\n", line, BOX_WIDTH - (length - UTF8_BULLET_OVERHEAD), "");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
static void print_box_line_with_bullet_and_color(const char* color, const char* format, ...) {
|
|
110
|
+
char line[256];
|
|
111
|
+
va_list args;
|
|
112
|
+
va_start(args, format);
|
|
113
|
+
int length = vsnprintf(line, sizeof(line), format, args);
|
|
114
|
+
va_end(args);
|
|
115
|
+
|
|
116
|
+
int visual_length = length - UTF8_BULLET_OVERHEAD - (int) strlen(color) - (int) strlen(ANSI_COLOR_RESET);
|
|
117
|
+
printf("║%s%*s║\n", line, BOX_WIDTH - visual_length, "");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
void hb_arena_print_stats(const hb_arena_T* allocator) {
|
|
121
|
+
if (allocator->head == NULL) {
|
|
122
|
+
print_box_top();
|
|
123
|
+
print_box_line_centered("ARENA MEMORY LAYOUT");
|
|
124
|
+
print_box_separator();
|
|
125
|
+
print_box_line(" Arena is empty (not initialized)");
|
|
126
|
+
print_box_bottom();
|
|
127
|
+
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
size_t num_pages = 0;
|
|
132
|
+
size_t total_capacity = 0;
|
|
133
|
+
size_t total_used = 0;
|
|
134
|
+
size_t fragmentation = 0;
|
|
135
|
+
|
|
136
|
+
for (const hb_arena_page_T* page = allocator->head; page != NULL; page = page->next) {
|
|
137
|
+
num_pages++;
|
|
138
|
+
total_capacity += page->capacity;
|
|
139
|
+
total_used += page->position;
|
|
140
|
+
|
|
141
|
+
if (page != allocator->tail && page->position < page->capacity) {
|
|
142
|
+
fragmentation += (page->capacity - page->position);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
size_t total_available = total_capacity - total_used;
|
|
147
|
+
double usage_percentage = (double) total_used / (double) total_capacity * 100.0;
|
|
148
|
+
double fragmentation_percentage = (double) fragmentation / (double) total_capacity * 100.0;
|
|
149
|
+
const char* overall_color = get_usage_color(usage_percentage);
|
|
150
|
+
|
|
151
|
+
char capacity_string[32], used_string[32], available_string[32], fragmentation_string[32], default_size_string[32];
|
|
152
|
+
format_bytes(total_capacity, capacity_string, sizeof(capacity_string));
|
|
153
|
+
format_bytes(total_used, used_string, sizeof(used_string));
|
|
154
|
+
format_bytes(total_available, available_string, sizeof(available_string));
|
|
155
|
+
format_bytes(fragmentation, fragmentation_string, sizeof(fragmentation_string));
|
|
156
|
+
format_bytes(allocator->default_page_size, default_size_string, sizeof(default_size_string));
|
|
157
|
+
|
|
158
|
+
print_box_top();
|
|
159
|
+
print_box_line_centered("ARENA MEMORY LAYOUT");
|
|
160
|
+
print_box_separator();
|
|
161
|
+
print_box_line(" Statistics:");
|
|
162
|
+
|
|
163
|
+
print_box_line_with_bullet(" • Pages: %zu", num_pages);
|
|
164
|
+
print_box_line_with_bullet(" • Default Page Size: %s", default_size_string);
|
|
165
|
+
print_box_line_with_bullet(" • Total Capacity: %s", capacity_string);
|
|
166
|
+
print_box_line_with_bullet_and_color(
|
|
167
|
+
overall_color,
|
|
168
|
+
" • Total Used: %s%s%s",
|
|
169
|
+
overall_color,
|
|
170
|
+
used_string,
|
|
171
|
+
ANSI_COLOR_RESET
|
|
172
|
+
);
|
|
173
|
+
print_box_line_with_bullet(" • Total Available: %s", available_string);
|
|
174
|
+
print_box_line_with_bullet_and_color(
|
|
175
|
+
overall_color,
|
|
176
|
+
" • Usage: %s%.1f%%%s",
|
|
177
|
+
overall_color,
|
|
178
|
+
usage_percentage,
|
|
179
|
+
ANSI_COLOR_RESET
|
|
180
|
+
);
|
|
181
|
+
print_box_line_with_bullet(" • Allocations: %zu", allocator->allocation_count);
|
|
182
|
+
print_box_line_with_bullet(" • Fragmentation: %s", fragmentation_string);
|
|
183
|
+
|
|
184
|
+
if (fragmentation > 0) { print_box_line(" (%.1f%% skipped in non-tail pages)", fragmentation_percentage); }
|
|
185
|
+
|
|
186
|
+
print_box_separator();
|
|
187
|
+
|
|
188
|
+
size_t page_number = 0;
|
|
189
|
+
|
|
190
|
+
for (const hb_arena_page_T* page = allocator->head; page != NULL; page = page->next) {
|
|
191
|
+
double page_usage = (double) page->position / (double) page->capacity * 100.0;
|
|
192
|
+
const char* page_color = get_usage_color(page_usage);
|
|
193
|
+
|
|
194
|
+
char page_capacity_string[32], page_used_string[32];
|
|
195
|
+
format_bytes(page->capacity, page_capacity_string, sizeof(page_capacity_string));
|
|
196
|
+
format_bytes(page->position, page_used_string, sizeof(page_used_string));
|
|
197
|
+
|
|
198
|
+
if (page == allocator->tail) {
|
|
199
|
+
char header_line[256];
|
|
200
|
+
snprintf(header_line, sizeof(header_line), " Page %zu @ %p ← CURRENT", page_number, (void*) page);
|
|
201
|
+
int visual_length = (int) strlen(header_line) - 2;
|
|
202
|
+
printf("║%s%*s║\n", header_line, BOX_WIDTH - visual_length, "");
|
|
203
|
+
} else {
|
|
204
|
+
print_box_line(" Page %zu @ %p", page_number, (void*) page);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
char stats_line[128];
|
|
208
|
+
int stats_length =
|
|
209
|
+
snprintf(stats_line, sizeof(stats_line), "%s / %s (%.0f%%)", page_used_string, page_capacity_string, page_usage);
|
|
210
|
+
|
|
211
|
+
int bar_width = BOX_WIDTH - 4 - 2 - 2 - stats_length - 1;
|
|
212
|
+
int bar_with_brackets = bar_width + 2;
|
|
213
|
+
|
|
214
|
+
printf("║ ");
|
|
215
|
+
print_progress_bar(page->position, page->capacity, bar_width, page_color);
|
|
216
|
+
printf(" %s %*s║\n", stats_line, BOX_WIDTH - 4 - bar_with_brackets - 2 - stats_length - 1, "");
|
|
217
|
+
|
|
218
|
+
size_t unused = page->capacity - page->position;
|
|
219
|
+
|
|
220
|
+
if (unused > 0) {
|
|
221
|
+
char unused_string[32];
|
|
222
|
+
format_bytes(unused, unused_string, sizeof(unused_string));
|
|
223
|
+
|
|
224
|
+
if (page == allocator->tail) {
|
|
225
|
+
print_box_line(" Unused: %s (available for allocations)", unused_string);
|
|
226
|
+
} else {
|
|
227
|
+
print_box_line(" Unused: %s", unused_string);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
printf("║%*s║\n", BOX_WIDTH, "");
|
|
232
|
+
|
|
233
|
+
page_number++;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
print_box_bottom();
|
|
237
|
+
}
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
#include <stdint.h>
|
|
2
2
|
#include <stdio.h>
|
|
3
3
|
|
|
4
|
-
#include "include/
|
|
5
|
-
#include "include/
|
|
6
|
-
#include "include/memory.h"
|
|
4
|
+
#include "../include/macros.h"
|
|
5
|
+
#include "../include/util/hb_array.h"
|
|
7
6
|
|
|
8
|
-
size_t
|
|
9
|
-
return sizeof(
|
|
7
|
+
size_t hb_array_sizeof(void) {
|
|
8
|
+
return sizeof(hb_array_T);
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
hb_array_T* hb_array_init(const size_t capacity) {
|
|
12
|
+
hb_array_T* array = malloc(hb_array_sizeof());
|
|
14
13
|
|
|
15
14
|
array->size = 0;
|
|
16
15
|
array->capacity = capacity;
|
|
17
|
-
array->items =
|
|
16
|
+
array->items = malloc(capacity * sizeof(void*));
|
|
18
17
|
|
|
19
18
|
if (!array->items) {
|
|
20
19
|
free(array);
|
|
@@ -24,7 +23,7 @@ array_T* array_init(const size_t capacity) {
|
|
|
24
23
|
return array;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
void
|
|
26
|
+
void hb_array_append(hb_array_T* array, void* item) {
|
|
28
27
|
if (array->size >= array->capacity) {
|
|
29
28
|
size_t new_capacity;
|
|
30
29
|
|
|
@@ -45,7 +44,7 @@ void array_append(array_T* array, void* item) {
|
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
size_t new_size_bytes = new_capacity * sizeof(void*);
|
|
48
|
-
void* new_items =
|
|
47
|
+
void* new_items = realloc(array->items, new_size_bytes);
|
|
49
48
|
|
|
50
49
|
if (unlikely(new_items == NULL)) { return; }
|
|
51
50
|
|
|
@@ -57,29 +56,29 @@ void array_append(array_T* array, void* item) {
|
|
|
57
56
|
array->size++;
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
void*
|
|
59
|
+
void* hb_array_get(const hb_array_T* array, const size_t index) {
|
|
61
60
|
if (index >= array->size) { return NULL; }
|
|
62
61
|
|
|
63
62
|
return array->items[index];
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
void*
|
|
65
|
+
void* hb_array_first(hb_array_T* array) {
|
|
67
66
|
if (!array || array->size == 0) { return NULL; }
|
|
68
67
|
return array->items[0];
|
|
69
68
|
}
|
|
70
69
|
|
|
71
|
-
void*
|
|
70
|
+
void* hb_array_last(hb_array_T* array) {
|
|
72
71
|
if (!array || array->size == 0) { return NULL; }
|
|
73
72
|
return array->items[array->size - 1];
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
void
|
|
75
|
+
void hb_array_set(const hb_array_T* array, const size_t index, void* item) {
|
|
77
76
|
if (index >= array->size) { return; }
|
|
78
77
|
|
|
79
78
|
array->items[index] = item;
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
void
|
|
81
|
+
void hb_array_remove(hb_array_T* array, const size_t index) {
|
|
83
82
|
if (index >= array->size) { return; }
|
|
84
83
|
|
|
85
84
|
for (size_t i = index; i < array->size - 1; i++) {
|
|
@@ -89,7 +88,7 @@ void array_remove(array_T* array, const size_t index) {
|
|
|
89
88
|
array->size--;
|
|
90
89
|
}
|
|
91
90
|
|
|
92
|
-
size_t
|
|
91
|
+
size_t hb_array_index_of(hb_array_T* array, void* item) {
|
|
93
92
|
for (size_t i = 0; i < array->size; i++) {
|
|
94
93
|
if (array->items[i] == item) { return i; }
|
|
95
94
|
}
|
|
@@ -97,37 +96,37 @@ size_t array_index_of(array_T* array, void* item) {
|
|
|
97
96
|
return SIZE_MAX;
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
void
|
|
101
|
-
size_t index =
|
|
99
|
+
void hb_array_remove_item(hb_array_T* array, void* item) {
|
|
100
|
+
size_t index = hb_array_index_of(array, item);
|
|
102
101
|
|
|
103
|
-
if (index != SIZE_MAX) {
|
|
102
|
+
if (index != SIZE_MAX) { hb_array_remove(array, index); }
|
|
104
103
|
}
|
|
105
104
|
|
|
106
|
-
// Alias for
|
|
107
|
-
void
|
|
108
|
-
|
|
105
|
+
// Alias for hb_array_append
|
|
106
|
+
void hb_array_push(hb_array_T* array, void* item) {
|
|
107
|
+
hb_array_append(array, item);
|
|
109
108
|
}
|
|
110
109
|
|
|
111
|
-
void*
|
|
110
|
+
void* hb_array_pop(hb_array_T* array) {
|
|
112
111
|
if (!array || array->size == 0) { return NULL; }
|
|
113
112
|
|
|
114
|
-
void* last_item =
|
|
113
|
+
void* last_item = hb_array_last(array);
|
|
115
114
|
array->size--;
|
|
116
115
|
|
|
117
116
|
return last_item;
|
|
118
117
|
}
|
|
119
118
|
|
|
120
|
-
size_t
|
|
119
|
+
size_t hb_array_size(const hb_array_T* array) {
|
|
121
120
|
if (array == NULL) { return 0; }
|
|
122
121
|
|
|
123
122
|
return array->size;
|
|
124
123
|
}
|
|
125
124
|
|
|
126
|
-
size_t
|
|
125
|
+
size_t hb_array_capacity(const hb_array_T* array) {
|
|
127
126
|
return array->capacity;
|
|
128
127
|
}
|
|
129
128
|
|
|
130
|
-
void
|
|
129
|
+
void hb_array_free(hb_array_T** array) {
|
|
131
130
|
if (!array || !*array) { return; }
|
|
132
131
|
|
|
133
132
|
free((*array)->items);
|