diff --git a/buff.h b/buff.h index 9b75fd4..666dc00 100644 --- a/buff.h +++ b/buff.h @@ -20,3 +20,15 @@ #define BUFF_REMOVE_FRONT(buff_ptr) {if((buff_ptr)->cur_index > 0) {for(int i = 0; i < (buff_ptr)->cur_index - 1; i++) { (buff_ptr)->data[i] = (buff_ptr)->data[i+1]; }; (buff_ptr)->cur_index--;}} #define BUFF_REMOVE_AT_INDEX(buff_ptr, index) { BUFF_VALID(buff_ptr); assert(index >= 0); assert(index < (buff_ptr)->cur_index); for(int i = index; i < (buff_ptr)->cur_index - 1; i++) (buff_ptr)->data[i] = (buff_ptr)->data[i + 1]; (buff_ptr)->cur_index -= 1; } #define BUFF_CLEAR(buff_ptr) {memset((buff_ptr), 0, sizeof(*(buff_ptr))); ((buff_ptr)->cur_index = 0);} + +typedef struct +{ + void *data; + size_t max_data_elems; + size_t data_elem_size; + int *cur_index; +} BuffRef; + +#define BUFF_MAKEREF(buff_ptr) ((BuffRef){.data = (void*)((buff_ptr)->data), .max_data_elems = ARRLEN((buff_ptr)->data), .data_elem_size = sizeof((buff_ptr)->data[0]), .cur_index = &((buff_ptr)->cur_index)}) + + diff --git a/makeprompt.h b/makeprompt.h index 7a1f984..bf5533e 100644 --- a/makeprompt.h +++ b/makeprompt.h @@ -405,7 +405,26 @@ void process_perception(Entity *it, Perception p) } } -#define printf_buff(buff_ptr, ...) { BUFF_VALID(buff_ptr); int written = snprintf((buff_ptr)->data+(buff_ptr)->cur_index, ARRLEN((buff_ptr)->data) - (buff_ptr)->cur_index, __VA_ARGS__); assert(written >= 0); (buff_ptr)->cur_index += written; }; +// returns if printed into the buff without any errors +bool printf_buff_impl(BuffRef into, const char *format, ...) +{ + assert(*into.cur_index < into.max_data_elems); + assert(into.data_elem_size == 1); // characters + va_list args; + va_start (args, format); + int n = info.max_data_elems - *info.cur_index; + int written = vsnprintf((char*)into.data + *info.cur_index, n, format, args); + + // https://cplusplus.com/reference/cstdio/vsnprintf/ + bool succeeded = true; + if(written < 0) succeeded = false; // encoding error + if(written >= n) succeeded = false; // didn't fit in buffer + + va_end(args); + return succeeded; +} + +#define printf_buff(buff_ptr, ...) printf_buff_impl(BUFF_MAKEREF(buff_ptr), __VA_ARGS__) bool npc_does_dialog(Entity *it) {