move string functions out from the header
This commit is contained in:
parent
a66b88b1d3
commit
35167781cd
2 changed files with 86 additions and 73 deletions
76
compiler/nstr.c
Normal file
76
compiler/nstr.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "pre.h"
|
||||
|
||||
int
|
||||
vsnprintf(char *, unsigned long, const char *, va_list);
|
||||
|
||||
/* Creates a `Str` from a buffer of size `len` */
|
||||
Str
|
||||
Str_from_buf(u8 *buf, isize len)
|
||||
{
|
||||
/* If this triggers an OOB, its because the code that created the string was
|
||||
* broken anyways. ASan will catch it. */
|
||||
Assert(buf[len] == '\0');
|
||||
return (Str){ buf, len };
|
||||
}
|
||||
|
||||
/* "Converts" a `Str` into a C string. Since `Str` are meant to be
|
||||
* null-terminated already, no conversion is made, but ensures that the
|
||||
* null terminator is present. */
|
||||
char *
|
||||
Str_to_c(Str s)
|
||||
{
|
||||
if (s.len == 0 || s.s == nil)
|
||||
return nil;
|
||||
Assert(s.s[s.len] == '\0');
|
||||
return (char *)s.s;
|
||||
}
|
||||
|
||||
/* Returns `true` if both strings are equal. */
|
||||
bool
|
||||
Str_equal(Str s1, Str s2)
|
||||
{
|
||||
/* because passing nil to mem* is UB even if size == 0... */
|
||||
return (s1.len == s2.len) && (s1.len == 0 || memcmp(s1.s, s2.s, s1.len) == 0);
|
||||
}
|
||||
|
||||
/* Heaps allocates a new `Str` of size `len`, with contents from `data` if it is
|
||||
* not `nil`.*/
|
||||
Str
|
||||
Str_new(const u8 *data, isize len)
|
||||
{
|
||||
Assert(len >= 0);
|
||||
Str s;
|
||||
s.s = calloc(len + 1, sizeof(*s.s));
|
||||
s.len = len;
|
||||
if (data != nil) {
|
||||
memcpy(s.s, data, len);
|
||||
s.s[len + 1] = '\0'; /* ensure */
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Returns a formatted string (heap allocated) of the exact required size. */
|
||||
Str
|
||||
Strafmt(const char *fmt, ...)
|
||||
{
|
||||
Str s = {0};
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
/* Calculate buffer size required to hold the formatted string */
|
||||
int reqs = vsnprintf(nil, 0, fmt, args);
|
||||
va_end(args);
|
||||
if (reqs < 0)
|
||||
return s;
|
||||
|
||||
s = Str_new(nil, reqs);
|
||||
va_start(args, fmt); /* `vsnprintf` touched the arg list, reinitialize it */
|
||||
/* the nil terminator is guaranteed by `Str_new` */
|
||||
vsnprintf((char *)s.s, s.len + 1, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return s;
|
||||
}
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef int8_t i8;
|
||||
|
@ -87,76 +85,15 @@ typedef struct {
|
|||
#define Str_empty(s) ((s).len == 0)
|
||||
#define Str_default(s, sor) (!Str_empty(s) ? (s) : (sor))
|
||||
|
||||
int
|
||||
vsnprintf(char *, unsigned long, const char *, va_list);
|
||||
|
||||
/* Creates a `Str` from a buffer of size `len` */
|
||||
static inline Str
|
||||
Str_from_buf(u8 *buf, isize len)
|
||||
{
|
||||
/* If this triggers an OOB, its because the code that created the string was
|
||||
* broken anyways. ASan will catch it. */
|
||||
Assert(buf[len] == '\0');
|
||||
return (Str){ buf, len };
|
||||
}
|
||||
|
||||
/* "Converts" a `Str` into a C string. Since `Str` are meant to be
|
||||
* null-terminated already, no conversion is made, but ensures that the
|
||||
* null terminator is present. */
|
||||
static inline char *
|
||||
Str_to_c(Str s)
|
||||
{
|
||||
if (s.len == 0 || s.s == nil)
|
||||
return nil;
|
||||
Assert(s.s[s.len] == '\0');
|
||||
return (char *)s.s;
|
||||
}
|
||||
|
||||
/* Returns `true` if both strings are equal. */
|
||||
static inline bool
|
||||
Str_equal(Str s1, Str s2)
|
||||
{
|
||||
/* because passing nil to mem* is UB even if size == 0... */
|
||||
return (s1.len == s2.len) && (s1.len == 0 || memcmp(s1.s, s2.s, s1.len) == 0);
|
||||
}
|
||||
|
||||
/* Heaps allocates a new `Str` of size `len`, with contents from `data` if it is
|
||||
* not `nil`.*/
|
||||
static inline Str
|
||||
Str_new(const u8 *data, isize len)
|
||||
{
|
||||
Assert(len >= 0);
|
||||
Str s;
|
||||
s.s = calloc(len + 1, sizeof(*s.s));
|
||||
s.len = len;
|
||||
if (data != nil) {
|
||||
memcpy(s.s, data, len);
|
||||
s.s[len + 1] = '\0'; /* ensure */
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Returns a formatted string (heap allocated) of the exact required size. */
|
||||
static inline Str
|
||||
Strafmt(const char *fmt, ...)
|
||||
{
|
||||
Str s = {0};
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
/* Calculate buffer size required to hold the formatted string */
|
||||
int reqs = vsnprintf(nil, 0, fmt, args);
|
||||
va_end(args);
|
||||
if (reqs < 0)
|
||||
return s;
|
||||
|
||||
s = Str_new(nil, reqs);
|
||||
va_start(args, fmt); /* `vsnprintf` touched the arg list, reinitialize it */
|
||||
/* the nil terminator is guaranteed by `Str_new` */
|
||||
vsnprintf((char *)s.s, s.len + 1, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return s;
|
||||
}
|
||||
Str
|
||||
Str_from_buf(u8 *buf, isize len);
|
||||
char *
|
||||
Str_to_c(Str s);
|
||||
bool
|
||||
Str_equal(Str s1, Str s2);
|
||||
Str
|
||||
Str_new(const u8 *data, isize len);
|
||||
Str
|
||||
Strafmt(const char *fmt, ...);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue