1 /*
2 dynamicstring.c
3
4 $Id: dynamicstring.c,v 1.6 2002/12/27 21:48:25 bears Exp $
5 */
6
7 #if HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <sys/types.h>
12 #include "dynamicstring.h"
13 #include "log.h"
14 #include "portable.h"
15
16 struct DynStr
17 {
18 int len; /* Current length (without trailing '\0') */
19 int max; /* Max length that fits into buffer (incl. trailing '\0') */
20 char *str;
21 };
22
23 static void
reallocStr(DynStr * self,int max)24 reallocStr( DynStr *self, int max )
25 {
26 ASSERT( max >= 0 );
27 if ( max <= self->max )
28 return;
29 if ( ! ( self->str = (char *)realloc( self->str, (size_t)max ) ) )
30 Log_fatal( "Realloc of DynStr failed" );
31 if ( self->max == 0 ) /* First allocation? */
32 *(self->str) = '\0';
33 self->max = max;
34 }
35
36 DynStr *
new_DynStr(int reserve)37 new_DynStr( int reserve )
38 {
39 DynStr *s;
40
41 if ( ! ( s = malloc( sizeof( DynStr ) ) ) )
42 Log_fatal( "Allocation of DynStr failed" );
43 s->len = 0;
44 s->max = 0;
45 s->str = NULL;
46 if ( reserve > 0 )
47 reallocStr( s, reserve + 1 );
48 return s;
49 }
50
51 void
del_DynStr(DynStr * self)52 del_DynStr( DynStr *self )
53 {
54 if ( ! self )
55 return;
56 free( self->str );
57 self->str = NULL;
58 free( self );
59 }
60
61 int
DynStr_len(const DynStr * self)62 DynStr_len( const DynStr *self )
63 {
64 return self->len;
65 }
66
67 const char *
DynStr_str(const DynStr * self)68 DynStr_str( const DynStr *self )
69 {
70 return self->str;
71 }
72
73 void
DynStr_app(DynStr * self,const char * s)74 DynStr_app( DynStr *self, const char *s )
75 {
76 int len;
77
78 len = strlen( s );
79 if ( self->len + len + 1 > self->max )
80 reallocStr( self, self->len * 2 + len + 1 );
81 strcpy( self->str + self->len, s );
82 self->len += len;
83 }
84
85 void
DynStr_appDynStr(DynStr * self,const DynStr * s)86 DynStr_appDynStr( DynStr *self, const DynStr *s )
87 {
88 if ( self->len + s->len + 1 > self->max )
89 reallocStr( self, self->len * 2 + s->len + 1 );
90 memcpy( self->str + self->len, s->str, (size_t)s->len + 1 );
91 self->len += s->len;
92 }
93
94 void
DynStr_appLn(DynStr * self,const char * s)95 DynStr_appLn( DynStr *self, const char *s )
96 {
97 DynStr_app( self, s );
98 DynStr_app( self, "\n" );
99 }
100
101 void
DynStr_appN(DynStr * self,const char * s,int n)102 DynStr_appN( DynStr *self, const char *s, int n )
103 {
104 int len = self->len;
105
106 ASSERT( n >= 0 );
107 if ( len + n + 1 > self->max )
108 reallocStr( self, len * 2 + n + 1 );
109 strncat( self->str + len, s, (size_t)n );
110 self->len = len + strlen( self->str + len );
111 }
112
113 void
DynStr_clear(DynStr * self)114 DynStr_clear( DynStr *self )
115 {
116 self->len = 0;
117 if ( self->max > 0 )
118 *(self->str) = '\0';
119 }
120
121