From: hgn Date: Sat, 27 May 2023 04:18:36 +0000 (+0100) Subject: fixed some complaints from mingw/gcc X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=commitdiff_plain;h=127f6fa3df70c71f53199b32d4468c79e8bcd022 fixed some complaints from mingw/gcc --- diff --git a/vg_console.h b/vg_console.h index c25dc6f..d2f8d87 100644 --- a/vg_console.h +++ b/vg_console.h @@ -459,7 +459,7 @@ VG_STATIC void console_update_suggestions(void) const char *args[8]; int token_count = vg_console_tokenize( vg_console.input, temp, args ); - + if( !token_count ) return; vg_console.suggestion_pastepos = args[token_count-1]-temp; /* Score all our commands and cvars */ diff --git a/vg_msg.h b/vg_msg.h index cc38e85..83bc086 100644 --- a/vg_msg.h +++ b/vg_msg.h @@ -1,6 +1,95 @@ #ifndef VG_MSG_H #define VG_MSG_H #include "vg_stdint.h" +#include "vg_platform.h" + +/* + * Example data: + * kvstr "someinfo" + * kvint 200 + * frame "person"{ + * name "jeff" + * country "england" + * } + * frame "building"{ + * capacity 1000 + * } + * frame "person"{ + * country "wales" + * name "micheal" + * } + * + * Creating the data in code: + * ----------------------------------------------------------------------------- + * u8 data_buf[512]; + * vg_msg data; + * vg_msg_init( &data, data_buf, 512 ); + * vg_msg_wkvstr( &data, "kvstr", "someinfo" ); + * vg_msg_wkvint( &data, "kvint", i32 value=200 ); + * + * vg_msg_frame( &data, "person" ); + * vg_msg_wkvstr( &data, "name", "jeff" ); + * vg_msg_wkvstr( &data, "country", "england" ); + * vg_msg_end_frame( &data ); + * + * vg_msg_frame( &data, "building" ); + * vg_msg_wkvint( &data, "capacity", i32 value=1000 ); + * vg_msg_end_frame( &data ); + * + * vg_msg_frame( &data, "person" ); + * vg_msg_wkvstr( &data, "country", "wales" ); + * vg_msg_wkvstr( &data, "name", "micheal" ); + * vg_msg_end_frame( &data ); + * + * Saving the data out + * ----------------------------------------------------------------------------- + * + * if( data.error == k_vg_msg_error_OK ){ + * // write data_buf, for length data.cur + * } + * + * Load the data + * ----------------------------------------------------------------------------- + * + * u8 data_buf[512]; + * u32 data_len; + * // read data_buf and data_len + * vg_msg data; + * vg_msg_init( &data, data_buf, data_len ); + * + * Reading back the stream linearly + * ----------------------------------------------------------------------------- + * + * vg_msg_cmd cmd; + * while( vg_msg_next( &data, &cmd ) ){ + * if( cmd.code == k_vg_msg_code_frame ) printf( "{" ); + * else if( cmd.code == k_vg_msg_code_endframe ) printf( "}" ); + * esle if( cmd.code == k_vg_msg_code_kvstring ) + * printf( "string: %s\n", cmd.value._buf ); + * } + * + * Reading back the stream as frames/nodes. this is obviously slower + * ----------------------------------------------------------------------------- + * + * vg_msg person = data + * while( vg_msg_seekframe( &person, "person", VG_MSG_NEXT ) ){ + * const char *name = vg_msg_seekkvstr(&person, "name", VG_MSG_NEXT); + * const char *country = vg_msg_seekkvstr(&person, "country", VG_MSG_FIRST); + * + * printf( "Guy '%s' is from '%s'\n", name, country ); + * vg_msg_skip_frame(&person); + * } + * + * vg_msg building = root; + * if( vg_msg_seekframe( &building, "building", VG_MSG_FIRST ) ){ + * vg_msg_cmd capacity = vg_msg_seekkv(&building, "capacity", VG_MSG_FIRST); + * if( capacity.code & k_vg_msg_code_signed ) + * print( "building capacity: %d\n", capacity.value._i32 ); + * + * vg_msg_skip_frame( &building ); + * } + * + */ enum vg_msg_code{ k_vg_msg_code_end = 0, @@ -11,7 +100,8 @@ enum vg_msg_code{ k_vg_msg_code_kvbin = 12, k_vg_msg_code_signed = 0x80, /* byte sizes stored in lower 4 bits */ k_vg_msg_code_unsigned = 0x40, - k_vg_msg_code_float = 0x20 + k_vg_msg_code_float = 0x20, + k_vg_msg_code_integer = k_vg_msg_code_signed|k_vg_msg_code_unsigned }; typedef struct vg_msg vg_msg; @@ -20,6 +110,9 @@ struct vg_msg{ u32 cur,max; u8 *buf; u32 depth; + + /* reading */ + u32 rframe_depth, rframe_cur; enum vg_msg_error{ k_vg_msg_error_OK, @@ -45,14 +138,18 @@ struct vg_msg_cmd{ u32 value_djb2; }; +/* generic stream reset */ static void vg_msg_init( vg_msg *msg, u8 *buf, u32 max ){ msg->cur = 0; msg->max = max; msg->buf = buf; msg->depth = 0; msg->error = k_vg_msg_error_OK; + msg->rframe_depth = 0; + msg->rframe_cur = 0; } +/* write or read a buffer from msg, rang checked. */ static void vg_msg_exchbuf( vg_msg *msg, int write, u8 *buf, u32 len ){ if( msg->error != k_vg_msg_error_OK ) return; if( msg->cur+len > msg->max ){ @@ -65,6 +162,7 @@ static void vg_msg_exchbuf( vg_msg *msg, int write, u8 *buf, u32 len ){ } } +/* write null terminated string to stream */ static void vg_msg_wstr( vg_msg *msg, const char *str ){ if( msg->error != k_vg_msg_error_OK ) return; for( u32 i=0;; i++ ){ @@ -73,6 +171,7 @@ static void vg_msg_wstr( vg_msg *msg, const char *str ){ } } +/* read null terminated string, range check and generate hash (djb2) */ static const char *vg_msg_rstr( vg_msg *msg, u32 *djb2 ){ if( msg->error != k_vg_msg_error_OK ) return 0; @@ -91,6 +190,7 @@ static const char *vg_msg_rstr( vg_msg *msg, u32 *djb2 ){ return str; } +/* begin a new frame in message stream */ static void vg_msg_frame( vg_msg *msg, const char *name ){ if( msg->error != k_vg_msg_error_OK ) return; @@ -99,6 +199,7 @@ static void vg_msg_frame( vg_msg *msg, const char *name ){ vg_msg_wstr( msg, name ); } +/* end frame in message stream */ static void vg_msg_end_frame( vg_msg *msg ){ if( msg->error != k_vg_msg_error_OK ) return; if( !msg->depth ){ @@ -109,12 +210,14 @@ static void vg_msg_end_frame( vg_msg *msg ){ vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_endframe }, 1 ); } +/* write a KV string to stream */ static void vg_msg_wkvstr( vg_msg *msg, const char *key, const char *value ){ vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_kvstring }, 1 ); vg_msg_wstr( msg, key ); vg_msg_wstr( msg, value ); } +/* write a binary block to stream */ static void vg_msg_wkvbin( vg_msg *msg, const char *key, u8 *bin, u32 len ){ vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_kvbin }, 1 ); vg_msg_wstr( msg, key ); @@ -122,6 +225,7 @@ static void vg_msg_wkvbin( vg_msg *msg, const char *key, u8 *bin, u32 len ){ vg_msg_exchbuf( msg, 1, bin, len ); } +/* write a generic sized kv */ static void vg__msg_wkvgen( vg_msg *msg, const char *key, u8 basecode, void *value, u32 size ){ u8 code = basecode | size; @@ -130,6 +234,15 @@ static void vg__msg_wkvgen( vg_msg *msg, const char *key, vg_msg_exchbuf( msg, 1, value, size ); } +/* + * macros to write sized integers and floats + * + * you use them like: + * vg_msg_wkvint( &msg, "key", u32 value=32 ); + * + * this will write a 32 bit unsigned int to the stream + */ + #define vg_msg_wkvint( MSGPTR, KEY, DECL ){ \ DECL; \ vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_signed, &value, sizeof(value));\ @@ -143,6 +256,14 @@ static void vg__msg_wkvgen( vg_msg *msg, const char *key, vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_float, &value, sizeof(value));\ } +/* + * The stream reading interface + * ----------------------------------------------------------------------------- + */ + +/* move the cursor through the next message. it will always read in the value or + * create an error if it runs of the end of the stream. every possible command + * must be handled in this function */ static int vg_msg_next( vg_msg *msg, vg_msg_cmd *cmd ){ vg_msg_exchbuf( msg, 0, &cmd->code, 1 ); if( msg->error != k_vg_msg_error_OK ) return 0; @@ -193,6 +314,7 @@ static int vg_msg_next( vg_msg *msg, vg_msg_cmd *cmd ){ else return 1; } +/* move through the frame(and subframes) until we fall out of it */ static int vg_msg_skip_frame( vg_msg *msg ){ vg_msg_cmd cmd; @@ -203,4 +325,83 @@ static int vg_msg_skip_frame( vg_msg *msg ){ return 0; } +/* + * A more friendly but slower interface + * ----------------------------------------------------------------------------- + */ + +enum vg_msg_dir{ + k_vg_msg_first=0, /* reset the frame pointer and find the first thing */ + k_vg_msg_next=1 /* get next item in the stream, wont find behind cursor */ +}; + +/* reset frame pointer and depth to the start of the frame set by seekframe */ +static void vg_msg_framereset( vg_msg *frame ){ + frame->cur = frame->rframe_cur; + frame->depth = frame->rframe_depth; +} + +/* moves to a frame, and sets the base frame in msg if it finds it */ +static int vg_msg_seekframe( vg_msg *msg, const char *name, + enum vg_msg_dir dir ) +{ + if( dir == k_vg_msg_first ) vg_msg_framereset( msg ); + + vg_msg_cmd cmd; + while( vg_msg_next( msg, &cmd ) ){ + if( msg->depth < msg->rframe_depth ){ + vg_msg_framereset(msg); + return 0; + } + if( msg->depth != msg->rframe_depth+1 ) continue; + if( cmd.code == k_vg_msg_code_frame ){ + if( VG_STRDJB2_EQ( name, cmd.key, cmd.key_djb2 ) ){ + msg->rframe_cur = msg->cur; + msg->rframe_depth = msg->depth; + return 1; + } + } + } + + return 0; +} + +/* move to the kv named key, doesnt matter what type */ +static vg_msg_cmd vg_msg_seekkv( vg_msg *msg, const char *key, + enum vg_msg_dir dir ) +{ + if( dir == k_vg_msg_first ) vg_msg_framereset( msg ); + + vg_msg_cmd kv; + kv.code = k_vg_msg_code_end; + kv.key = ""; + kv.key_djb2 = 0; + kv.value._u64 = 0; + kv.key_djb2 = 0; + + vg_msg_cmd cmd; + while( vg_msg_next( msg, &cmd ) ){ + if( msg->depth < msg->rframe_depth ){ + vg_msg_framereset(msg); + return kv; + } + if( msg->depth > msg->rframe_depth ) continue; + if( cmd.code > k_vg_msg_code_kv ) + if( VG_STRDJB2_EQ( key, cmd.key, cmd.key_djb2 ) ) + return cmd; + } + + return kv; +} + +/* helper for reading string kvs. returns NULL if not found */ +static const char *vg_msg_seekkvstr( vg_msg *msg, const char *key, + enum vg_msg_dir dir ) +{ + vg_msg_cmd cmd = vg_msg_seekkv( msg, key, dir ); + if( cmd.code == k_vg_msg_code_kvstring ) return cmd.value._buf; + else return NULL; +} + + #endif /* VG_MSG_H */ diff --git a/vg_platform.h b/vg_platform.h index 2ebc506..1b0317c 100644 --- a/vg_platform.h +++ b/vg_platform.h @@ -96,6 +96,7 @@ VG_STATIC void vg_strnull( vg_str *str, char *buffer, u32 len ) VG_STATIC void vg_strcat( vg_str *str, const char *append ) { + if( !append ) return; for( u32 i=0; str->i < str->len; i++, str->i ++ ){ str->buffer[ str->i ] = append[i];