implemented buffer_size calculation in vsprintf_malloc

This commit is contained in:
Timerix 2025-11-10 01:54:47 +05:00
parent e2f1f6c09b
commit 1406189511
3 changed files with 38 additions and 28 deletions

View File

@ -47,7 +47,7 @@ typedef struct Result_ {
#define IGNORE_RESULT Result_ __ignored_##__LINE__ ATTRIBUTE_UNUSED =
#define RESULT_ERROR(MSG, IS_MSG_ON_HEAP) (Result_){ .error = Error_create(MSG, IS_MSG_ON_HEAP, ErrorCallPos_here()) }
#define RESULT_ERROR_FMT(FORMAT, ARGS...) RESULT_ERROR(sprintf_malloc(4096, FORMAT ,##ARGS), true)
#define RESULT_ERROR_FMT(FORMAT, ARGS...) RESULT_ERROR(sprintf_malloc(FORMAT ,##ARGS), true)
#define RESULT_ERROR_ERRNO() RESULT_ERROR(strerror(errno), false)
#define RESULT_VOID (Result_){ .error = NULL, .u = 0 }
#define RESULT_VALUE(FIELD, V) (Result_){ .error = NULL, .FIELD = V }

View File

@ -2,8 +2,8 @@
#include "../std.h"
#define strcat_malloc(STR0, ...) _strcat_malloc(count_args(__VA_ARGS__), STR0, __VA_ARGS__)
char* _strcat_malloc(size_t n, cstr str0, ...);
char* _vstrcat_malloc(size_t n, cstr str0, va_list argv);
char* _strcat_malloc(u64 n, cstr str0, ...);
char* _vstrcat_malloc(u64 n, cstr str0, va_list args);
char* NULLABLE(sprintf_malloc)(size_t buffer_size, cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(2, 3);
char* NULLABLE(vsprintf_malloc)(size_t buffer_size, cstr format, va_list argv);
char* sprintf_malloc(cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(1, 2);
char* vsprintf_malloc(cstr format, va_list args);

View File

@ -1,21 +1,21 @@
#include "tlibc/string/cstr.h"
char* _strcat_malloc(size_t n, cstr str0, ...){
va_list argv;
va_start(argv, str0);
char* heap_ptr = _vstrcat_malloc(n, str0, argv);
va_end(argv);
char* _strcat_malloc(u64 n, cstr str0, ...){
va_list args;
va_start(args, str0);
char* heap_ptr = _vstrcat_malloc(n, str0, args);
va_end(args);
return heap_ptr;
}
char* _vstrcat_malloc(size_t n, cstr str0, va_list argv){
size_t str0_len = strlen(str0);
size_t total_len = str0_len;
char* _vstrcat_malloc(u64 n, cstr str0, va_list args){
u64 str0_len = strlen(str0);
u64 total_len = str0_len;
cstr* const parts = malloc(sizeof(cstr) * n);
size_t* const part_lengths = malloc(sizeof(size_t) * n);
for(size_t i = 0; i < n; i++){
cstr part = va_arg(argv, cstr);
size_t length = strlen(part);
u64* const part_lengths = malloc(sizeof(u64) * n);
for(u64 i = 0; i < n; i++){
cstr part = va_arg(args, cstr);
u64 length = strlen(part);
parts[i] = part;
part_lengths[i] = length;
total_len += length;
@ -23,7 +23,7 @@ char* _vstrcat_malloc(size_t n, cstr str0, va_list argv){
char* const buf = malloc(total_len + 1);
memcpy(buf, str0, str0_len);
char* walking_ptr = buf + str0_len;
for(size_t i = 0; i < n; i++){
for(u64 i = 0; i < n; i++){
memcpy(walking_ptr, parts[i], part_lengths[i]);
walking_ptr += part_lengths[i];
}
@ -33,20 +33,30 @@ char* _vstrcat_malloc(size_t n, cstr str0, va_list argv){
return buf;
}
char* NULLABLE(sprintf_malloc)(size_t buffer_size, cstr format, ...){
va_list argv;
va_start(argv, format);
char* NULLABLE(heap_ptr) = vsprintf_malloc(buffer_size, format, argv);
va_end(argv);
char* NULLABLE(sprintf_malloc)(cstr format, ...){
va_list args;
va_start(args, format);
char* heap_ptr = vsprintf_malloc(format, args);
va_end(args);
return heap_ptr;
}
char* NULLABLE(vsprintf_malloc)(size_t buffer_size, cstr format, va_list argv){
char* buf = malloc(buffer_size);
int r = vsprintf(buf, format, argv);
char* vsprintf_malloc(cstr format, va_list args){
// thanks to libtoml developer
va_list args_copy;
va_copy(args_copy, args);
i32 buf_size = vsnprintf(NULL, 0, format, args_copy);
va_end(args_copy);
if(buf_size < 63)
buf_size = 63;
buf_size += 1; // for '\0'
char* buf = malloc(buf_size);
int r = vsnprintf(buf, buf_size, format, args);
if(r < 0){
free(buf);
return NULL;
char err_msg[] = "<ERROR vsprintf_malloc (tlibc/src/cstr.c:55)>";
u32 err_msg_size = sizeof(err_msg);
memcpy(buf, err_msg, err_msg_size);
}
return buf;
}