1 /*
2  * Copyright (C) 1998,1999 Uwe Ohse
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  * As a special exception this source may be used as part of the
19  * SRS project by CORE/Computer Service Langenbach
20  * regardless of the copyright they choose.
21  *
22  * Contact: uwe@ohse.de
23  */
24 #ifndef UOSTR_H
25 #define UOSTR_H
26 
27 #ifndef P__
28 #define P__(x) x
29 #endif
30 #include <stddef.h>
31 
32 typedef struct uostr_t {
33 	char *data;
34 	size_t size;
35 	size_t len;
36 } uostr_t;
37 #define UOSTR_INIT {0,0,0} /* really only care about data */
38 
39 uostr_t *uostr_alloc P__((void)); /* mallocs a uostr_t and inits with 0 */
40 void uostr_free P__((uostr_t *)); /* free(uostr_t), after free(uostr_t->data) */
41 void uostr_freedata P__((uostr_t *)); /* free(uostr_t->data) */
42 void uostr_forget P__((uostr_t *)); /* get around "reusing uostr" check */
43 extern void (*uostr_xallocfn) P__((const char *)); /* called by x-functions in case of oom */
44 void uostr_xallocerr P__((const char *fn)); /* internal function, leave alone */
45 
46 /* be careful - if u->data is NULL then u->len and u->size need not to contain any information */
47 /* both are boolean: 0/NULL is "error" */
48 #define uostr_needmore(u,bytes) \
49 	(!(u)->data ? uostr_allocmore((u),(bytes)) : \
50 		(((bytes)+(u)->len>(u)->size) ? uostr_allocmore((u),(bytes)) : u))
51 #define uostr_xneedmore(u,bytes) \
52 	(!(u)->data ? uostr_allocmore((u),(bytes)) : \
53 		(((bytes)+(u)->len>(u)->size) ? uostr_allocmore((u),(bytes)) : u))
54 #define uostr_need(u,bytes) \
55 	(!(u)->data ? uostr_allocmore((u),(bytes)) : \
56 		(((bytes)>(u)->size) ? uostr_allocmore((u),(bytes)-(u)->size) : u))
57 #define uostr_xneed(u,bytes) \
58 	(!((u)->data) ? uostr_allocmore((u),(bytes)) : \
59 		(((bytes)>(u)->size) ? uostr_allocmore((u),(bytes)-(u)->size) : u))
60 uostr_t * uostr_allocmore P__((uostr_t *u, size_t bytes));
61 uostr_t * uostr_xallocmore P__((uostr_t *u, size_t bytes));
62 
63 #define UOSTR_EMPTY(x) ((x)->data?(x)->len==0:1)
64 #define UOSTR_EMPTY0(x) ((x)->data?(x)->len==1 && (x)->data[0]==0? 1: (x)->len==0 ? 1 : 0 : 1)
65 
66 
67 #define uostr_0(u) uostr_add_char(u,0)
68 #define uostr_x0(u) uostr_xadd_char(u,0)
69 
70 uostr_t *uostr_dup_cstr P__((uostr_t *,const char *)); /* strdup */
71 uostr_t *uostr_dup_cstrmulti P__((uostr_t *u,...)); /* dup first, concat rest */
72 uostr_t *uostr_dup_char P__((uostr_t *,const char)); /* char2uostr_t */
73 uostr_t *uostr_dup_uostr P__((uostr_t *,const uostr_t *));
74 uostr_t *uostr_dup_mem P__((uostr_t *,const char *, size_t len)); /* */
75 uostr_t *uostr_add_cstr P__((uostr_t *,const char *)); /* */
76 uostr_t *uostr_add_cstrmulti P__((uostr_t *u,...));
77 uostr_t *uostr_add_char P__((uostr_t *,const char)); /* */
78 uostr_t *uostr_add_uostr P__((uostr_t *,const uostr_t *)); /* */
79 uostr_t *uostr_add_mem P__((uostr_t *,const char *, size_t len)); /* */
80 
81 uostr_t *uostr_xdup_cstr P__((uostr_t *,const char *)); /* strdup */
82 uostr_t *uostr_xdup_cstrmulti P__((uostr_t *u,...)); /* dup first, concat rest */
83 uostr_t *uostr_xdup_char P__((uostr_t *,const char)); /* char2uostr_t */
84 uostr_t *uostr_xdup_uostr P__((uostr_t *,const uostr_t *));
85 uostr_t *uostr_xdup_mem P__((uostr_t *,const char *, size_t len)); /* */
86 uostr_t *uostr_xadd_cstr P__((uostr_t *,const char *)); /* */
87 uostr_t *uostr_xadd_cstrmulti P__((uostr_t *u,...));
88 uostr_t *uostr_xadd_char P__((uostr_t *,const char)); /* */
89 uostr_t *uostr_xadd_uostr P__((uostr_t *,const uostr_t *)); /* */
90 uostr_t *uostr_xadd_mem P__((uostr_t *,const char *, size_t len)); /* */
91 
92 uostr_t *uostr_cut P__((uostr_t *,long new_len)); /* !!! long, may be negativ (cut by -x chars) */
93 #define uostr_fcut(u) do {(u)->len=0; if ((u)->data) (u)->data[0]='Z';} while(0)
94 
95 
96 #endif
97