use larger string heap
[rrq/fuse_xattrs.git] / stringmem.c
1 #include <stdarg.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #define BIGSTRING 1048576
6 #define STRINGSPACE ( BIGSTRING * 50 )
7
8 static struct {
9     char *base;
10     char *current;
11     char *end;
12 } heap;
13
14 static inline void strinitialize() {
15     if ( heap.base == 0 ) {
16         heap.base = (char*) malloc( STRINGSPACE );
17         heap.current = heap.base;
18         heap.end = heap.base + STRINGSPACE;
19     }
20 }
21
22 extern char *stralloc(int size) {
23     strinitialize();
24     if ( heap.current + size >= heap.end ) {
25         heap.current = heap.base;
26     }
27     char *start = heap.current;
28     heap.current += size;
29     return start;
30 }
31
32 char *strjoin(const char *first,...) {
33     va_list ap;
34     strinitialize();
35     char *start = heap.current;
36     const char *p = first;
37     size_t size = strlen( first ) + 1;
38     va_start( ap, first );
39     while ( ( p = va_arg( ap, const char* ) ) ) {
40         size += strlen( p );
41     }
42     va_end( ap );
43     if ( size > BIGSTRING ) {
44         start = (char*) malloc( size );
45     } else {
46         if ( heap.current + size >= heap.end ) {
47             heap.current = heap.base;
48         }
49         start = heap.current;
50         heap.current += size;
51     }
52     char *current = start;
53     strcpy( current, first );
54     current += strlen( first );
55     va_start( ap, first );
56     while ( ( p = va_arg( ap, const char* ) ) ) {
57         strcpy( current, p );
58         current += strlen( p );
59     }
60     va_end( ap );
61     *current = 0;
62     return start;
63 }
64
65 void strfree(char *p) {
66     if ( p < heap.base || p >= heap.end ) {
67         free( p );
68     }
69 }