4 /* string builder with optional dynamic memory or static buffer. */
8 typedef struct vg_str vg_str
;
9 typedef struct vg_str_dynamic vg_str_dynamic
;
13 i32 i
, /* -1: error condition. otherwise, current cursor position */
14 len
; /* -1: dynamically allocated. otherwise, buffer length */
17 struct vg_str_dynamic
{
22 * Returns the current storage size of the string
24 static i32
vg_str_storage( vg_str
*str
){
27 vg_str_dynamic
*arr
= (vg_str_dynamic
*)str
->buffer
;
36 * Reset string. If len is -1 (dynamically allocated), buffer must be either
37 * NULL or be acquired from malloc or realloc
39 static void vg_strnull( vg_str
*str
, char *buffer
, i32 len
){
42 str
->buffer
[0] = '\0';
50 static void vg_strfree( vg_str
*str
){
53 vg_str_dynamic
*arr
= (vg_str_dynamic
*)str
->buffer
;
63 * Double the size of the dynamically allocated string. If unallocated, alloc of
66 static i32
vg_str_dynamic_grow( vg_str
*str
){
68 vg_str_dynamic
*hdr
= ((vg_str_dynamic
*)str
->buffer
) - 1;
69 i32 total
= (hdr
->len
+ sizeof(vg_str_dynamic
)) * 2;
70 hdr
= realloc( hdr
, total
);
71 hdr
->len
= total
- sizeof(vg_str_dynamic
);
72 str
->buffer
= (char *)(hdr
+1);
76 vg_str_dynamic
*hdr
= malloc(16);
77 hdr
->len
= 16-sizeof(vg_str_dynamic
);
78 str
->buffer
= (char *)(hdr
+1);
79 str
->buffer
[0] = '\0';
85 * Append null terminated string to vg_str
87 static void vg_strcat( vg_str
*str
, const char *append
){
88 if( !append
|| (str
->i
== -1) ) return;
90 i32 max
= vg_str_storage( str
),
96 max
= vg_str_dynamic_grow( str
);
99 str
->buffer
[ max
-1 ] = '\0';
104 char c
= append
[ i
++ ];
105 str
->buffer
[ str
->i
] = c
;
115 * Append character to vg_str
117 static void vg_strcatch( vg_str
*str
, char c
){
118 vg_strcat( str
, (char[]){ c
, '\0' } );
122 * FIXME: Negative numbers
124 static void vg_strcati32( vg_str
*str
, i32 value
){
128 while( value
&& (i
<31) ){
129 temp
[ i
++ ] = '0' + (value
% 10);
134 for( int j
=0; j
<i
; j
++ )
135 reverse
[j
] = temp
[ i
-1-j
];
138 vg_strcat( str
, reverse
);
141 vg_strcat( str
, "0" );
144 static void vg_strcati32r( vg_str
*str
, i32 value
, i32 n
, char alt
){
151 temp
[ n
-1 - (i
++) ] = '0' + (value
% 10);
156 temp
[ n
-1 - i
] = alt
;
159 vg_strcat( str
, temp
);
163 * Returns 1 if string did not overflow while building
165 static int vg_strgood( vg_str
*str
){
166 if( str
->i
== -1 ) return 0;
171 * Returns pointer to last instance of character
173 static char *vg_strch( vg_str
*str
, char c
){
175 for( i32 i
=0; i
<str
->i
; i
++ ){
176 if( str
->buffer
[i
] == c
)
183 #endif /* VG_STRING_H */