X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=blobdiff_plain;f=vg_string.h;fp=vg_string.h;h=62d5abc14a38d40818b1a93bcec244d4f3111f68;hp=c99fc7a65f3825ee8a8955121c1bbf494c381238;hb=3b14f3dcd5bf9dd3c85144f2123d667bfa4bb63f;hpb=fce86711735b15bff37de0f70716808410fcf269 diff --git a/vg_string.h b/vg_string.h index c99fc7a..62d5abc 100644 --- a/vg_string.h +++ b/vg_string.h @@ -1,183 +1,67 @@ -#ifndef VG_STRING_H -#define VG_STRING_H +#pragma once +#include "vg_platform.h" /* string builder with optional dynamic memory or static buffer. */ -#include "vg_stdint.h" - typedef struct vg_str vg_str; typedef struct vg_str_dynamic vg_str_dynamic; -struct vg_str{ +struct vg_str +{ char *buffer; i32 i, /* -1: error condition. otherwise, current cursor position */ len; /* -1: dynamically allocated. otherwise, buffer length */ }; -struct vg_str_dynamic { +struct vg_str_dynamic +{ i32 len; }; /* * Returns the current storage size of the string */ -static 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; -} +i32 vg_str_storage( vg_str *str ); /* * Reset string. If len is -1 (dynamically allocated), buffer must be either * NULL or be acquired from malloc or realloc */ -static 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; - - assert(len); -} - -static 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_strnull( vg_str *str, char *buffer, i32 len ); +void vg_strfree( vg_str *str ); /* * Append null terminated string to vg_str */ -static 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_strcat( vg_str *str, const char *append ); /* * Append character to vg_str */ -static void vg_strcatch( vg_str *str, char c ){ - vg_strcat( str, (char[]){ c, '\0' } ); -} - -/* - * FIXME: Negative numbers - */ -static 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; -} +int vg_strgood( vg_str *str ); /* * Returns pointer to last instance of character */ -static 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; - } +char *vg_strch( vg_str *str, char c ); + +enum strncpy_behaviour +{ + k_strncpy_always_add_null = 0, + k_strncpy_allow_cutoff = 1, + k_strncpy_overflow_fatal = 2 +}; - return ptr; -} +u32 vg_strncpy( const char *src, char *dst, u32 len, + enum strncpy_behaviour behaviour ); +u32 vg_strdjb2( const char *str ); +int vg_strdjb2_eq( const char *s1, u32 h1, const char *s2, u32 h2 ); -#endif /* VG_STRING_H */ +#define VG_STRDJB2_EQ( CS1, S2, H2 ) \ + vg_strdjb2_eq( CS1, vg_strdjb2(CS1), S2, H2 )