diff --git a/view.c b/view.c index 0aa73a4..a174ed8 100644 --- a/view.c +++ b/view.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "view.h" @@ -103,23 +104,29 @@ view_t s_get_str(str_info_t data) }; } -__attribute__((cold)) -static size_t _sv_copy_manual(size_t sz, char buffer[restrict static sz], view_t view) +__attribute__((__always_inline__, __gnu_inline__, artificial)) +inline static size_t _sv_copy_manual(size_t sz, char buffer[restrict static sz], view_t view) { + + memcpy(buffer, view.ptr, sz = min((sz-1), view.len)); + /* size_t i=0; for(;i< (sz-1) && iptr, min(out->len, sz), fmt, args); + else return vsnprintf((char[]){}, 0, fmt, args); +} + +size_t sv_vsvnprintf(view_t* restrict out, size_t sz, view_t fmt, va_list args) +{ + char buffer[fmt.len+1]; + sv_copy_to(fmt.len+1, buffer, fmt); + return sv_vsnprintf(out, sz, buffer, args); +} +size_t sv_snprintf(view_t* restrict out, size_t sz, const char* fmt, ...) +{ + va_list va; + va_start(va, fmt); + size_t r = sv_vsnprintf(out, sz, fmt, va); + va_end(va); + return r; +} + +size_t sv_sprintf(view_t* restrict out, const char* fmt, ...) +{ + va_list va; + va_start(va, fmt); + size_t r = sv_vsnprintf(out, out ? out->len : 0, fmt, va); + va_end(va); + return r; +} +size_t sv_svnprintf(view_t* restrict out, size_t sz, view_t fmt, ...) +{ + va_list va; + va_start(va, fmt); + size_t r = sv_vsvnprintf(out, sz, fmt, va); + va_end(va); + return r; +} + +size_t sv_svprintf(view_t* restrict out, view_t fmt, ...) +{ + va_list va; + va_start(va, fmt); + size_t r = sv_vsvnprintf(out, out ? out->len : fmt.len, fmt, va); + va_end(va); + return r; +} diff --git a/view.h b/view.h index 3864441..ffc3f4b 100644 --- a/view.h +++ b/view.h @@ -5,6 +5,11 @@ #include #include +/// Printf format string for `view_t` +#define SV_PRINT_FMT "%.*s" +/// Printf format arguments for `view_t` to match the position of `SV_PRINT_FMT` +#define SV_PRINT_ARG(view) (int)(view).len, (view).ptr + typedef struct string_view { size_t len; char* ptr; @@ -36,6 +41,12 @@ extern inline size_t sv_split_cstr(const char* p, char on, view_t* restrict firs size_t sv_copy_to(size_t sz, char buffer[restrict static sz], view_t view); char* sv_to_cstr(view_t view, char* restrict buffer, size_t n); +// sprintf-like +size_t sv_svnprintf(view_t* restrict out, size_t sz, view_t fmt, ...); +size_t sv_svprintf(view_t* restrict out, view_t fmt, ...); +size_t sv_sprintf(view_t* restrict out, const char* fmt, ...); +size_t sv_snprintf(view_t* restrict out, size_t sz, const char* fmt, ...); + __attribute__((__gnu_inline__, malloc)) extern inline char* sv_dupto_cstr(view_t view) { return sv_to_cstr(view, (char*)0, 0); }