2023-12-05 00:00:08 +01:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
char **str_split(char* a_str, const char a_delim)
|
|
|
|
{
|
|
|
|
char** result = 0;
|
|
|
|
size_t count = 0;
|
|
|
|
char* tmp = a_str;
|
|
|
|
char* last_comma = 0;
|
|
|
|
char delim[2];
|
|
|
|
delim[0] = a_delim;
|
|
|
|
delim[1] = 0;
|
|
|
|
/* Count how many elements will be extracted. */
|
|
|
|
while (*tmp)
|
|
|
|
{
|
|
|
|
if (a_delim == *tmp)
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
last_comma = tmp;
|
|
|
|
}
|
|
|
|
tmp++;
|
|
|
|
}
|
|
|
|
/* Add space for trailing token. */
|
|
|
|
count += last_comma < (a_str + strlen(a_str) - 1);
|
|
|
|
/* Add space for terminating null string so caller
|
|
|
|
knows where the list of returned strings ends. */
|
|
|
|
count++;
|
|
|
|
result = malloc(sizeof(char*) * count);
|
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
size_t idx = 0;
|
|
|
|
char* token = strtok(a_str, delim);
|
|
|
|
while (token)
|
|
|
|
{
|
|
|
|
assert(idx < count);
|
|
|
|
*(result + idx++) = strdup(token);
|
|
|
|
token = strtok(0, delim);
|
|
|
|
}
|
|
|
|
assert(idx == count - 1);
|
|
|
|
*(result + idx) = 0;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Note: This function returns a pointer to a substring of the original string.
|
|
|
|
// If the given string was allocated dynamically, the caller must not overwrite
|
|
|
|
// that pointer with the returned value, since the original pointer must be
|
|
|
|
// deallocated using the same allocator with which it was allocated. The return
|
|
|
|
// value must NOT be deallocated using free() etc.
|
|
|
|
char *trimwhitespace(char *str)
|
|
|
|
{
|
|
|
|
char *end;
|
|
|
|
// Trim leading space
|
|
|
|
while(isspace((unsigned char)*str)) str++;
|
|
|
|
if(*str == 0) // All spaces?
|
|
|
|
return str;
|
|
|
|
// Trim trailing space
|
|
|
|
end = str + strlen(str) - 1;
|
|
|
|
while(end > str && isspace((unsigned char)*end)) end--;
|
|
|
|
// Write new null terminator character
|
|
|
|
end[1] = '\0';
|
|
|
|
return str;
|
|
|
|
}
|
2023-12-05 00:04:04 +01:00
|
|
|
|
|
|
|
void replace(char *target, const char *needle, const char *replacement)
|
|
|
|
{
|
|
|
|
char buffer[1024] = { 0 };
|
|
|
|
char *insert_point = &buffer[0];
|
|
|
|
const char *tmp = target;
|
|
|
|
size_t needle_len = strlen(needle);
|
|
|
|
size_t repl_len = strlen(replacement);
|
|
|
|
while (1) {
|
|
|
|
const char *p = strstr(tmp, needle);
|
|
|
|
if (p == NULL) { // walked past last occurrence of needle; copy remaining part
|
|
|
|
strcpy(insert_point, tmp);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
memcpy(insert_point, tmp, p - tmp); // copy part before needle
|
|
|
|
insert_point += p - tmp;
|
|
|
|
memcpy(insert_point, replacement, repl_len); // copy replacement string
|
|
|
|
insert_point += repl_len;
|
|
|
|
tmp = p + needle_len;
|
|
|
|
}
|
|
|
|
strcpy(target, buffer);
|
|
|
|
}
|