X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=blobdiff_plain;f=vg_string.c;fp=vg_string.c;h=1a38479e139243635011b0c272a6af081c6d6b80;hp=0000000000000000000000000000000000000000;hb=3b14f3dcd5bf9dd3c85144f2123d667bfa4bb63f;hpb=fce86711735b15bff37de0f70716808410fcf269 diff --git a/vg_string.c b/vg_string.c new file mode 100644 index 0000000..1a38479 --- /dev/null +++ b/vg_string.c @@ -0,0 +1,204 @@ +#include "vg_string.h" +#include "vg_platform.h" +#include + +i32 vg_str_storage( vg_str *str ) +{ + if( str->len == -1 ){ + if( str->buffer ){ + vg_str_dynamic *arr = (vg_str_dynamic *)str->buffer; + return (arr-1)->len; + } + else return 0; + } + else return str->len; +} + +/* + * Reset string. If len is -1 (dynamically allocated), buffer must be either + * NULL or be acquired from malloc or realloc + */ +void vg_strnull( vg_str *str, char *buffer, i32 len ) +{ + str->buffer = buffer; + if( buffer ) + str->buffer[0] = '\0'; + + str->i = 0; + str->len = len; + + if( len == 0 ) + vg_fatal_error( "0 length string allocation\n" ); +} + +void vg_strfree( vg_str *str ) +{ + if( str->len == -1 ){ + if( str->buffer ){ + vg_str_dynamic *arr = (vg_str_dynamic *)str->buffer; + free( arr-1 ); + + str->buffer = NULL; + str->i = 0; + } + } +} + +/* + * Double the size of the dynamically allocated string. If unallocated, alloc of + * 16 bytes minimum. + */ +static i32 vg_str_dynamic_grow( vg_str *str ) +{ + if( str->buffer ){ + vg_str_dynamic *hdr = ((vg_str_dynamic *)str->buffer) - 1; + i32 total = (hdr->len + sizeof(vg_str_dynamic)) * 2; + hdr = realloc( hdr, total ); + hdr->len = total - sizeof(vg_str_dynamic); + str->buffer = (char *)(hdr+1); + return hdr->len; + } + else { + vg_str_dynamic *hdr = malloc(16); + hdr->len = 16-sizeof(vg_str_dynamic); + str->buffer = (char *)(hdr+1); + str->buffer[0] = '\0'; + return hdr->len; + } +} + +void vg_strcat( vg_str *str, const char *append ) +{ + if( !append || (str->i == -1) ) return; + + i32 max = vg_str_storage( str ), + i = 0; + +append: + if( str->i == max ){ + if( str->len == -1 ) + max = vg_str_dynamic_grow( str ); + else{ + str->i = -1; + str->buffer[ max-1 ] = '\0'; + return; + } + } + + char c = append[ i ++ ]; + str->buffer[ str->i ] = c; + + if( c == '\0' ) + return; + + str->i ++; + goto append; +} + +void vg_strcatch( vg_str *str, char c ) +{ + vg_strcat( str, (char[]){ c, '\0' } ); +} + +/* + * FIXME: Negative numbers + */ +void vg_strcati32( vg_str *str, i32 value ) +{ + if( value ){ + char temp[32]; + int i=0; + while( value && (i<31) ){ + temp[ i ++ ] = '0' + (value % 10); + value /= 10; + } + + char reverse[32]; + for( int j=0; j=n ) + break; + + temp[ n-1 - (i ++) ] = '0' + (value % 10); + value /= 10; + } + + for( ;ii == -1 ) return 0; + else return 1; +} + +/* + * Returns pointer to last instance of character + */ +char *vg_strch( vg_str *str, char c ) +{ + char *ptr = NULL; + for( i32 i=0; ii; i++ ){ + if( str->buffer[i] == c ) + ptr = str->buffer+i; + } + + return ptr; +} + +u32 vg_strncpy( const char *src, char *dst, u32 len, + enum strncpy_behaviour behaviour ) +{ + for( u32 i=0; i