Initial commit

This commit is contained in:
2024-04-27 11:20:46 +02:00
commit 648178bce9
10 changed files with 2823 additions and 0 deletions

301
lstring.c Normal file
View File

@@ -0,0 +1,301 @@
// LCZ libraries v0.1b
#include "lstring.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
// String building / constructors
String string_take(char *src)
{
String res;
res.text = src;
res.length = rstring_length(src);
return res;
}
DString dstring_take(char *src)
{
DString res;
res.text = src;
res.length = rstring_length(src);
res.capacity = res.length;
return res;
}
String string_copy(const char *src, u64 length)
{
String res;
res.text = malloc(length + 1);
assert(res.text != NULL);
memcpy(res.text, src, length);
res.text[length] = '\0';
res.length = length;
return res;
}
DString dstring_copy(const char *src, u64 length)
{
DString res;
res.text = malloc(length + 1);
assert(res.text != NULL);
memcpy(res.text, src, length);
res.text[length] = '\0';
res.length = length;
res.capacity = length;
return res;
}
DString dstring_new(u64 capacity)
{
DString res;
res.text = malloc(capacity + 1);
assert(res.text != NULL);
res.text[0] = '\0';
res.length = 0;
res.capacity = capacity;
return res;
}
// n = number of strings, ... = , const char *src1, u64 length1, ...
String string_concat(u32 n, ...)
{
va_list ap;
va_start(ap, n);
const char *strings[n];
u64 sizes[n];
u64 tot_len = 0;
for (u32 i = 0; i < n; i++)
{
strings[i] = va_arg(ap, const char *);
sizes[i] = va_arg(ap, u64);
tot_len += sizes[i];
}
String res;
res.text = malloc(tot_len + 1);
assert(res.text != NULL);
res.length = tot_len;
char *cursor = res.text;
for (u32 i = 0; i < n; i++)
{
memcpy(cursor, strings[i], sizes[i]);
cursor += sizes[i];
}
*cursor = '\0';
va_end(ap);
return res;
}
// n = number of strings, ... = , const char *src1, u64 length1, ...
DString dstring_concat(u32 n, ...)
{
va_list ap;
const char *strings[n];
u64 sizes[n];
u64 tot_len = 0;
va_start(ap, n);
for (u32 i = 0; i < n; i++)
{
strings[i] = va_arg(ap, const char *);
sizes[i] = va_arg(ap, u64);
tot_len += sizes[i];
}
DString res;
res.text = malloc(tot_len + 1);
assert(res.text != NULL);
res.length = tot_len;
res.capacity = tot_len;
char *cursor = res.text;
for (u32 i = 0; i < n; i++)
{
memcpy(cursor, strings[i], sizes[i]);
cursor += sizes[i];
}
*cursor = '\0';
va_end(ap);
return res;
}
// Compute string length, excluding zero-terminator
u64 rstring_length(const char *src)
{
u64 length = 0;
while(*(src++) != '\0')
length++;
return length;
}
// Comparison
int rstring_compare(const char* left, const char *right)
{
do
{
if (*left < *right)
return -1;
if (*left > *right)
return +1;
right++;
} while (*(left++));
return 0;
}
bool string_equal(String left, String right)
{
if (left.length != right.length)
return false;
char *l = left.text;
char *r = right.text;
char *l_end = l + left.length;
while (l != l_end)
{
if (*l != *r)
return false;
l++; r++;
}
return true;
}
bool string_find(String str, u64 start_index, String to_find, u64 *found_index)
{
// @TODO: Replace with better algorithm (Knuth-Morris-Pratt?)
char *end = str.text + str.length;
char *last_valid_start = end - to_find.length;
for (char *curr = str.text + start_index; curr <= last_valid_start; curr++)
{
bool found = true;
for (u64 i = 0; i < to_find.length; i++)
{
if (curr[i] != to_find.text[i])
{
found = false;
break;
}
}
if (found)
{
*found_index = curr - str.text;
return true;
}
}
return false;
}
String string_substring(String *str, u64 start, u64 end)
{
String res;
res.text = &str->text[start];
end = (end < str->length ? end : str->length);
end = (start < end ? end : start);
res.length = end - start;
return res;
}
String string_trim(String *str)
{
u64 start = 0;
u64 end = str->length;
while(start < str->length && isspace(str->text[start]))
start++;
while(end > start && isspace(str->text[end-1]))
end--;
return string_substring(str, start, end);
}
// DString specific operations
void dstring_reserve(DString *dstr, u64 new_length)
{
if (dstr->length < new_length)
dstr->text = realloc(dstr->text, new_length + 1); // + 1 --> reserve space for '\0'
assert(dstr->text != NULL);
}
void dstring_append(DString *dstr, const char *to_append, u64 count)
{
u64 len;
// Make sure we have enought space
len = dstr->length + count;
dstring_reserve(dstr, len);
// Copy bytes
memcpy(dstr->text + dstr->length, to_append, count);
dstr->text[len] = '\0';
dstr->length = len;
}
void dstring_insert(DString *dstr, u64 index, const char *to_insert, u64 count)
{
u64 len;
char *insert_start;
char *insert_end;
// Make sure we have enought space
len = dstr->length + count;
dstring_reserve(dstr, len);
// Move content to make space for the data we have to insert
insert_start = dstr->text + index;
insert_end = insert_start + count;
memmove(insert_end, insert_start, dstr->length - index + 1);
// Insert
memcpy(insert_start, to_insert, count);
dstr->length = len;
}
void dstring_erase(DString *dstr, u64 index, u64 count)
{
if (index + count > dstr->length)
count = dstr->length - index;
char *start = dstr->text + index;
char *end = start + count;
u64 to_move_from_end = dstr->length - index - count + 1; // Remember to move terminating zero
memmove(start, end, to_move_from_end);
dstr->length -= count;
}
void dstring_replace(DString *dstr, u64 index, u64 rem_count, const char *to_insert, u64 ins_count)
{
if (index + rem_count > dstr->length)
rem_count = dstr->length - index;
u64 len = dstr->length - rem_count + ins_count;
dstring_reserve(dstr, len);
char *start = dstr->text + index;
char *rem_end = start + rem_count;
char *ins_end = start + ins_count;
u64 to_move_from_end = dstr->length - index - rem_count + 1;
memmove(ins_end, rem_end, to_move_from_end);
memcpy(start, to_insert, ins_count);
dstr->length = len;
}