Spaces:
Sleeping
Sleeping
// Enable MinGW secure API for _snprintf_s | |
typedef struct string_buffer { | |
char* buffer; | |
int position; | |
int size; | |
} string_buffer; | |
typedef struct string_list { | |
char** buffer; | |
int position; | |
int size; | |
} string_list; | |
static __INLINE string_buffer* buffer_create(int L) { | |
string_buffer* B = (string_buffer*) malloc(sizeof(string_buffer)); | |
B->size = L; | |
B->buffer = (char*) malloc(sizeof(char) * B->size); | |
B->position = 0; | |
return B; | |
} | |
static __INLINE void buffer_reset(string_buffer* B) { | |
B->position = 0; | |
} | |
static __INLINE void buffer_destroy(string_buffer** B) { | |
if (!(*B)) return; | |
if ((*B)->buffer) { | |
free((*B)->buffer); | |
(*B)->buffer = NULL; | |
} | |
free((*B)); | |
(*B) = NULL; | |
} | |
static __INLINE char* buffer_extract(const string_buffer* B) { | |
char *S = (char*) malloc(sizeof(char) * (B->position + 1)); | |
memcpy(S, B->buffer, B->position); | |
S[B->position] = '\0'; | |
return S; | |
} | |
static __INLINE int buffer_size(const string_buffer* B) { | |
return B->position; | |
} | |
static __INLINE void buffer_push(string_buffer* B, char C) { | |
int required = 1; | |
if (required > B->size - B->position) { | |
B->size = B->position + BUFFER_INCREMENT_STEP; | |
B->buffer = (char*) realloc(B->buffer, sizeof(char) * B->size); | |
} | |
B->buffer[B->position] = C; | |
B->position += required; | |
} | |
static __INLINE void buffer_append(string_buffer* B, const char *format, ...) { | |
int required; | |
va_list args; | |
va_start(args, format); | |
required = _vscprintf(format, args) + 1; | |
va_end(args); | |
if (required >= B->size - B->position) { | |
B->size = B->position + required + 1; | |
B->buffer = (char*) realloc(B->buffer, sizeof(char) * B->size); | |
} | |
va_start(args, format); | |
required = _vsnprintf_s(&(B->buffer[B->position]), B->size - B->position, _TRUNCATE, format, args); | |
va_end(args); | |
B->position += required; | |
va_start(args, format); | |
required = vsnprintf(&(B->buffer[B->position]), B->size - B->position, format, args); | |
va_end(args); | |
if (required >= B->size - B->position) { | |
B->size = B->position + required + 1; | |
B->buffer = (char*) realloc(B->buffer, sizeof(char) * B->size); | |
va_start(args, format); | |
required = vsnprintf(&(B->buffer[B->position]), B->size - B->position, format, args); | |
va_end(args); | |
} | |
B->position += required; | |
} | |
static __INLINE string_list* list_create(int L) { | |
string_list* B = (string_list*) malloc(sizeof(string_list)); | |
B->size = L; | |
B->buffer = (char**) malloc(sizeof(char*) * B->size); | |
memset(B->buffer, 0, sizeof(char*) * B->size); | |
B->position = 0; | |
return B; | |
} | |
static __INLINE void list_reset(string_list* B) { | |
int i; | |
for (i = 0; i < B->position; i++) { | |
if (B->buffer[i]) free(B->buffer[i]); | |
B->buffer[i] = NULL; | |
} | |
B->position = 0; | |
} | |
static __INLINE void list_destroy(string_list **B) { | |
int i; | |
if (!(*B)) return; | |
for (i = 0; i < (*B)->position; i++) { | |
if ((*B)->buffer[i]) free((*B)->buffer[i]); (*B)->buffer[i] = NULL; | |
} | |
if ((*B)->buffer) { | |
free((*B)->buffer); (*B)->buffer = NULL; | |
} | |
free((*B)); | |
(*B) = NULL; | |
} | |
static __INLINE char* list_get(const string_list *B, int I) { | |
if (I < 0 || I >= B->position) { | |
return NULL; | |
} else { | |
if (!B->buffer[I]) { | |
return NULL; | |
} else { | |
char *S; | |
int length = strlen(B->buffer[I]); | |
S = (char*) malloc(sizeof(char) * (length + 1)); | |
memcpy(S, B->buffer[I], length + 1); | |
return S; | |
} | |
} | |
} | |
static __INLINE int list_size(const string_list *B) { | |
return B->position; | |
} | |
static __INLINE void list_append(string_list *B, char* S) { | |
int required = 1; | |
int length = strlen(S); | |
if (required > B->size - B->position) { | |
B->size = B->position + 16; | |
B->buffer = (char**) realloc(B->buffer, sizeof(char*) * B->size); | |
} | |
B->buffer[B->position] = (char*) malloc(sizeof(char) * (length + 1)); | |
memcpy(B->buffer[B->position], S, length + 1); | |
B->position += required; | |
} | |
// This version of the append does not copy the string but simply takes the control of its allocation | |
static __INLINE void list_append_direct(string_list *B, char* S) { | |
int required = 1; | |
// int length = strlen(S); | |
if (required > B->size - B->position) { | |
B->size = B->position + 16; | |
B->buffer = (char**) realloc(B->buffer, sizeof(char*) * B->size); | |
} | |
B->buffer[B->position] = S; | |
B->position += required; | |
} | |