diff options
| author | Tyge Løvset <[email protected]> | 2021-05-13 18:24:53 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-05-13 18:24:53 +0200 |
| commit | 560b6520ed0cb6f8faaf8309a87d4803b55a32c4 (patch) | |
| tree | 243e4493dba47ad907f591c447d392d61a13c49a | |
| parent | c4c680501791b9c1e69429e114bfac2b78d7a203 (diff) | |
| download | STC-modified-560b6520ed0cb6f8faaf8309a87d4803b55a32c4.tar.gz STC-modified-560b6520ed0cb6f8faaf8309a87d4803b55a32c4.zip | |
Updated cstr: Added cstr_new(literal), Renamed cstr_assign_s() to cstr_copy(). Fixed and added minors in ccommon.h
| -rw-r--r-- | docs/cstr_api.md | 35 | ||||
| -rw-r--r-- | stc/carray.h | 2 | ||||
| -rw-r--r-- | stc/ccommon.h | 6 | ||||
| -rw-r--r-- | stc/cstr.h | 57 |
4 files changed, 55 insertions, 45 deletions
diff --git a/docs/cstr_api.md b/docs/cstr_api.md index 77fbe86c..308c54ab 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -16,6 +16,7 @@ All cstr definitions and prototypes are available by including a single header f ```c cstr cstr_init(void); // constructor +cstr cstr_new(const char literal_only[]); // constructor cstr cstr_with_capacity(size_t cap); cstr cstr_with_size(size_t len, char fill); // repeat fill len times cstr cstr_from(const char* str); @@ -37,9 +38,9 @@ void cstr_resize(cstr* self, size_t len, char fill); void cstr_clear(cstr* self); cstr* cstr_assign(cstr* self, const char* str); -cstr* cstr_assign_s(cstr* self, cstr s); // cstr_take(self, cstr_clone(s)) cstr* cstr_assign_n(cstr* self, const char* str, size_t n); // assign n first chars of str cstr* cstr_assign_fmt(cstr* self, const char* fmt, ...); // printf() formatting +cstr* cstr_copy(cstr* self, cstr s); // cstr_take(self, cstr_clone(s)) cstr* cstr_append(cstr* self, const char* str); cstr* cstr_append_s(cstr* self, cstr s); @@ -84,9 +85,13 @@ void cstr_next(cstr_iter_t* it); bool cstr_getline(cstr *self, FILE *stream); // cstr_getdelim(self, '\n', stream) bool cstr_getdelim(cstr *self, int delim, FILE *stream); ``` -Helper methods: + +Note that all methods with arguments `(..., const char* str, size_t n)`, `n` must be within the range of `str` length. + +#### Helper methods: ```c -const char* cstr_toraw(const cstr* x); +const char* cstr_toraw(const cstr* self); + int c_rawstr_compare(const char** x, const char** y); bool c_rawstr_equals(const char** x, const char** y); uint64_t c_rawstr_hash(const char* const* x, size_t ignored); @@ -105,26 +110,30 @@ char* c_strncasestr(const char* str, const char* needle, size_t n); ## Constants and macros -| Name | Value | -|:------------------|:-----------------| -| `cstr_npos` | `(-1ull)` | +| Name | Value | +|:------------------|:------------------| +| `cstr_npos` | `((size_t) -1)` | +| `cstr_null | cstr null value | ## Example ```c #include <stc/cstr.h> int main() { - cstr s1 = cstr_from("one-nine-three-seven-five"); - printf("%s.\n", s1.str); + cstr s0 = cstr_new("Initialization without using strlen()."); + printf("%s\nLength: %zu\n\n", s0.str, cstr_size(s0)); + + cstr s1 = cstr_from("one-nine-three-seven-five."); + printf("%s\n", s1.str); cstr_insert(&s1, 3, "-two"); - printf("%s.\n", s1.str); + printf("%s\n", s1.str); cstr_erase_n(&s1, 7, 5); // -nine - printf("%s.\n", s1.str); + printf("%s\n", s1.str); - cstr_replace(&s1, cstr_find(&s1, "seven"), 5, "four"); - printf("%s.\n", s1.str); + cstr_replace(&s1, cstr_find(s1, "seven"), 5, "four"); + printf("%s\n", s1.str); // reassign: cstr_assign(&s1, "one two three four five six seven"); @@ -134,7 +143,7 @@ int main() { cstr full_path = cstr_from_fmt("%s/%s.%s", "directory", "filename", "ext"); printf("%s\n", full_path.str); - c_del(cstr, &s1, &full_path); + c_del(cstr, &s0, &s1, &full_path); } ``` Output: diff --git a/stc/carray.h b/stc/carray.h index 1e0d26c6..d61cbfcf 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -33,7 +33,7 @@ using_carray2(i, int); int main() {
int w = 7, h = 5;
- carray2i image = carray2i_init(w, h, 0);
+ carray2i image = carray2i_init(w, h);
int *dat = carray2i_data(&image);
for (int i = 0; i < carray2i_size(image); ++i)
diff --git a/stc/ccommon.h b/stc/ccommon.h index 37458243..38015d16 100644 --- a/stc/ccommon.h +++ b/stc/ccommon.h @@ -43,7 +43,7 @@ # define STC_API extern
# define STC_DEF
# define STC_LIBRARY_ONLY(...) __VA_ARGS__
-# define STC_STATIC_ONLY(...)
+# define STC_STATIC_ONLY(...)
#else
# define STC_API static inline
# define STC_DEF static inline
@@ -69,9 +69,11 @@ #if __cplusplus
#define c_new(T) static_cast<T*>(c_malloc(sizeof(T)))
#define c_new_n(T, n) static_cast<T*>(c_malloc(sizeof(T)*(n)))
+#define c_cast(T) T
#else
#define c_new(T) c_malloc(sizeof(T))
-#define c_new_n(T, n) c_malloc(sizeof(T[n]))
+#define c_new_n(T, n) c_malloc(sizeof(T)*(n))
+#define c_cast(T) (T)
#endif
#ifndef c_malloc
#define c_malloc(sz) malloc(sz)
@@ -33,14 +33,15 @@ typedef struct { char* str; } cstr;
typedef struct { char *ref; } cstr_iter_t;
typedef char cstr_value_t;
+
#define cstr_npos ((size_t) (-1))
+STC_LIBRARY_ONLY( extern const cstr cstr_null; )
struct cstr_rep { size_t size, cap; char str[sizeof(size_t)]; };
#define _cstr_rep(self) c_container_of((self)->str, struct cstr_rep, str)
-STC_LIBRARY_ONLY( extern const cstr cstr_inits; )
STC_STATIC_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}};
- static const cstr cstr_inits = {_cstr_nullrep.str}; )
-
+ static const cstr cstr_null = {_cstr_nullrep.str}; )
+typedef const char strlit_t[];
/* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */
#define _cstr_opt_mem(cap) ((((offsetof(struct cstr_rep, str) + (cap) + 8)>>4)<<4) + 8)
/* optimal string capacity: 7, 23, 39, ... */
@@ -64,25 +65,27 @@ STC_API int c_strncasecmp(const char* s1, const char* s2, size_t n); STC_API char* c_strnstr(const char* s, const char* needle, size_t nmax);
STC_API char* c_strncasestr(const char* s, const char* needle, size_t nmax);
-STC_INLINE cstr cstr_init() { return cstr_inits; }
+STC_INLINE cstr cstr_init() { return cstr_null; }
+#define cstr_new(literal) \
+ cstr_from_n(literal, sizeof c_cast(strlit_t){literal} - 1)
+STC_INLINE cstr cstr_from(const char* str)
+ { return cstr_from_n(str, strlen(str)); }
STC_INLINE size_t cstr_size(cstr s) { return _cstr_rep(&s)->size; }
+STC_INLINE size_t cstr_length(cstr s) { return _cstr_rep(&s)->size; }
STC_INLINE size_t cstr_capacity(cstr s) { return _cstr_rep(&s)->cap; }
STC_INLINE size_t cstr_empty(cstr s) { return _cstr_rep(&s)->size == 0; }
-STC_INLINE size_t cstr_length(cstr s) { return _cstr_rep(&s)->size; }
STC_INLINE void cstr_del(cstr* self)
{ if (_cstr_rep(self)->cap) c_free(_cstr_rep(self)); }
-STC_INLINE cstr cstr_from(const char* str)
- { return cstr_from_n(str, cstr_npos); }
STC_INLINE cstr cstr_clone(cstr s)
{ return cstr_from_n(s.str, _cstr_rep(&s)->size); }
STC_INLINE void cstr_clear(cstr* self)
{ self->str[_cstr_rep(self)->size = 0] = '\0'; }
STC_INLINE cstr* cstr_assign(cstr* self, const char* str)
- { return cstr_assign_n(self, str, cstr_npos); }
-STC_INLINE cstr* cstr_assign_s(cstr* self, cstr s)
+ { return cstr_assign_n(self, str, strlen(str)); }
+STC_INLINE cstr* cstr_copy(cstr* self, cstr s)
{ return cstr_assign_n(self, s.str, _cstr_rep(&s)->size); }
STC_INLINE cstr* cstr_append(cstr* self, const char* str)
- { return cstr_append_n(self, str, cstr_npos); }
+ { return cstr_append_n(self, str, strlen(str)); }
STC_INLINE cstr* cstr_append_s(cstr* self, cstr s)
{ return cstr_append_n(self, s.str, _cstr_rep(&s)->size); }
STC_INLINE void cstr_push_back(cstr* self, char value)
@@ -92,11 +95,11 @@ STC_INLINE void cstr_pop_back(cstr* self) STC_INLINE void cstr_insert_n(cstr* self, size_t pos, const char* str, size_t n)
{ cstr_replace_n(self, pos, 0, str, n); }
STC_INLINE void cstr_insert(cstr* self, size_t pos, const char* str)
- { cstr_replace_n(self, pos, 0, str, cstr_npos); }
+ { cstr_replace_n(self, pos, 0, str, strlen(str)); }
STC_INLINE void cstr_insert_s(cstr* self, size_t pos, cstr s)
{ cstr_replace_n(self, pos, 0, s.str, _cstr_rep(&s)->size); }
STC_INLINE void cstr_replace(cstr* self, size_t pos, size_t len, const char* str)
- { cstr_replace_n(self, pos, len, str, cstr_npos); }
+ { cstr_replace_n(self, pos, len, str, strlen(str)); }
STC_INLINE void cstr_replace_s(cstr* self, size_t pos, size_t len, cstr s)
{ cstr_replace_n(self, pos, len, s.str, _cstr_rep(&s)->size); }
STC_INLINE void cstr_erase(cstr* self, size_t pos)
@@ -105,9 +108,9 @@ STC_INLINE char* cstr_front(cstr* self) { return self->str; } STC_INLINE char* cstr_back(cstr* self)
{ return self->str + _cstr_rep(self)->size - 1; }
STC_INLINE cstr_iter_t cstr_begin(cstr* self)
- { cstr_iter_t it = {self->str}; return it; }
+ { return c_cast(cstr_iter_t){self->str}; }
STC_INLINE cstr_iter_t cstr_end(cstr* self)
- { cstr_iter_t it = {self->str + _cstr_rep(self)->size}; return it; }
+ { return c_cast(cstr_iter_t){self->str + _cstr_rep(self)->size}; }
STC_INLINE void cstr_next(cstr_iter_t* it) {++it->ref; }
STC_INLINE bool cstr_equals(cstr s1, const char* str)
{ return strcmp(s1.str, str) == 0; }
@@ -128,14 +131,14 @@ STC_INLINE bool cstr_getline(cstr *self, FILE *stream) STC_INLINE cstr
cstr_with_capacity(size_t cap) {
- cstr s = cstr_inits;
+ cstr s = cstr_null;
cstr_reserve(&s, cap);
return s;
}
STC_INLINE cstr
cstr_with_size(size_t len, char fill) {
- cstr s = cstr_inits;
+ cstr s = cstr_null;
cstr_resize(&s, len, fill);
return s;
}
@@ -151,7 +154,7 @@ cstr_take(cstr* self, cstr s) { STC_INLINE cstr
cstr_move(cstr* self) {
cstr tmp = *self;
- *self = cstr_inits;
+ *self = cstr_null;
return tmp;
}
@@ -179,7 +182,7 @@ cstr_iends_with(cstr s, const char* needle) { #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
STC_LIBRARY_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}};
- const cstr cstr_inits = {_cstr_nullrep.str}; )
+ const cstr cstr_null = {_cstr_nullrep.str}; )
STC_DEF size_t
cstr_reserve(cstr* self, size_t cap) {
@@ -204,8 +207,7 @@ cstr_resize(cstr* self, size_t len, char fill) { STC_DEF cstr
cstr_from_n(const char* str, size_t n) {
- if (n == 0) return cstr_inits;
- size_t sz = strlen(str); if (n > sz) n = sz;
+ if (n == 0) return cstr_null;
struct cstr_rep* rep = (struct cstr_rep*) c_malloc(_cstr_opt_mem(n));
cstr s = {(char *) memcpy(rep->str, str, n)};
s.str[rep->size = n] = '\0';
@@ -240,7 +242,7 @@ cstr_vfmt(cstr* self, const char* fmt, va_list args) { STC_DEF cstr
cstr_from_fmt(const char* fmt, ...) {
- cstr ret = cstr_inits;
+ cstr ret = cstr_null;
va_list args; va_start(args, fmt);
cstr_vfmt(&ret, fmt, args);
va_end(args);
@@ -249,7 +251,7 @@ cstr_from_fmt(const char* fmt, ...) { STC_DEF cstr*
cstr_assign_fmt(cstr* self, const char* fmt, ...) {
- cstr ret = cstr_inits;
+ cstr ret = cstr_null;
va_list args; va_start(args, fmt);
cstr_vfmt(&ret, fmt, args);
va_end(args);
@@ -259,7 +261,6 @@ cstr_assign_fmt(cstr* self, const char* fmt, ...) { STC_DEF cstr*
cstr_assign_n(cstr* self, const char* str, size_t n) {
- size_t sz = strlen(str); if (n > sz) n = sz;
if (n || _cstr_rep(self)->cap) {
cstr_reserve(self, n);
memmove(self->str, str, n);
@@ -271,7 +272,6 @@ cstr_assign_n(cstr* self, const char* str, size_t n) { STC_DEF cstr*
cstr_append_n(cstr* self, const char* str, size_t n) {
if (n == 0) return self;
- size_t sz = strlen(str); if (n > sz) n = sz;
size_t oldlen = _cstr_rep(self)->size, newlen = oldlen + n;
if (newlen > _cstr_rep(self)->cap) {
size_t off = (size_t) (str - self->str); /* handle self append */
@@ -297,7 +297,6 @@ STC_DEF void cstr_replace_n(cstr* self, size_t pos, size_t len, const char* str, size_t n) {
size_t sz = cstr_size(*self);
if (len > sz - pos) len = sz - pos;
- sz = strlen(str); if (n > sz) n = sz;
c_withbuffer (xstr, char, n) {
memcpy(xstr, str, n);
_cstr_internal_move(self, pos + len, pos + n);
@@ -307,15 +306,15 @@ cstr_replace_n(cstr* self, size_t pos, size_t len, const char* str, size_t n) { STC_DEF size_t
cstr_replace_all(cstr* self, const char* find, const char* replace) {
- cstr out = cstr_inits;
- size_t find_len = strlen(find), from = 0, n = 0, pos;
+ cstr out = cstr_null;
+ size_t find_len = strlen(find), repl_len = strlen(replace), from = 0, n = 0, pos;
while ((pos = cstr_find_n(*self, find, from, cstr_npos)) != cstr_npos) {
cstr_append_n(&out, self->str + from, pos - from );
- cstr_append(&out, replace);
+ cstr_append_n(&out, replace, repl_len);
from = pos + find_len; ++n;
}
if (!n) return 0;
- cstr_append(&out, self->str + from);
+ cstr_append_n(&out, self->str + from, cstr_size(*self) - from);
cstr_del(self); *self = out;
return n;
}
|
