summaryrefslogtreecommitdiffhomepage
path: root/docs/cstr_api.md
blob: 9d9bd36e7512e04d62f09b8b5903621e936b5921 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# STC [cstr](../stc/cstr.h): String
![String](pics/string.jpg)

A **cstr** object represent sequences of characters. It supports an interface similar to that of a standard container of bytes, but adding features specifically designed to operate with strings of single-byte characters, terminated by the null character.

See the c++ class [std::basic_string](https://en.cppreference.com/w/cpp/string/basic_string) for a functional description.

## Header file

All cstr definitions and prototypes are available by including a single header file.

```c
#include <stc/cstr.h>
```
## Methods

```c
cstr         cstr_init(void);                                         // 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);
cstr         cstr_from_n(const char* str, size_t n);
cstr         cstr_from_fmt(const char* fmt, ...);                     // printf() formatting
cstr         cstr_clone(cstr s);

cstr*        cstr_take(cstr* self, cstr s);                           // take the constructed or moved string
cstr         cstr_move(cstr* self);                                   // move string to caller, leave empty string
void         cstr_del(cstr *self);                                    // destructor

size_t       cstr_size(cstr s);
size_t       cstr_length(cstr s);
size_t       cstr_capacity(cstr s);
bool         cstr_empty(cstr s);

size_t       cstr_reserve(cstr* self, size_t capacity);
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);
cstr*        cstr_assign_fmt(cstr* self, const char* fmt, ...);       // printf() formatting

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);    // appends n characters
cstr*        cstr_append_fmt(cstr* self, const char* fmt, ...);       // printf() formatting

void         cstr_insert(cstr* self, size_t pos, const char* str);
void         cstr_insert_s(cstr* self, size_t pos, cstr s);
void         cstr_insert_n(cstr* self, size_t pos, const char* str, size_t n);

void         cstr_replace(cstr* self, size_t pos, size_t len, const char* str);
void         cstr_replace_s(cstr* self, size_t pos, size_t len, cstr s);
void         cstr_replace_n(cstr* self, size_t pos, size_t len, const char* str, size_t n);
size_t       cstr_replace_all(cstr* self, const char* find, const char* replace);

void         cstr_erase(cstr* self, size_t pos);
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_n(cstr s, const char* substr, size_t pos, size_t n);
bool         cstr_contains(cstr s, const char* substr);
bool         cstr_begins_with(cstr s, const char* substr);
bool         cstr_ends_with(cstr s, const char* substr);

bool         cstr_iequals(cstr s, const char* str);                   // prefix i = case-insensitive
size_t       cstr_ifind_n(cstr s, const char* substr, size_t pos, size_t n);
bool         cstr_icontains(cstr s, const char* substr);
bool         cstr_ibegins_with(cstr s, const char* substr);
bool         cstr_iends_with(cstr s, const char* substr);

void         cstr_push_back(cstr* self, char ch);
void         cstr_pop_back(cstr* self);
char*        cstr_front(cstr* self);
char*        cstr_back(cstr* self);

cstr_iter_t  cstr_begin(cstr* self);
cstr_iter_t  cstr_end(cstr* self);
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:
```c
const char*  cstr_toraw(const cstr* x);
int          c_rstr_compare(const char** x, const char** y);
bool         c_rstr_equals(const char** x, const char** y);
uint64_t     c_rstr_hash(const char* const* x, size_t ignored);
int          c_strncasecmp(const char* str1, const char* str2, size_t n);
char*        c_strnstr(const char* str, const char* needle, size_t n);
char*        c_strncasestr(const char* str, const char* needle, size_t n);
```

## Types

| Type name         | Type definition                  | Used to represent...     |
|:------------------|:---------------------------------|:-------------------------|
| `cstr`            | `struct { const char *str; }`    | The string type          |
| `cstr_value_t`    | `char`                           | The string element type  |
| `cstr_iter_t`     | `struct { cstr_value_t *ref; }`  | cstr iterator            |

## Constants and macros

| Name              | Value            |
|:------------------|:-----------------|
|  `cstr_npos`      | `(-1ull)`        |

## Example
```c
#include <stc/cstr.h>

int main() {
    cstr s1 = cstr_from("one-nine-three-seven-five");
    printf("%s.\n", s1.str);

    cstr_insert(&s1, 3, "-two");
    printf("%s.\n", s1.str);

    cstr_erase_n(&s1, 7, 5); // -nine
    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");
    cstr_append(&s1, " eight");
    printf("append: %s\n", s1.str);

    cstr full_path = cstr_from_fmt("%s/%s.%s", "directory", "filename", "ext");
    printf("%s\n", full_path.str);

    c_del(cstr, &s1, &full_path);
}
```
Output:
```
one-nine-three-seven-five.
one-two-nine-three-seven-five.
one-two-three-seven-five.
one-two-three-four-five.
append: one two three four five six seven eight
directory/filename.ext
```