1 |
#include <string.h> |
2 |
#include <ctype.h> |
3 |
#include <stdbool.h> |
4 |
#include <stdlib.h> |
5 |
#include <stdarg.h> |
6 |
#include "strutils.h" |
7 |
#include "xmalloc.h" |
8 |
|
9 |
/** |
10 |
* @brief Allocates a buffer and stores the left-trimmed string into it. |
11 |
*/ |
12 |
char *str_ltrim(const char *restrict str) |
13 |
{ |
14 |
size_t length = strlen(str); |
15 |
|
16 |
if (length == 0) |
17 |
{ |
18 |
return strdup(str); |
19 |
} |
20 |
|
21 |
char *outstr = xmalloc(length + 1); |
22 |
bool is_start = true; |
23 |
size_t j = 0; |
24 |
|
25 |
for (size_t i = 0; i < length; i++) |
26 |
{ |
27 |
if (is_start && isspace(str[i])) |
28 |
continue; |
29 |
else if (is_start) |
30 |
is_start = false; |
31 |
|
32 |
outstr[j++] = str[i]; |
33 |
} |
34 |
|
35 |
outstr[j] = 0; |
36 |
return outstr; |
37 |
} |
38 |
|
39 |
/** |
40 |
* @brief Allocates a buffer and stores the right-trimmed string into it. |
41 |
*/ |
42 |
char *str_rtrim(const char *restrict str) |
43 |
{ |
44 |
size_t length = strlen(str); |
45 |
|
46 |
if (length == 0) |
47 |
{ |
48 |
return strdup(str); |
49 |
} |
50 |
|
51 |
char *outstr = xmalloc(length + 1); |
52 |
size_t spaces = 0; |
53 |
|
54 |
for (size_t i = length;; i--) |
55 |
{ |
56 |
if (str[i] == 0) |
57 |
continue; |
58 |
|
59 |
if (isspace(str[i])) |
60 |
spaces++; |
61 |
else |
62 |
break; |
63 |
|
64 |
if (i == 0) |
65 |
break; |
66 |
} |
67 |
|
68 |
for (size_t i = 0; i < (length - spaces); i++) |
69 |
{ |
70 |
outstr[i] = str[i]; |
71 |
} |
72 |
|
73 |
outstr[length - spaces] = 0; |
74 |
return outstr; |
75 |
} |
76 |
|
77 |
/** |
78 |
* @brief Allocates a buffer and stores the both right and left-trimmed string into it. |
79 |
*/ |
80 |
char *str_trim(const char *restrict str) |
81 |
{ |
82 |
char *ltrimmed = str_ltrim(str); |
83 |
char *final = str_rtrim(ltrimmed); |
84 |
free(ltrimmed); |
85 |
return final; |
86 |
} |
87 |
|
88 |
bool str_starts_with(const char *restrict haystack, const char *restrict needle) |
89 |
{ |
90 |
size_t haystack_length = strlen(haystack); |
91 |
size_t needle_length = strlen(needle); |
92 |
|
93 |
if (haystack_length < needle_length) |
94 |
{ |
95 |
return false; |
96 |
} |
97 |
|
98 |
for (size_t i = 0; i < needle_length; i++) |
99 |
{ |
100 |
if (haystack[i] != needle[i]) |
101 |
{ |
102 |
return false; |
103 |
} |
104 |
} |
105 |
|
106 |
return true; |
107 |
} |
108 |
|
109 |
char *str_concat_varg(const char *start, ...) |
110 |
{ |
111 |
va_list args; |
112 |
char *buffer = strdup(start); |
113 |
size_t length = strlen(start); |
114 |
|
115 |
va_start(args, start); |
116 |
|
117 |
while (true) |
118 |
{ |
119 |
const char *part = va_arg(args, const char *); |
120 |
size_t part_length; |
121 |
|
122 |
if (part == NULL) |
123 |
break; |
124 |
|
125 |
part_length = strlen(part); |
126 |
length += part_length; |
127 |
buffer = xrealloc(buffer, length); |
128 |
strncat(buffer, part, part_length); |
129 |
} |
130 |
|
131 |
va_end(args); |
132 |
return buffer; |
133 |
} |