blob: 2bdaa9c213ba9b69f2581c2a1d066e5395a54526 (
plain)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
/*
* Copyright (c) 2026, Chloe M.
* Provided under the BSD-3 clause
*/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "cescal/ptrbox.h"
/*
* Allocate a pointer box entry to be used
*/
static struct ptrbox_entry *
ptrbox_alloc_entry(void)
{
struct ptrbox_entry *entry;
if ((entry = malloc(sizeof(*entry))) == NULL) {
return NULL;
}
entry->data = NULL;
entry->next = NULL;
return entry;
}
static int
ptrbox_push_entry(struct ptrbox *ptrbox, struct ptrbox_entry *entry)
{
if (ptrbox == NULL || entry == NULL) {
errno = EINVAL;
return -1;
}
if (ptrbox->head == NULL || ptrbox->tail == NULL) {
ptrbox->head = entry;
ptrbox->tail = entry;
} else {
ptrbox->head->next = entry;
ptrbox->head = entry;
}
return 0;
}
int
ptrbox_init(struct ptrbox *ptrbox)
{
if (ptrbox == NULL) {
errno = EINVAL;
return -1;
}
ptrbox->head = NULL;
ptrbox->tail = NULL;
return 0;
}
void *
ptrbox_alloc(struct ptrbox *ptrbox, size_t len)
{
struct ptrbox_entry *entry;
void *p;
if (ptrbox == NULL || len == 0) {
errno = EINVAL;
return NULL;
}
if ((p = malloc(len)) == NULL) {
return NULL;
}
if ((entry = ptrbox_alloc_entry()) == NULL) {
free(p);
return NULL;
}
entry->data = p;
if (ptrbox_push_entry(ptrbox, entry) < 0) {
free(p);
free(entry);
return NULL;
}
return 0;
}
char *
ptrbox_strdup(struct ptrbox *ptrbox, const char *s)
{
char *sdup;
size_t slen;
if (ptrbox == NULL || s == NULL) {
errno = EINVAL;
return NULL;
}
slen = strlen(s) + 1;
if ((sdup = ptrbox_alloc(ptrbox, slen)) == NULL) {
return NULL;
}
memcpy(sdup, s, slen);
return sdup;
}
void
ptrbox_destroy(struct ptrbox *ptrbox)
{
struct ptrbox_entry *entry, *tmp;
if (ptrbox == NULL) {
return;
}
if ((entry = ptrbox->tail) == NULL) {
return;
}
while (entry != NULL) {
tmp = entry;
entry = entry->next;
free(tmp->data);
free(tmp);
}
}
|