7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
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
|
* compose.c contains some useful string utilities
* that libc lacks.
TODO add macro to use homebrew strlen instead of
dragging in <string.h> */
#ifdef k_header // only emit the declarations
# define fn(x)
#else
# define fn(x) x
#endif
#include <string.h>
typedef struct pstr { size_t len; union {
const char* ptr;
char* mutptr;
................................................................................
# ifndef k_static
bool heap;
# endif
size_t len;
} safestr;
#ifndef k_static
void delstr(safestr s) fn ({
if (s.heap) { free(s.mutptr); }
});
#endif
void clrstr(safestr* s) fn ({
# ifndef k_static
delstr(*s);
s->heap = false;
# endif
s->ptr = NULL;
s->len = 0;
})
size_t pstrsum(pstr* lst,size_t ct) fn({
size_t len = 0;
for (size_t i = 0; i < ct; ++i) {
if (lst[i].len == 0) {
if (lst[i].ptr == NULL) continue;
lst[i].len = strlen(lst[i].ptr);
}
len += lst[i].len;
}
return len;
})
char* pstrcoll(pstr* lst, size_t ct, char* ptr) fn({
for (size_t i = 0; i < ct; ++i) {
if (lst[i].len == 0) continue;
strncpy(ptr,lst[i].ptr,lst[i].len);
ptr += lst[i].len;
}
return ptr;
})
#ifndef k_static
char* compose(pstr* lst,size_t ct, size_t* strsz) fn({
size_t len = pstrsum(lst,ct)
if (strsz != NULL) *strsz = len;
if (len == 0) return NULL;
char* str = malloc(len + 1);
char* ptr = pstrcoll(lst, ct, ptr);
*ptr = 0;
return str;
});
#endif
char* impose(pstr* lst,size_t ct, size_t* strsz, char* buf) fn({
size_t len = pstrsum(lst,ct);
if (strsz != NULL) *strsz = len;
if (len == 0) return NULL;
char* ptr = pstrcoll(lst, ct, buf);
*ptr = 0;
return ptr;
});
char* imprint(pstr lst, size_t* strsz, char* buf) fn({
size_t len = pstrsum(&lst,1);
if (strsz != NULL) *strsz = len;
if (len == 0) return NULL;
char* ptr = pstrcoll(&lst,1,buf);
*ptr = 0;
return ptr;
});
#undef fn
|
|
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
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
|
* compose.c contains some useful string utilities
* that libc lacks.
TODO add macro to use homebrew strlen instead of
dragging in <string.h> */
#ifdef k_header // only emit the declarations
# define k_impl(x)
#else
# define k_impl(x) x
#endif
#include <string.h>
typedef struct pstr { size_t len; union {
const char* ptr;
char* mutptr;
................................................................................
# ifndef k_static
bool heap;
# endif
size_t len;
} safestr;
#ifndef k_static
void delstr(safestr s) k_impl ({
if (s.heap) { free(s.mutptr); }
});
#endif
void clrstr(safestr* s) k_impl ({
# ifndef k_static
delstr(*s);
s->heap = false;
# endif
s->ptr = NULL;
s->len = 0;
})
size_t pstrsum(pstr* lst,size_t ct) k_impl ({
size_t len = 0;
for (size_t i = 0; i < ct; ++i) {
if (lst[i].len == 0) {
if (lst[i].ptr == NULL) continue;
lst[i].len = strlen(lst[i].ptr);
}
len += lst[i].len;
}
return len;
})
char* pstrcoll(pstr* lst, size_t ct, char* ptr) k_impl ({
for (size_t i = 0; i < ct; ++i) {
if (lst[i].len == 0) continue;
strncpy(ptr,lst[i].ptr,lst[i].len);
ptr += lst[i].len;
}
return ptr;
})
#ifndef k_static
char* compose(pstr* lst,size_t ct, size_t* strsz) k_impl ({
size_t len = pstrsum(lst,ct)
if (strsz != NULL) *strsz = len;
if (len == 0) return NULL;
char* str = malloc(len + 1);
char* ptr = pstrcoll(lst, ct, ptr);
*ptr = 0;
return str;
});
#endif
char* impose(pstr* lst,size_t ct, size_t* strsz, char* buf) k_impl({
size_t len = pstrsum(lst,ct);
if (strsz != NULL) *strsz = len;
if (len == 0) return NULL;
char* ptr = pstrcoll(lst, ct, buf);
*ptr = 0;
return ptr;
});
char* imprint(pstr lst, size_t* strsz, char* buf) k_impl({
size_t len = pstrsum(&lst,1);
if (strsz != NULL) *strsz = len;
if (len == 0) return NULL;
char* ptr = pstrcoll(&lst,1,buf);
*ptr = 0;
return ptr;
});
#undef k_impl
|