Fixed various bugs and added usage for String data type
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -Wall -Wextra -Werror -pedantic-errors -fstack-protector-strong \
|
CFLAGS = -Wall -Wextra -Werror -pedantic-errors -fstack-protector-strong \
|
||||||
-fsanitize=address -fsanitize=undefined -fstack-clash-protection \
|
-fsanitize=address -fsanitize=undefined -fstack-clash-protection \
|
||||||
-Wwrite-strings -g -std=c99
|
-fdiagnostics-color=always -Wwrite-strings -g -std=c99
|
||||||
|
|
||||||
BENCH_FLAGS = -Wall -Wextra -Werror -O3
|
BENCH_FLAGS = -Wall -Wextra -Werror -O3
|
||||||
|
|
||||||
|
|||||||
15
src/string.c
15
src/string.c
@@ -22,7 +22,7 @@ static inline int utf8_char_len(unsigned char byte) {
|
|||||||
if ((byte & 0x80) == 0x00) return 1;
|
if ((byte & 0x80) == 0x00) return 1;
|
||||||
if ((byte & 0xE0) == 0xC0) return 2;
|
if ((byte & 0xE0) == 0xC0) return 2;
|
||||||
if ((byte & 0xF0) == 0xE0) return 3;
|
if ((byte & 0xF0) == 0xE0) return 3;
|
||||||
if ((byte & 0xF0) == 0xE0) return 4;
|
if ((byte & 0xF8) == 0xF0) return 4;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -285,7 +285,7 @@ string_result_t string_concat(const string_t *x, const string_t *y) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buf, x->data, y->byte_size);
|
memcpy(buf, x->data, x->byte_size);
|
||||||
memcpy(buf + x->byte_size, y->data, y->byte_size);
|
memcpy(buf + x->byte_size, y->data, y->byte_size);
|
||||||
buf[new_size] = '\0';
|
buf[new_size] = '\0';
|
||||||
result = string_new(buf);
|
result = string_new(buf);
|
||||||
@@ -400,7 +400,7 @@ string_result_t string_substring(const string_t *haystack, const string_t *needl
|
|||||||
*
|
*
|
||||||
* Gets symbol indexed by @position from @str
|
* Gets symbol indexed by @position from @str
|
||||||
*
|
*
|
||||||
* Returns a string_result_t containing a the symbol as a C string
|
* Returns a string_result_t containing the symbol as a C string
|
||||||
*/
|
*/
|
||||||
string_result_t string_get_at(const string_t *str, size_t position) {
|
string_result_t string_get_at(const string_t *str, size_t position) {
|
||||||
string_result_t result = {0};
|
string_result_t result = {0};
|
||||||
@@ -418,17 +418,18 @@ string_result_t string_get_at(const string_t *str, size_t position) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int char_len = utf8_char_len((unsigned char)*ptr);
|
int char_len = utf8_char_len((unsigned char)*ptr);
|
||||||
char *symbol = malloc(char_len + 1);
|
char *utf8_char = malloc(char_len + 1);
|
||||||
if (symbol == NULL) {
|
if (utf8_char == NULL) {
|
||||||
result.status = STRING_ERR_ALLOCATE;
|
result.status = STRING_ERR_ALLOCATE;
|
||||||
SET_MSG(result, "Cannot allocate memory");
|
SET_MSG(result, "Cannot allocate memory");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(symbol, ptr, char_len);
|
memcpy(utf8_char, ptr, char_len);
|
||||||
symbol[char_len] = '\0';
|
utf8_char[char_len] = '\0';
|
||||||
|
|
||||||
|
result.value.symbol = utf8_char;
|
||||||
result.status = STRING_OK;
|
result.status = STRING_OK;
|
||||||
SET_MSG(result, "Symbol successfully retrieved");
|
SET_MSG(result, "Symbol successfully retrieved");
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ typedef struct {
|
|||||||
uint8_t message[RESULT_MSG_SIZE];
|
uint8_t message[RESULT_MSG_SIZE];
|
||||||
union {
|
union {
|
||||||
string_t *string; // For new, reverse, trim
|
string_t *string; // For new, reverse, trim
|
||||||
char *c_str; // For get_at
|
char *symbol; // For get_at
|
||||||
int64_t idx; // For substring search
|
int64_t idx; // For substring search
|
||||||
bool is_equ; // For comparison
|
bool is_equ; // For comparison
|
||||||
struct { // For split
|
struct { // For split
|
||||||
|
|||||||
98
usage.c
98
usage.c
@@ -25,10 +25,12 @@
|
|||||||
#include "src/vector.h"
|
#include "src/vector.h"
|
||||||
#include "src/map.h"
|
#include "src/map.h"
|
||||||
#include "src/bigint.h"
|
#include "src/bigint.h"
|
||||||
|
#include "src/string.h"
|
||||||
|
|
||||||
static int vector_usage(void);
|
static int vector_usage(void);
|
||||||
static int map_usage(void);
|
static int map_usage(void);
|
||||||
static int bigint_usage(void);
|
static int bigint_usage(void);
|
||||||
|
static int string_usage(void);
|
||||||
|
|
||||||
static vector_order_t cmp_int_asc(const void *x, const void *y);
|
static vector_order_t cmp_int_asc(const void *x, const void *y);
|
||||||
static vector_order_t cmp_int_desc(const void *x, const void *y);
|
static vector_order_t cmp_int_desc(const void *x, const void *y);
|
||||||
@@ -52,6 +54,11 @@ int main(void) {
|
|||||||
st = bigint_usage();
|
st = bigint_usage();
|
||||||
if (st) { return st; }
|
if (st) { return st; }
|
||||||
|
|
||||||
|
SEP(50);
|
||||||
|
|
||||||
|
st = string_usage();
|
||||||
|
if (st) { return st; }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,3 +531,94 @@ int bigint_usage(void) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int string_usage(void) {
|
||||||
|
// Create a new string
|
||||||
|
string_result_t res = string_new("Hello, ");
|
||||||
|
if (res.status != STRING_OK) {
|
||||||
|
printf("Error: %s\n", res.message);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string_t *str1 = res.value.string;
|
||||||
|
printf("Created string: \"%s\"\n", str1->data);
|
||||||
|
printf("Character count: %zu (%zu actual bytes)\n\n", string_len(str1), str1->byte_size);
|
||||||
|
|
||||||
|
// Concatenation of strings
|
||||||
|
string_result_t res_suffix = string_new("World! 🦜");
|
||||||
|
if (res_suffix.status != STRING_OK) {
|
||||||
|
printf("Error: %s\n", res.message);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string_t *suffix = res_suffix.value.string;
|
||||||
|
printf("Created another string: \"%s\"\n", suffix->data);
|
||||||
|
printf("Character count: %zu (%zu actual bytes)\n\n", string_len(suffix), suffix->byte_size);
|
||||||
|
|
||||||
|
string_result_t res_cat = string_concat(str1, suffix);
|
||||||
|
if (res_cat.status != STRING_OK) {
|
||||||
|
printf("Error: %s\n", res_cat.message);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
string_destroy(suffix);
|
||||||
|
|
||||||
|
string_t *concat_str = res_cat.value.string;
|
||||||
|
printf("Concatenation result: \"%s\"\n\n", concat_str->data);
|
||||||
|
|
||||||
|
// Uppercase string
|
||||||
|
string_result_t res_upper = string_to_upper(concat_str);
|
||||||
|
if (res_upper.status != STRING_OK) {
|
||||||
|
printf("Error: %s\n", res_upper.message);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Uppercase: \"%s\"\n", res_upper.value.string->data);
|
||||||
|
string_destroy(res_upper.value.string);
|
||||||
|
|
||||||
|
// Lowercase string
|
||||||
|
string_result_t res_lower = string_to_lower(concat_str);
|
||||||
|
if (res_lower.status != STRING_OK) {
|
||||||
|
printf("Error: %s\n", res_lower.message);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Lowercase: \"%s\"\n\n", res_lower.value.string->data);
|
||||||
|
string_destroy(res_lower.value.string);
|
||||||
|
|
||||||
|
// Reverse string
|
||||||
|
string_result_t res_rev = string_reverse(concat_str);
|
||||||
|
if (res_rev.status != STRING_OK) {
|
||||||
|
printf("Error: %s\n", res_rev.message);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Reversed: \"%s\"\n\n", res_rev.value.string->data);
|
||||||
|
string_destroy(res_rev.value.string);
|
||||||
|
|
||||||
|
// Change first character of the string
|
||||||
|
string_result_t res_set = string_set_at(concat_str, 0, "J");
|
||||||
|
if (res_set.status != STRING_OK) {
|
||||||
|
printf("Error: %s\n", res_set.message);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Updated string: \"%s\"\n\n", concat_str->data);
|
||||||
|
|
||||||
|
// Get character from string (the emoji)
|
||||||
|
string_result_t res_get = string_get_at(concat_str, 14);
|
||||||
|
if (res_get.status != STRING_OK) {
|
||||||
|
printf("Error: %s\n", res_get.message);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Extracted symbol: \"%s\"\n", res_get.value.symbol);
|
||||||
|
free(res_get.value.symbol);
|
||||||
|
|
||||||
|
string_destroy(concat_str);
|
||||||
|
string_destroy(str1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user