agendafs

A filesystem for your calendar.

git clone git://mccd.space/agendafs

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 }