agendafs
A filesystem for your calendar.
git clone git://mccd.space/agendafs| Log | Files | Refs | README | LICENSE | Mail | Website |
arena.c (3571B)
1 #include "arena.h"
2 #include "util.h"
3 #include <assert.h>
4 #include <libical/ical.h>
5 #include <stdarg.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 typedef void (*free_func_t)(void *);
11
12 arena *
13 create_arena(void)
14 {
15 arena *region = xmalloc(sizeof(arena));
16 region->head = NULL;
17 return region;
18 }
19
20 void
21 arena_register(arena *region, void *ptr, free_func_t free_func)
22 {
23 assert(free_func);
24 memory_block *block = xmalloc(sizeof(memory_block));
25 block->ptr = ptr;
26 block->free_func = free_func;
27 block->next = region->head;
28 region->head = block;
29 }
30
31 void *
32 rmalloc(arena *region, size_t size)
33 {
34 void *ptr = xmalloc(size);
35 arena_register(region, ptr, free);
36 return ptr;
37 }
38
39 // Copies and null terminates a string
40 char *
41 rstrndup(arena *ar, const char *src, size_t len)
42 {
43 char *buf = rmalloc(ar, len + 1);
44 memcpy(buf, src, len);
45 buf[len] = '\0';
46 return buf;
47 }
48
49 void
50 free_all(arena *region)
51 {
52 if (!region)
53 return;
54 memory_block *block = region->head;
55 while (block) {
56 memory_block *next = block->next;
57 if (block->free_func)
58 block->free_func(block->ptr);
59 free(block);
60 block = next;
61 }
62 region->head = NULL;
63 free(region);
64 }
65
66 // String functions
67 char *
68 rstrdup(arena *region, const char *str)
69 {
70 char *copy = xstrdup(str);
71 arena_register(region, copy, free);
72 return copy;
73 }
74
75 char *
76 rstrins(arena *region, const char *str, size_t offset, const char *buf,
77 size_t size)
78 {
79 size_t str_len = strlen(str);
80
81 size_t previous_new_len = (offset <= str_len) ? offset : str_len;
82
83 char *result = NULL;
84 size_t result_len = 0;
85
86 FILE *stream = open_memstream(&result, &result_len);
87 assert(stream);
88
89 fwrite(str, 1, previous_new_len, stream);
90 fwrite(buf, 1, size, stream);
91
92 fclose(stream);
93
94 arena_register(region, result, free);
95
96 return result;
97 }
98
99 int
100 rasprintf(arena *region, char **strp, const char *fmt, ...)
101 {
102 // Calculate length
103 va_list args;
104 va_start(args, fmt);
105 int len = vsnprintf(NULL, 0, fmt, args);
106 va_end(args);
107
108 if (len < 0) {
109 *strp = NULL;
110 return -1;
111 }
112
113 char *buffer = rmalloc(region, len + 1);
114 va_start(args, fmt);
115 int ret = vsnprintf(buffer, len + 1, fmt, args);
116 va_end(args);
117 if (ret < 0) {
118 *strp = NULL;
119 return -1;
120 }
121 *strp = buffer;
122 return ret;
123 }
124
125 // iCal functions
126
127 icalparser *
128 ricalparser_new(arena *region)
129 {
130 icalparser *p = icalparser_new();
131 arena_register(region, p, (void *)icalparser_free);
132 return p;
133 }
134
135 void
136 ricalcomponent_free(icalcomponent *ic)
137 {
138 if (ic)
139 icalcomponent_free(ic);
140 }
141
142 icalcomponent *
143 ricalcomponent_empty(arena *region)
144 {
145 icalcomponent *ic = NULL;
146 arena_register(region, ic, (void *)ricalcomponent_free);
147 return ic;
148 }
149
150 icalcomponent *
151 ricalcomponent_new_clone(arena *region, icalcomponent *ic)
152 {
153 icalcomponent *nic = icalcomponent_new_clone(ic);
154 arena_register(region, nic, (void *)ricalcomponent_free);
155 return nic;
156 }
157
158 icalcomponent *
159 ricalcomponent_new_from_string(arena *region, const char *ic)
160 {
161 icalcomponent *nic = icalcomponent_new_from_string(ic);
162 arena_register(region, nic, (void *)ricalcomponent_free);
163 return nic;
164 }
165
166 char *
167 ricalcomponent_as_ical_string(arena *region, icalcomponent *ic)
168 {
169 char *c = icalcomponent_as_ical_string(ic);
170 arena_register(region, c, free);
171 return c;
172 }
173
174 char *
175 ricalcomponent_as_ical_string_r(arena *region, icalcomponent *ic)
176 {
177 char *c = icalcomponent_as_ical_string_r(ic);
178 arena_register(region, c, free);
179 return c;
180 }
181
182 icalcomponent *
183 ricalcomponent_new_vcalendar(arena *region)
184 {
185 icalcomponent *new_comp = icalcomponent_new_vcalendar();
186 arena_register(region, new_comp, (void *)ricalcomponent_free);
187 return new_comp;
188 }