You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
2.9 KiB
133 lines
2.9 KiB
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
#include "string_utils.h"
|
|
#include "array.h"
|
|
#include "log.h"
|
|
|
|
char* str_new(const char* string, ...)
|
|
{
|
|
int length = 0;
|
|
char* new_string = NULL;
|
|
|
|
/* First pass, find out the length of the string by passing NULL and zero length */
|
|
va_list list;
|
|
va_start(list, string);
|
|
length = vsnprintf(new_string, 0, string, list);
|
|
va_end(list);
|
|
|
|
if(length < 0)
|
|
{
|
|
log_error("str_new", "Could not find length of string");
|
|
return new_string;
|
|
}
|
|
|
|
length++;
|
|
new_string = malloc(length);
|
|
if(!new_string)
|
|
{
|
|
log_error("str_new", "Malloc failed, out of memory!");
|
|
new_string = NULL;
|
|
return new_string;
|
|
}
|
|
/* Actual string allocation and copy */
|
|
va_start(list, string);
|
|
length = vsnprintf(new_string, length, string, list);
|
|
if(length < 0)
|
|
{
|
|
log_error("str_new", "Writing to new string failed");
|
|
free(new_string);
|
|
return new_string;
|
|
}
|
|
va_end(list);
|
|
return new_string;
|
|
}
|
|
|
|
char* str_concat(char* string, const char* str_to_concat)
|
|
{
|
|
size_t length = strlen(str_to_concat);
|
|
size_t length_orig = string ? strlen(string) : 0;
|
|
|
|
char* temp = realloc(string, length + length_orig + 1); /* +1 at the end to cope for null byte */
|
|
if(temp)
|
|
{
|
|
string = temp;
|
|
strcat(string + length_orig, str_to_concat);
|
|
}
|
|
return string;
|
|
}
|
|
|
|
char* str_replace(char* string, const char* pattern, const char* replacement)
|
|
{
|
|
int* indices = array_new(int);
|
|
size_t string_len = strlen(string);
|
|
|
|
/* Calculate size of new string and allocate new memory */
|
|
size_t pattern_len = strlen(pattern);
|
|
size_t replacement_len = strlen(replacement);
|
|
|
|
int done = 0;
|
|
char* remaining_string = string;
|
|
while(!done)
|
|
{
|
|
char* location = strstr(remaining_string, pattern);
|
|
if(location)
|
|
{
|
|
int index = location - string;
|
|
array_push(indices, index, int);
|
|
remaining_string = location + pattern_len; /* Find the next occurance in the remaining string */
|
|
}
|
|
else
|
|
{
|
|
done = 1;
|
|
}
|
|
}
|
|
|
|
int num_indices = array_len(indices);
|
|
if(num_indices > 0)
|
|
{
|
|
size_t string_len_without_pattern = string_len - (pattern_len * num_indices);
|
|
size_t new_string_len = string_len_without_pattern + (replacement_len * num_indices);
|
|
char* new_string = malloc(new_string_len);
|
|
|
|
if(new_string)
|
|
{
|
|
done = 0;
|
|
int count = 0;
|
|
int index = indices[count];
|
|
unsigned int prev_index = 0;
|
|
while(!done)
|
|
{
|
|
char* source_beg = string + prev_index;
|
|
char* source_end = string + index;
|
|
|
|
strncat(new_string, source_beg, (source_end - source_beg));
|
|
strcat(new_string, replacement);
|
|
|
|
count++;
|
|
prev_index = index + pattern_len;
|
|
|
|
if(count == array_len(indices))
|
|
{
|
|
done = 1;
|
|
source_beg = string + prev_index;
|
|
strcat(new_string, source_beg);
|
|
}
|
|
else
|
|
{
|
|
index = indices[count];
|
|
}
|
|
}
|
|
free(string);
|
|
}
|
|
|
|
array_free(indices);
|
|
return new_string;
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|