This repository has been archived by the owner on Jun 11, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 102
/
Copy pathcstring.h
66 lines (51 loc) · 1.52 KB
/
cstring.h
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
#ifndef cstring_h
#define cstring_h
#include <stdint.h>
#include <stddef.h>
#define CSTRING_PERMANENT 1
#define CSTRING_INTERNING 2
#define CSTRING_ONSTACK 4
#define CSTRING_INTERNING_SIZE 32
#define CSTRING_STACK_SIZE 128
struct cstring_data {
char * cstr;
uint32_t hash_size;
uint16_t type;
uint16_t ref;
};
typedef struct _cstring_buffer {
struct cstring_data * str;
} cstring_buffer[1];
typedef struct cstring_data * cstring;
#define CSTRING_BUFFER(var) \
char var##_cstring [CSTRING_STACK_SIZE] = { '\0' }; \
struct cstring_data var##_cstring_data = { var##_cstring , 0, CSTRING_ONSTACK, 0 }; \
cstring_buffer var; \
var->str = &var##_cstring_data;
#define CSTRING_LITERAL(var, cstr) \
static cstring var = NULL; \
if (var) {} else { \
cstring tmp = cstring_persist(""cstr, (sizeof(cstr)/sizeof(char))-1); \
if (!__sync_bool_compare_and_swap(&var, NULL, tmp)) { \
cstring_free_persist(tmp); \
} \
}
#define CSTRING(s) ((s)->str)
#define CSTRING_CLOSE(var) \
if ((var)->str->type != 0) {} else \
cstring_release((var)->str);
/* low level api, don't use directly */
cstring cstring_persist(const char * cstr, size_t sz);
void cstring_free_persist(cstring s);
/* public api */
cstring cstring_grab(cstring s);
void cstring_release(cstring s);
cstring cstring_cat(cstring_buffer sb, const char * str);
cstring cstring_printf(cstring_buffer sb, const char * format, ...)
#ifdef __GNUC__
__attribute__((format(printf, 2, 3)))
#endif
;
int cstring_equal(cstring a, cstring b);
uint32_t cstring_hash(cstring s);
#endif