diff options
| author | Tyge Løvset <[email protected]> | 2021-05-27 10:07:57 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-05-27 10:07:57 +0200 |
| commit | c7a6f7c17e2d2a2b0144cbec87f4b2c93e8150dd (patch) | |
| tree | ea7c569309072360d0c439db6e5c09aa10371bd6 | |
| parent | b840bc032d8500379888caf93702ab057e712937 (diff) | |
| download | STC-modified-c7a6f7c17e2d2a2b0144cbec87f4b2c93e8150dd.tar.gz STC-modified-c7a6f7c17e2d2a2b0144cbec87f4b2c93e8150dd.zip | |
Made substr() and slice() only returning csview. Added Both cstr and csview input argument variants. Changed def of cstr_npos.
| -rw-r--r-- | docs/clist_api.md | 20 | ||||
| -rw-r--r-- | docs/cstr_api.md | 16 | ||||
| -rw-r--r-- | docs/csview_api.md | 40 | ||||
| -rw-r--r-- | examples/splitstr.c | 2 | ||||
| -rw-r--r-- | include/stc/clist.h | 6 | ||||
| -rw-r--r-- | include/stc/cstr.h | 13 | ||||
| -rw-r--r-- | include/stc/csview.h | 41 |
7 files changed, 82 insertions, 56 deletions
diff --git a/docs/clist_api.md b/docs/clist_api.md index 909a8e54..4a9b7f92 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -48,10 +48,10 @@ clist_X clist_X_init(void); clist_X clist_X_clone(clist_X list); void clist_X_clear(clist_X* self); -void clist_X_del(clist_X* self); // destructor +void clist_X_del(clist_X* self); // destructor bool clist_X_empty(clist_X list); -size_t clist_X_count(clist_X list); // size() in O(n) time +size_t clist_X_count(clist_X list); // size() in O(n) time clist_X_value_t* clist_X_front(const clist_X* self); clist_X_value_t* clist_X_back(const clist_X* self); @@ -60,21 +60,21 @@ void clist_X_push_front(clist_X* self, Value value); void clist_X_emplace_front(clist_X* self, RawValue raw); void clist_X_pop_front(clist_X* self); -void clist_X_push_back(clist_X* self, Value value); // note: no pop_back(). +void clist_X_push_back(clist_X* self, Value value); // note: no pop_back(). void clist_X_emplace_back(clist_X* self, RawValue raw); void clist_X_emplace_items(clist_X *self, const clist_X_rawvalue_t arr[], size_t n); -clist_X_iter_t clist_X_insert(clist_X* self, clist_X_iter_t it, Value value); // return iter to new elem +clist_X_iter_t clist_X_insert(clist_X* self, clist_X_iter_t it, Value value); // return iter to new elem clist_X_iter_t clist_X_emplace(clist_X* self, clist_X_iter_t it, RawValue raw); -clist_X_iter_t clist_X_erase(clist_X* self, clist_X_iter_t it); // return iter after it -clist_X_iter_t clist_X_erase_at(clist_X* self, clist_X_iter_t it); // alias for erase() +clist_X_iter_t clist_X_erase(clist_X* self, clist_X_iter_t it); // return iter after it +clist_X_iter_t clist_X_erase_at(clist_X* self, clist_X_iter_t it); // alias for erase() clist_X_iter_t clist_X_erase_range(clist_X* self, clist_X_iter_t it1, clist_X_iter_t it2); -size_t clist_X_remove(clist_X* self, RawValue raw); // removes all elements equal to raw +size_t clist_X_remove(clist_X* self, RawValue raw); // removes matching elements -clist_X clist_X_split(clist_X* self, clist_X_iter_t it1, clist_X_iter_t it2); // split out [it1, it2) -clist_X_iter_t clist_X_splice(clist_X* self, clist_X_iter_t it, clist_X* other); // return updated valid it -clist_X_iter_t clist_X_splice_range(clist_X* self, clist_X_iter_t it, // return updated valid it +clist_X clist_X_split_off(clist_X* self, clist_X_iter_t i1, clist_X_iter_t i2); // split off [i1, i2) +clist_X_iter_t clist_X_splice(clist_X* self, clist_X_iter_t it, clist_X* other); // return updated valid it +clist_X_iter_t clist_X_splice_range(clist_X* self, clist_X_iter_t it, // return updated valid it clist_X* other, clist_X_iter_t it1, clist_X_iter_t it2); clist_X_iter_t clist_X_find(const clist_X* self, RawValue raw); diff --git a/docs/cstr_api.md b/docs/cstr_api.md index 26450ac7..a38718bc 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -41,9 +41,7 @@ cstr* cstr_assign(cstr* self, const char* str); 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_substr(cstr* self, intptr_t pos, size_t n); // negative pos count from end -cstr* cstr_slice(cstr* self, intptr_t p1, intptr_t p2); // negative p1,p2 count from end. - // substr(), slice() modifies self + cstr* cstr_append(cstr* self, const char* str); cstr* cstr_append_s(cstr* self, cstr s); cstr* cstr_append_n(cstr* self, const char* str, size_t n); @@ -63,17 +61,17 @@ void cstr_erase_n(cstr* self, size_t pos, size_t n); int cstr_compare(const cstr *s1, const cstr *s2); bool cstr_equals(cstr s, const char* str); bool cstr_equals_s(cstr s, cstr s2); -size_t cstr_find(cstr s, const char* substr); +size_t cstr_find(cstr s, const char* needle); size_t cstr_find_n(cstr s, const char* needle, size_t pos, size_t nmax); bool cstr_contains(cstr s, const char* needle); -bool cstr_begins_with(cstr s, const char* substr); -bool cstr_ends_with(cstr s, const char* substr); +bool cstr_begins_with(cstr s, const char* str); +bool cstr_ends_with(cstr s, const char* str); bool cstr_iequals(cstr s, const char* str); // prefix i = case-insensitive size_t cstr_ifind_n(cstr s, const char* needle, size_t pos, size_t nmax); bool cstr_icontains(cstr s, const char* needle); -bool cstr_ibegins_with(cstr s, const char* substr); -bool cstr_iends_with(cstr s, const char* substr); +bool cstr_ibegins_with(cstr s, const char* str); +bool cstr_iends_with(cstr s, const char* str); void cstr_push_back(cstr* self, char ch); void cstr_pop_back(cstr* self); @@ -114,7 +112,7 @@ char* c_strncasestrn(const char* str, const char* needle, size_t slen, si | Name | Value | |:------------------|:------------------| -| `cstr_npos` | `((size_t) -1)` | +| `cstr_npos` | `INTPTR_MAX` | | `cstr_null` | cstr null value | ## Example diff --git a/docs/csview_api.md b/docs/csview_api.md index 63b84a1d..b23ec9c2 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -10,7 +10,7 @@ when passing it around. It is faster when using`csview` as convertion type (raw) containers with cstr keys. E.g. prefer `using_cmap_svkey()` over `using_cmap_strkey()`. Note that a **csview** may not be null-terminated, and should therefore be printed the following way: -`printf("%.*s", csview_arg(sv))`. +`printf("%.*s", csview_ARG(sv))`. See the c++ class [std::basic_string_view](https://en.cppreference.com/w/cpp/string/basic_string_view) for a functional description. @@ -38,7 +38,7 @@ bool csview_empty(csview sv); void csview_clear(csview* self); csview csview_substr(csview sv, intptr_t pos, size_t n); // negative pos count from end -csview csview_slice(csview sv, intptr_t p1, intptr_t p2); // negative p1,p2 count from end +csview csview_slice(csview sv, intptr_t p1, intptr_t p2); // negative p1, p2 count from end csview csview_first_token(csview sv, csview sep); // see split example below. csview csview_next_token(csview sv, csview sep, csview token); @@ -59,6 +59,8 @@ void csview_next(csview_iter_t* it); ```c cstr cstr_from_v(csview sv); csview cstr_to_v(const cstr* self); +csview cstr_substr(cstr s, intptr_t pos, size_t n); // negative pos count from end +csview cstr_slice(cstr s, intptr_t p1, intptr_t p2); // negative p1, p2 count from end cstr* cstr_assign_v(cstr* self, csview sv); cstr* cstr_append_v(cstr* self, csview sv); void cstr_insert_v(cstr* self, size_t pos, csview sv); @@ -90,7 +92,7 @@ uint64_t csview_hash_ref(const csview* x, size_t ignored); |:-----------------|:--------------------|:----------------------------------| | `csview_null` | same as `c_lit("")` | `sview = csview_null;` | | `c_lit(literal)` | csview constructor | `sview = c_lit("hello, world");` | -| `csview_arg(sv)` | printf argument | `printf("%.*s", csview_arg(sv));` | +| `csview_ARG(sv)` | printf argument | `printf("%.*s", csview_ARG(sv));` | ## cstr-containers with csview emplace/lookup API ``` @@ -159,7 +161,7 @@ void print_split(csview str, csview sep) csview token = csview_first_token(str, sep); for (;;) { // print non-null-terminated csview - printf("\"%.*s\"\n", csview_arg(token)); + printf("\"%.*s\"\n", csview_ARG(token)); if (csview_end(&token).ref == csview_end(&str).ref) break; token = csview_next_token(str, sep, token); } @@ -208,3 +210,33 @@ Output: "now" "" ``` +### Example 3 +```c +#include <stc/csview.h> + +int main () +{ + cstr str1 = cstr_lit("We think in generalities, but we live in details."); + // (quoting Alfred N. Whitehead) + + csview sv1 = cstr_substr(str1, 3, 5); // "think" + size_t pos = cstr_find(str1, "live"); // position of "live" in str + csview sv2 = cstr_substr(str1, pos, cstr_npos); // get from "live" to the end + + printf("%.*s %.*s\n", csview_ARG(sv1), csview_ARG(sv2)); + + cstr s1 = cstr_lit("Apples are red"); + cstr s2 = cstr_from_v(cstr_substr(s1, 11, 3)); // "red" + printf("%s\n", s2.str); + cstr s3 = cstr_from_v(cstr_substr(s1, 0, 6)); // "Apples" + printf("%s\n", s3.str); + + c_del(cstr, &str1, &s1, &s2, &s3); +} +``` +Output: +``` +think live in details. +red +Apples +```
\ No newline at end of file diff --git a/examples/splitstr.c b/examples/splitstr.c index ba49ddcf..b6c703b4 100644 --- a/examples/splitstr.c +++ b/examples/splitstr.c @@ -6,7 +6,7 @@ void print_split(csview str, csview sep) csview token = csview_first_token(str, sep);
for (;;) {
// print non-null-terminated csview
- printf("\t\"%.*s\"\n", csview_arg(token));
+ printf("\t\"%.*s\"\n", csview_ARG(token));
if (csview_end(&token).ref == csview_end(&str).ref) break;
token = csview_next_token(str, sep, token);
}
diff --git a/include/stc/clist.h b/include/stc/clist.h index f07aa9d6..496fc9d5 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -110,7 +110,7 @@ STC_API size_t _clist_count(const clist_VOID* self); STC_API CX##_iter_t CX##_erase_range(CX* self, CX##_iter_t it1, CX##_iter_t it2); \
STC_API size_t CX##_remove(CX* self, RawValue val); \
STC_API CX##_iter_t CX##_splice(CX* self, CX##_iter_t it, CX* other); \
- STC_API CX CX##_split(CX* self, CX##_iter_t it1, CX##_iter_t it2); \
+ STC_API CX CX##_split_off(CX* self, CX##_iter_t it1, CX##_iter_t it2); \
STC_API void CX##_sort(CX* self); \
STC_API CX##_iter_t CX##_find_in(CX##_iter_t it1, CX##_iter_t it2, RawValue val); \
STC_API CX##_node_t* CX##_erase_after_(CX* self, CX##_node_t* node); \
@@ -168,7 +168,7 @@ STC_API size_t _clist_count(const clist_VOID* self); STC_INLINE CX##_iter_t \
CX##_splice_range(CX* self, CX##_iter_t it, \
CX* other, CX##_iter_t it1, CX##_iter_t it2) { \
- CX tmp = CX##_split(other, it1, it2); \
+ CX tmp = CX##_split_off(other, it1, it2); \
return CX##_splice(self, it, &tmp); \
} \
\
@@ -297,7 +297,7 @@ STC_API size_t _clist_count(const clist_VOID* self); } \
\
STC_DEF CX \
- CX##_split(CX* self, CX##_iter_t it1, CX##_iter_t it2) { \
+ CX##_split_off(CX* self, CX##_iter_t it1, CX##_iter_t it2) { \
CX cx = {NULL}; \
if (it1.ref == it2.ref) return cx; \
CX##_node_t *p1 = it1.prev, \
diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 7b7fdaa6..8f5841eb 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -34,7 +34,7 @@ typedef struct { char* str; } cstr; typedef struct { char *ref; } cstr_iter_t;
typedef char cstr_value_t;
-#define cstr_npos ((size_t) (-1))
+#define cstr_npos INTPTR_MAX
STC_LIBRARY_ONLY( extern const cstr cstr_null; )
struct cstr_rep { size_t size, cap; char str[sizeof(size_t)]; };
@@ -61,6 +61,7 @@ STC_API size_t cstr_find(cstr s, const char* needle); STC_API size_t cstr_find_n(cstr s, const char* needle, size_t pos, size_t nmax);
STC_API size_t cstr_ifind_n(cstr s, const char* needle, size_t pos, size_t nmax);
STC_API bool cstr_getdelim(cstr *self, int delim, FILE *stream);
+
STC_API int c_strncasecmp(const char* s1, const char* s2, size_t nmax);
STC_API char* c_strnstrn(const char* s, const char* needle, size_t slen, size_t nmax);
STC_API char* c_strncasestrn(const char* s, const char* needle, size_t slen, size_t nmax);
@@ -78,16 +79,6 @@ STC_INLINE void cstr_del(cstr* self) { if (_cstr_rep(self)->cap) c_free(_cstr_rep(self)); }
STC_INLINE cstr cstr_clone(cstr s)
{ return cstr_from_n(s.str, _cstr_rep(&s)->size); }
-STC_INLINE cstr* cstr_substr(cstr* self, intptr_t pos, size_t n) {
- size_t sz = _cstr_rep(self)->size;
- if (pos < 0) pos += sz; if (pos + n > sz) n = sz - pos;
- return cstr_assign_n(self, self->str + pos, n);
- }
-STC_INLINE cstr* cstr_slice(cstr* self, intptr_t p1, intptr_t p2) {
- size_t sz = _cstr_rep(self)->size;
- if (p1 < 0) p1 += sz; if (p2 < 0) p2 += sz; if (p2 > sz) p2 = sz;
- return cstr_assign_n(self, self->str + p1, p2 > p1 ? p2 - p1 : 0);
- }
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)
diff --git a/include/stc/csview.h b/include/stc/csview.h index 7d6946ca..9cfef3b6 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -29,7 +29,7 @@ typedef struct { const char* str; size_t size; } csview; typedef struct { const char *ref; } csview_iter_t;
typedef char csview_value_t;
#define csview_null c_make(csview){"", 0}
-#define csview_arg(sv) (int)(sv).size, (sv).str
+#define csview_ARG(sv) (int)(sv).size, (sv).str
#define c_lit(literal) csview_lit(literal)
#define c_sv(s) csview_from_s(s)
@@ -42,16 +42,6 @@ STC_INLINE csview csview_from_n(const char* str, size_t n) { return c_make(csview){str, n}; }
STC_INLINE csview csview_from_s(cstr s)
{ return c_make(csview){s.str, _cstr_rep(&s)->size}; }
-STC_INLINE csview csview_substr(csview sv, intptr_t pos, size_t n) {
- if (pos < 0) pos += sv.size;
- if (pos + n > sv.size) n = sv.size - pos;
- sv.str += pos, sv.size = n; return sv;
- }
-STC_INLINE csview csview_slice(csview sv, intptr_t p1, intptr_t p2) {
- if (p1 < 0) p1 += sv.size; if (p2 < 0) p2 += sv.size;
- if (p2 > sv.size) p2 = sv.size;
- sv.str += p1, sv.size = p2 > p1 ? p2 - p1 : 0; return sv;
- }
STC_INLINE size_t csview_size(csview sv) { return sv.size; }
STC_INLINE size_t csview_length(csview sv) { return sv.size; }
STC_INLINE bool csview_empty(csview sv) { return sv.size == 0; }
@@ -79,20 +69,31 @@ STC_INLINE csview_iter_t csview_end(const csview* self) { return c_make(csview_iter_t){self->str + self->size}; }
STC_INLINE void csview_next(csview_iter_t* it) { ++it->ref; }
+STC_INLINE csview csview_substr(csview sv, intptr_t pos, size_t n) {
+ if (pos < 0) pos += sv.size;
+ if (pos + n > sv.size) n = sv.size - pos;
+ sv.str += pos, sv.size = n; return sv;
+}
+
+STC_INLINE csview csview_slice(csview sv, intptr_t p1, intptr_t p2) {
+ if (p1 < 0) p1 += sv.size; if (p2 < 0) p2 += sv.size;
+ if (p2 > sv.size) p2 = sv.size;
+ sv.str += p1, sv.size = p2 > p1 ? p2 - p1 : 0; return sv;
+}
STC_INLINE csview csview_first_token(csview sv, csview sep) {
const char* res = c_strnstrn(sv.str, sep.str, sv.size, sep.size);
return c_make(csview){sv.str, (res ? res - sv.str : sv.size)};
}
-STC_INLINE csview csview_next_token(csview sv, csview sep, csview token) {
- if (&token.str[token.size] == &sv.str[sv.size])
+STC_INLINE csview csview_next_token(csview sv, csview sep, csview tok) {
+ if (&tok.str[tok.size] == &sv.str[sv.size])
return c_make(csview){&sv.str[sv.size], 0};
- token.str += token.size + sep.size;
- size_t n = sv.size - (token.str - sv.str);
- const char* res = c_strnstrn(token.str, sep.str, n, sep.size);
- token.size = res ? res - token.str : n;
- return token;
+ tok.str += tok.size + sep.size;
+ size_t n = sv.size - (tok.str - sv.str);
+ const char* res = c_strnstrn(tok.str, sep.str, n, sep.size);
+ tok.size = res ? res - tok.str : n;
+ return tok;
}
/* cstr interaction with csview: */
@@ -101,6 +102,10 @@ STC_INLINE cstr cstr_from_v(csview sv) { return cstr_from_n(sv.str, sv.size); }
STC_INLINE csview cstr_to_v(const cstr* self)
{ return c_make(csview){self->str, _cstr_rep(self)->size}; }
+STC_INLINE csview cstr_substr(cstr s, intptr_t pos, size_t n)
+ { return csview_substr(csview_from_s(s), pos, n); };
+STC_INLINE csview cstr_slice(cstr s, intptr_t p1, intptr_t p2)
+ { return csview_slice(csview_from_s(s), p1, p2); };
STC_INLINE cstr* cstr_assign_v(cstr* self, csview sv)
{ return cstr_assign_n(self, sv.str, sv.size); }
STC_INLINE cstr* cstr_append_v(cstr* self, csview sv)
|
