Compare commits

...

15 Commits

Author SHA1 Message Date
db208bd912 remove strcmp and fix hidden bugs 2025-06-02 23:50:20 +02:00
e25b8236e4 switch from assert to if + return 2025-05-28 20:21:24 +02:00
77ccd59ce3 new untested code 2025-05-28 19:32:15 +02:00
fec9f2633d Portable Makefile 2025-05-28 19:31:56 +02:00
61a398f402 new strops_remove_at_pos_char_inplace 2025-05-21 21:07:14 +02:00
d31bc73884 not implementing those 2025-05-21 20:49:17 +02:00
5b4a3f84e5 remove url stuff
I recommend using libcurl or similar for that
2025-05-21 20:36:47 +02:00
c3824e1dc7 remove string.h dependency 2025-05-21 20:34:11 +02:00
7e26a39ec6 new strops_copy_amount 2025-05-21 17:54:43 +02:00
9610831c9e new strops_length and strops_copy 2025-05-21 17:50:05 +02:00
1418c2843e trying out shared lib 2025-05-21 17:49:38 +02:00
28a235b680 progress on url and new stuff 2025-05-09 00:10:40 +02:00
fd30b35d10 switch to making static library 2025-05-08 20:02:59 +02:00
6505add9f5 move files into root of repo 2025-05-08 20:02:36 +02:00
4b4ce3d36f update .gitignore 2025-05-08 20:02:10 +02:00
7 changed files with 895 additions and 623 deletions

6
.gitignore vendored
View File

@ -1,2 +1,4 @@
# executables
build
strops.o
libstrops.so
libstrops.a
tests

View File

@ -1,11 +1,27 @@
test: debug
gcc -ansi -L./build -o build/tests src/tests.c -lstrops
.POSIX :
debug:
gcc -c -ansi -ggdb -o build/strops.o src/strops.c
gcc -shared -o build/libstrops.so build/strops.o
tests : libstrops.a libstrops.so strops.h
gcc -ansi -I . -L. -o tests tests.c -Wl,-Bstatic -lstrops -Wl,-Bdynamic
# gcc -ansi -I . -L. -o tests tests.c -lstrops
#release:
# gcc -ansi -O2 -pipe -fno-semantic-interposition -o build/hdb src/main.c src/db.c -lsqlite3
# strip build/hdb
libstrops.so : strops.o
gcc -shared -o libstrops.so strops.o
libstrops.a : strops.o
ar cr libstrops.a strops.o
strops.o : strops.c
# gcc -c -ansi -fPIC -ggdb -o strops.o strops.c
gcc -c -ansi -fpic -O2 -pipe -o strops.o strops.c
.PHONY : install uninstall
install: libstrops.a libstrops.so strops.h
sudo mv libstrops.a /usr/local/lib
sudo mv libstrops.so /usr/local/lib
sudo cp strops.h /usr/local/include
uninstall:
sudo rm /usr/local/lib/libstrops.a
sudo rm /usr/local/lib/libstrops.so
sudo rm /usr/local/include/strops.h

View File

@ -1,261 +0,0 @@
#include "strops.h"
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
/* Function template
char* strops_(const char* string) {
char *result = malloc(strlen(string));
memcpy(result, string, strlen(string));
return result;
}
*/
char* strops_to_lowercase(const char* string) {
char *result = malloc(strlen(string));
memcpy(result, string, strlen(string));
size_t i;
for (i = 0; i < strlen(string); i++) {
if (result[i] >= 'A' && result[i] <= 'Z') {
result[i] += 32;
}
}
return result;
}
char* strops_to_uppercase(const char* string) {
char *result = malloc(strlen(string));
memcpy(result, string, strlen(string));
size_t i;
for (i = 0; i < strlen(string); i++) {
if (result[i] >= 'a' && result[i] <= 'z') {
result[i] -= 32;
}
}
return result;
}
char* strops_insert_at_pos(const char* string, const char* string_to_insert, size_t pos) {
assert(pos <= strlen(string) && "pos needs to be inside string");
size_t string_length = strlen(string) + strlen(string_to_insert) + 1;
char *result = malloc(string_length);
memcpy(result, string, strlen(string));
size_t i, j;
/* Make space for string_to_insert */
for (i = string_length - 1; i > pos; i--) {
result[i] = result[i - strlen(string_to_insert)];
}
/* Insert string into empty space */
for (j = 0; j < strlen(string_to_insert); j++) {
result[pos + j] = string_to_insert[j];
}
return result;
}
char* strops_remove_at_pos(const char* string, size_t pos) {
assert(pos <= strlen(string) && "pos needs to be inside string");
char *result = malloc(strlen(string));
memcpy(result, string, strlen(string));
result[pos] = 0;
size_t i;
for (i = pos; i < strlen(string); i++) {
result[i] = result[i + 1];
}
result = realloc(result, strlen(result));
return result;
}
char* strops_trim_right_whitespace(const char* string) {
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
while (strchr("\t\n\v\f\r ", result[strlen(result) - 1]) != NULL) {
result = strops_remove_at_pos(result, strlen(result) - 1);
}
result = realloc(result, strlen(result));
return result;
}
char* strops_trim_left_whitespace(const char* string) {
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
while (strchr("\t\n\v\f\r ", result[0]) != NULL) {
result = strops_remove_at_pos(result, 0);
}
result = realloc(result, strlen(result));
return result;
}
char* strops_trim_both_whitespace(const char* string) {
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
result = strops_trim_right_whitespace(result);
result = strops_trim_left_whitespace(result);
return result;
}
char* strops_trim_right_chars(const char* string, const char* chars_to_remove) {
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
while (strchr(chars_to_remove, result[strlen(result) - 1]) != NULL) {
result = strops_remove_at_pos(result, strlen(result) - 1);
}
result = realloc(result, strlen(result));
return result;
}
char* strops_trim_left_chars(const char* string, const char* chars_to_remove) {
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
while (strchr(chars_to_remove, result[0]) != NULL) {
result = strops_remove_at_pos(result, 0);
}
result = realloc(result, strlen(result));
return result;
}
char* strops_trim_both_chars(const char* string, const char* chars_to_remove) {
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
result = strops_trim_right_chars(result, chars_to_remove);
result = strops_trim_left_chars(result, chars_to_remove);
return result;
}
char* strops_trim_right_string(const char* string, const char* string_to_remove) {
assert(strlen(string) >= strlen(string_to_remove) && "string_to_remove cannot be bigger than string");
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
size_t offset = strlen(result) - strlen(string_to_remove);
char* tmp = result + offset;
while (strcmp(tmp, string_to_remove) == 0) {
size_t i;
for (i = 0; i < strlen(string_to_remove); i++) {
result = strops_remove_at_pos(result, offset);
}
offset = strlen(result) - strlen(string_to_remove);
tmp = result + offset;
}
result = realloc(result, strlen(result));
return result;
}
char* strops_trim_left_string(const char* string, const char* string_to_remove) {
assert(strlen(string) >= strlen(string_to_remove) && "string_to_remove cannot be bigger than string");
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
char *tmp = malloc(strlen(string_to_remove) + 1);
memcpy(tmp, result, strlen(string_to_remove));
while (strcmp(tmp, string_to_remove) == 0) {
size_t i;
for (i = 0; i < strlen(string_to_remove); i++) {
result = strops_remove_at_pos(result, 0);
}
memcpy(tmp, result, strlen(string_to_remove));
}
free(tmp);
result = realloc(result, strlen(result));
return result;
}
char* strops_trim_both_string(const char* string, const char* string_to_remove) {
assert(strlen(string) >= strlen(string_to_remove) && "string_to_remove cannot be bigger than string");
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
result = strops_trim_right_string(result, string_to_remove);
result = strops_trim_left_string(result, string_to_remove);
return result;
}
char* strops_remove_chars(const char* string, const char* chars_to_remove) {
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
size_t i;
for (i = 0; i < strlen(chars_to_remove); i++) {
while (strchr(result, chars_to_remove[i]) != NULL) {
result = strops_remove_at_pos(result, strlen(result) - strlen(strchr(result, chars_to_remove[i])));
}
}
result = realloc(result, strlen(result));
return result;
}
char* strops_remove_string(const char* string, const char* string_to_remove) {
assert(strlen(string) >= strlen(string_to_remove) && "string_to_remove cannot be bigger than string");
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
while (strstr(result, string_to_remove) != NULL) {
size_t offset = strlen(result) - strlen(strstr(result, string_to_remove));
size_t i;
for (i = 0; i < strlen(string_to_remove); i++) {
result = strops_remove_at_pos(result, offset);
}
}
result = realloc(result, strlen(result));
return result;
}
size_t strops_word_count(const char* string) {
size_t word_count = 0;
char *tmp = malloc(strlen(string) + 1);
memcpy(tmp, string, strlen(string));
size_t i = 0;
size_t beginning_of_word = 0;
size_t end_of_word = end_of_word;
while (i < strlen(string) - 1) {
for (; i < strlen(string); i++) {
if ((tmp[i] >= 'A' && tmp[i] <= 'Z') || (tmp[i] >= 'a' && tmp[i] <= 'z')) {
beginning_of_word = i;
break;
}
}
if (strchr("\t\n\v\f\r ", tmp[beginning_of_word - 1]) == NULL) {
continue;
}
for (i = beginning_of_word; i < strlen(string); i++) {
if (!(tmp[i] >= 'A' && tmp[i] <= 'Z') && !(tmp[i] >= 'a' && tmp[i] <= 'z')) {
end_of_word = i;
break;
}
}
if (strchr("\t\n\v\f\r ", tmp[end_of_word + 1]) == NULL) {
continue;
}
if (end_of_word - beginning_of_word < 2) {
continue;
}
i = end_of_word;
word_count++;
}
free(tmp);
return word_count;
}
char* strops_url_encode(const char* string) {
/* multiplied by 3, because example: ( => %28. Three times the chars */
char *result = malloc(strlen(string) * 3 + 1);
memcpy(result, string, strlen(string));
char *unsafe_chars = "";
result = realloc(result, strlen(result));
return result;
}
char* strops_url_decode(const char* string) {
char *result = malloc(strlen(string) + 1);
memcpy(result, string, strlen(string));
result = realloc(result, strlen(result));
return result;
}

View File

@ -1,343 +0,0 @@
#include "strops.h"
#include <stdio.h>
/* Test template (Maybe make a macro in the future?)
int test_() {
char* input = "";
char* expected = "";
char* result = strops_(input);
if (strcmp(result, expected) != 0) {
printf("test_ failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
*/
int test_to_lowercase() {
char* input = "sTrInG";
char* expected = "string";
char* result = strops_to_lowercase(input);
if (strcmp(result, expected) != 0) {
printf("test_to_lowercase failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_to_uppercase() {
char* input = "sTrInG";
char* expected = "STRING";
char* result = strops_to_uppercase(input);
if (strcmp(result, expected) != 0) {
printf("test_to_uppercase failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_insert_at_pos() {
char* input = "Heo, World!";
char* expected = "Hello, World!";
char* result = strops_insert_at_pos(input, "ll", 2);
if (strcmp(result, expected) != 0) {
printf("test_insert_at_pos failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_remove_at_pos() {
char* input = "Hello";
char* expected = "Hllo";
char* result = strops_remove_at_pos(input, 1);
if (strcmp(result, expected) != 0) {
printf("test_remove_at_pos failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_trim_right_whitespace() {
char* input = "String \t\f\v\r\n ";
char* expected = "String";
char* result = strops_trim_right_whitespace(input);
if (strcmp(result, expected) != 0) {
printf("\ntest_trim_right_whitespace failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_trim_left_whitespace() {
char* input = " \t\f\v\r\n String";
char* expected = "String";
char* result = strops_trim_left_whitespace(input);
if (strcmp(result, expected) != 0) {
printf("\ntest_trim_left_whitespace failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_trim_both_whitespace() {
char* input = " \t\f\v String \r\n ";
char* expected = "String";
char* result = strops_trim_both_whitespace(input);
if (strcmp(result, expected) != 0) {
printf("\ntest_trim_both_whitespace failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_trim_right_chars() {
char* input = "banana";
char* expected = "b";
char* result = strops_trim_right_chars(input, "na");
if (strcmp(result, expected) != 0) {
printf("test_right_chars failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_trim_left_chars() {
char* input = "banana";
char* expected = "nana";
char* result = strops_trim_left_chars(input, "ba");
if (strcmp(result, expected) != 0) {
printf("test_left_chars failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_trim_both_chars() {
char* input = "anna";
char* expected = "nn";
char* result = strops_trim_both_chars(input, "a");
if (strcmp(result, expected) != 0) {
printf("test_trim_both_chars failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_trim_right_string() {
char* input = "adad_artist";
char* expected = "adad_";
char* result = strops_trim_right_string(input, "artist");
if (strcmp(result, expected) != 0) {
printf("test_trim_right_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_trim_left_string() {
char* input = "adad_artist";
char* expected = "_artist";
char* result = strops_trim_left_string(input, "adad");
if (strcmp(result, expected) != 0) {
printf("test_trim_left_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_trim_both_string() {
char* input = "NULLNULL Bruh NULLNULL";
char* expected = " Bruh ";
char* result = strops_trim_both_string(input, "NULL");
if (strcmp(result, expected) != 0) {
printf("test_trim_both_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_remove_chars() {
char* input = "banana";
char* expected = "bnn";
char* result = strops_remove_chars(input, "a");
if (strcmp(result, expected) != 0) {
printf("test_remove_chars failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_remove_string() {
char* input = "I hate you";
char* expected = "I you";
char* result = strops_remove_string(input, "hate");
if (strcmp(result, expected) != 0) {
printf("test_remove_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_word_count() {
char* input = "Hello, World!";
size_t expected = 2;
size_t result = strops_word_count(input);
if (result != expected) {
printf("test_word_count failed\n");
printf("Got = %ld\nExpected = %ld\n", result, expected);
return 1;
}
return 0;
}
int test_url_encode() {
char* input = "(artist)";
char* expected = "%28artist%29";
char* result = strops_url_encode(input);
if (strcmp(result, expected) != 0) {
printf("test_url_encode failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int test_url_decode() {
char* input = "%28artist%29";
char* expected = "(artist)";
char* result = strops_url_decode(input);
if (strcmp(result, expected) != 0) {
printf("test_url_decode failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
return 1;
}
return 0;
}
int main() {
int amount_of_tests = 18;
int amount_of_successful_tests = 0;
int ret;
/* Test template
ret = test_();
if (ret == 0) {
amount_of_successful_tests++;
}
*/
ret = test_to_lowercase();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_to_uppercase();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_insert_at_pos();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_remove_at_pos();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_trim_right_whitespace();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_trim_left_whitespace();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_trim_both_whitespace();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_trim_right_chars();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_trim_left_chars();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_trim_both_chars();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_trim_right_string();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_trim_left_string();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_trim_both_string();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_remove_chars();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_remove_string();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_word_count();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_url_encode();
if (ret == 0) {
amount_of_successful_tests++;
}
ret = test_url_decode();
if (ret == 0) {
amount_of_successful_tests++;
}
if (amount_of_successful_tests != amount_of_tests) {
printf("%d/%d tests passed successfully\n", amount_of_successful_tests, amount_of_tests);
return 1;
} else {
printf("All tests passed successfully\n");
return 0;
}
}

389
strops.c Normal file
View File

@ -0,0 +1,389 @@
#include "strops.h"
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
/* Function template
char* strops_(const char* string) {
char* result = strops_copy(string);
return result;
}
*/
ull_t strops_length(const char* string) {
if (!string) {
return 0;
}
ull_t string_length = 0;
while(string[string_length] != '\0') {
string_length++;
}
return string_length;
}
char* strops_copy(const char* string) {
if (!string) {
return 0;
}
ull_t length = strops_length(string);
if (length == 0) {
return 0;
}
char* result = malloc(length);
ull_t i;
for(i = 0; i < length; i++) {
result[i] = string[i];
}
result[i] = '\0';
return result;
}
char* strops_copy_amount(const char* string, ull_t amount) {
if (!string) {
return 0;
}
if (amount > strops_length(string)) {
return 0;
}
char* result = malloc(amount);
ull_t i;
for(i = 0; i < amount; i++) {
result[i] = string[i];
}
result[i] = '\0';
return result;
}
ull_t strops_first_pos_of_char(const char* string, char char_to_search) {
ull_t i;
for (i = 0; string[i] != char_to_search; i++) {}
return i;
}
ull_t strops_first_pos_of_string(const char* string, const char* string_to_search) {
bool_t contains_string;
ull_t sts_length = strops_length(string_to_search);
ull_t l = strops_length(string) - sts_length + 1;
ull_t i, j;
for (i = 0; i < l; i++) {
contains_string = 1;
for(j = 0; j < sts_length; j++) {
if (string[i + j] != string_to_search[j]) {
contains_string = 0;
break;
}
}
if (contains_string) {
break;
}
}
return i;
}
bool_t strops_contains_char(const char* string, char char_to_search) {
ull_t i;
for (i = 0; i < strops_length(string) + 1; i++) {
if (string[i] == char_to_search) {
return 1;
}
}
return 0;
}
bool_t strops_contains_string(const char* string, const char* string_to_search) {
bool_t contains_string = 0;
ull_t sts_length = strops_length(string_to_search);
ull_t l = strops_length(string) - sts_length + 1;
ull_t i, j;
for (i = 0; i < l; i++) {
contains_string = 1;
for(j = 0; j < sts_length; j++) {
if (string[i + j] != string_to_search[j]) {
contains_string = 0;
break;
}
}
if (contains_string) {
break;
}
}
return contains_string;
}
bool_t strops_equals(const char* string1, const char* string2) {
if (strops_length(string1) != strops_length(string2)) {
return 0;
}
bool_t equal = 1;
ull_t i;
for (i = 0; i < strops_length(string1); i++) {
if (string1[i] != string2[i]) {
equal = 0;
break;
}
}
return equal;
}
bool_t strops_starts_with(const char* string1, const char* string2) {
if (strops_length(string1) < strops_length(string2)) {
return 0;
}
bool_t starts_with = 1;
ull_t i;
for (i = 0; i < strops_length(string2); i++) {
if (string1[i] != string2[i]) {
starts_with = 0;
break;
}
}
return starts_with;
}
char* strops_to_lowercase(const char* string) {
char* result = strops_copy(string);
ull_t i;
for (i = 0; i < strops_length(string); i++) {
if (result[i] >= 'A' && result[i] <= 'Z') {
result[i] += 32;
}
}
return result;
}
char* strops_to_uppercase(const char* string) {
char* result = strops_copy(string);
ull_t i;
for (i = 0; i < strops_length(string); i++) {
if (result[i] >= 'a' && result[i] <= 'z') {
result[i] -= 32;
}
}
return result;
}
bool_t strops_is_lowercase(const char* string) {
ull_t i;
for (i = 0; i < strops_length(string); i++) {
if (!(string[i] >= 'a' && string[i] <= 'z')) {
return 0;
}
}
return 1;
}
bool_t strops_is_uppercase(const char* string) {
ull_t i;
for (i = 0; i < strops_length(string); i++) {
if (!(string[i] >= 'A' && string[i] <= 'Z')) {
return 0;
}
}
return 1;
}
char* strops_insert_at_pos_string(const char* string, const char* string_to_insert, ull_t pos) {
assert(pos <= strops_length(string) && "pos needs to be inside string");
ull_t string_length = strops_length(string) + strops_length(string_to_insert) + 1;
char* result = strops_copy(string);
ull_t i, j;
/* Make space for string_to_insert */
for (i = string_length - 1; i > pos; i--) {
result[i] = result[i - strops_length(string_to_insert)];
}
/* Insert string into empty space */
for (j = 0; j < strops_length(string_to_insert); j++) {
result[pos + j] = string_to_insert[j];
}
return result;
}
char* strops_remove_at_pos_char(const char* string, ull_t pos) {
assert(pos <= strops_length(string) && "pos needs to be inside string");
char* result = strops_copy(string);
result[pos] = 0;
ull_t i;
for (i = pos; i < strops_length(string); i++) {
result[i] = result[i + 1];
}
return result;
}
void strops_remove_at_pos_char_inplace(char* string, ull_t pos) {
assert(pos <= strops_length(string) && "pos needs to be inside string");
ull_t length = strops_length(string);
string[pos] = 0;
ull_t i;
for (i = pos; i < length; i++) {
string[i] = string[i + 1];
}
}
char* strops_trim_right_whitespace(const char* string) {
char* result = strops_copy(string);
char* tmp;
while (strops_contains_char("\t\n\v\f\r ", result[strops_length(result) - 1])) {
strops_remove_at_pos_char_inplace(result, strops_length(result) - 1);
}
result = realloc(result, strops_length(result));
return result;
}
char* strops_trim_left_whitespace(const char* string) {
char* result = strops_copy(string);
while (strops_contains_char("\t\n\v\f\r ", result[0])) {
strops_remove_at_pos_char_inplace(result, 0);
}
result = realloc(result, strops_length(result));
return result;
}
char* strops_trim_both_whitespace(const char* string) {
char* result;
char* tmp;
tmp = strops_trim_right_whitespace(string);
result = strops_trim_left_whitespace(tmp);
free(tmp);
return result;
}
char* strops_trim_right_chars(const char* string, const char* chars_to_remove) {
char* result = strops_copy(string);
while (strops_contains_char(chars_to_remove, result[strops_length(result) - 1])) {
strops_remove_at_pos_char_inplace(result, strops_length(result) - 1);
}
result = realloc(result, strops_length(result));
return result;
}
char* strops_trim_left_chars(const char* string, const char* chars_to_remove) {
char* result = strops_copy(string);
while (strops_contains_char(chars_to_remove, result[0])) {
strops_remove_at_pos_char_inplace(result, 0);
}
result = realloc(result, strops_length(result));
return result;
}
char* strops_trim_both_chars(const char* string, const char* chars_to_remove) {
char* result;
char* tmp;
tmp = strops_trim_right_chars(string, chars_to_remove);
result = strops_trim_left_chars(tmp, chars_to_remove);
free(tmp);
return result;
}
char* strops_trim_right_string(const char* string, const char* string_to_remove) {
assert(strops_length(string) >= strops_length(string_to_remove) && "string_to_remove cannot be bigger than string");
char* result = strops_copy(string);
ull_t offset = strops_length(result) - strops_length(string_to_remove);
char* tmp = result + offset;
while (strops_equals(tmp, string_to_remove)) {
ull_t i;
for (i = 0; i < strops_length(string_to_remove); i++) {
strops_remove_at_pos_char_inplace(result, offset);
}
offset = strops_length(result) - strops_length(string_to_remove);
tmp = result + offset;
}
result = realloc(result, strops_length(result));
return result;
}
char* strops_trim_left_string(const char* string, const char* string_to_remove) {
assert(strops_length(string) >= strops_length(string_to_remove) && "string_to_remove cannot be bigger than string");
char* result = strops_copy(string);
while (strops_first_pos_of_string(result, string_to_remove) == 0) {
ull_t i;
for (i = 0; i < strops_length(string_to_remove); i++) {
strops_remove_at_pos_char_inplace(result, 0);
}
}
result = realloc(result, strops_length(result));
return result;
}
char* strops_trim_both_string(const char* string, const char* string_to_remove) {
assert(strops_length(string) >= strops_length(string_to_remove) && "string_to_remove cannot be bigger than string");
char* result;
char* tmp;
tmp = strops_trim_right_string(string, string_to_remove);
result = strops_trim_left_string(tmp, string_to_remove);
return result;
}
char* strops_remove_chars(const char* string, const char* chars_to_remove) {
char* result = strops_copy(string);
ull_t i, j;
for (i = 0; i < strops_length(chars_to_remove); i++) {
while (strops_contains_char(result, chars_to_remove[i])) {
strops_remove_at_pos_char_inplace(result, strops_first_pos_of_char(result, chars_to_remove[i]));
}
}
result = realloc(result, strops_length(result));
return result;
}
char* strops_remove_string(const char* string, const char* string_to_remove) {
assert(strops_length(string) >= strops_length(string_to_remove) && "string_to_remove cannot be bigger than string");
char* result = strops_copy(string);
while (strops_contains_string(result, string_to_remove)) {
ull_t offset = strops_first_pos_of_string(result, string_to_remove);
ull_t i;
for (i = 0; i < strops_length(string_to_remove); i++) {
strops_remove_at_pos_char_inplace(result, offset);
}
}
result = realloc(result, strops_length(result));
return result;
}
ull_t strops_word_count(const char* string) {
ull_t word_count = 0;
char* tmp = strops_copy(string);
ull_t i = 0;
ull_t beginning_of_word = 0;
while (i < strops_length(string) - 1) {
for (; i < strops_length(tmp); i++) {
if ((tmp[i] >= 'A' && tmp[i] <= 'Z') || (tmp[i] >= 'a' && tmp[i] <= 'z')) {
beginning_of_word = i;
break;
}
}
if (!strops_contains_char("\t\n\v\f\r ", tmp[beginning_of_word - 1])) {
continue;
}
for (i = beginning_of_word; i < strops_length(tmp); i++) {
if (!(tmp[i] >= 'A' && tmp[i] <= 'Z') && !(tmp[i] >= 'a' && tmp[i] <= 'z')) {
break;
}
}
if (!strops_contains_char("\t\n\v\f\r ", tmp[i + 1])) {
continue;
}
if (i - beginning_of_word < 2) {
continue;
}
word_count++;
}
free(tmp);
return word_count;
}

View File

@ -4,17 +4,34 @@
#include <stddef.h>
/*
All functions return a new heap-allocated string to which the requested operation was applied to.
Functions that return char*, return a new heap-allocated string.
The user of this library is responsible for freeing the memory of the result.
No function modifies the input string. The input string is copied at the beginning of a function.
Only 7-Bit Ascii is supported.
*/
typedef unsigned long long ull_t;
typedef unsigned char bool_t;
ull_t strops_length(const char* string);
char* strops_copy(const char* string);
char* strops_copy_amount(const char* string, ull_t amount);
ull_t strops_first_pos_of_char(const char* string, char char_to_search);
ull_t strops_first_pos_of_string(const char* string, const char* string_to_search);
bool_t strops_contains_char(const char* string, char char_to_search);
bool_t strops_contains_string(const char* string, const char* string_to_search);
bool_t strops_equals(const char* string1, const char* string2);
bool_t strops_starts_with(const char* string1, const char* string2);
char* strops_to_lowercase(const char* string);
char* strops_to_uppercase(const char* string);
bool_t strops_is_lowercase(const char* string);
bool_t strops_is_uppercase(const char* string);
char* strops_insert_at_pos(const char* string, const char* string_to_insert, size_t pos);
char* strops_remove_at_pos(const char* string, size_t pos);
char* strops_insert_at_pos_string(const char* string, const char* string_to_insert, ull_t pos);
char* strops_remove_at_pos_char(const char* string, ull_t pos);
void strops_remove_at_pos_char_inplace(char* string, ull_t pos);
char* strops_trim_right_whitespace(const char* string);
char* strops_trim_left_whitespace(const char* string);
@ -31,10 +48,7 @@ char* strops_trim_both_string(const char* string, const char* string_to_remove);
char* strops_remove_chars(const char* string, const char* chars_to_remove);
char* strops_remove_string(const char* string, const char* string_to_remove);
size_t strops_word_count(const char* string);
/* https://www.w3schools.com/tags/ref_urlencode.asp */
char* strops_url_encode(const char* string);
char* strops_url_decode(const char* string);
ull_t strops_word_count(const char* string);
#endif /* STROPS_H */

455
tests.c Normal file
View File

@ -0,0 +1,455 @@
#include "strops.h"
#include <stdio.h>
#include <stdlib.h>
/* https://gist.githubusercontent.com/rexim/b5b0c38f53157037923e7cdd77ce685d/raw/86c3db57f485f3b6f7958f308ba7126fa81282d8/da_append.c */
#define da_append(xs, x) \
do { \
if ((xs)->count >= (xs)->capacity) { \
if ((xs)->capacity == 0) (xs)->capacity = 256; \
else (xs)->capacity *= 2; \
(xs)->items = realloc((xs)->items, (xs)->capacity*sizeof(*(xs)->items)); \
} \
\
(xs)->items[(xs)->count++] = (x); \
} while (0)
typedef int(*fnptr)();
typedef struct {
fnptr* items;
size_t capacity;
size_t count;
size_t amount_successful;
} Tests;
/* Test templates (Maybe make a macro in the future?)
int test_() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "";
expected = "";
result = strops_(input);
if (strcmp(result, expected) != 0) {
printf("test_ failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_() {
int ret = 1;
char* input;
int expected;
int result;
input = "";
expected = -1;
result = strops_(input);
if (result != expected) {
printf("test_ failed\n");
printf("Got = %d\nExpected = %d\n", result, expected);
ret = 0;
}
return ret;
}
*/
int test_contains_char() {
int ret = 1;
char* input;
char expected;
char result;
input = "string";
expected = 1;
result = strops_contains_char(input, 'i');
if (result != expected) {
printf("test_ failed\n");
printf("Got = %d\nExpected = %d\n", result, expected);
ret = 0;
}
return ret;
}
int test_contains_string() {
int ret = 1;
char* input;
char expected;
char result;
input = "I suck at C";
expected = 1;
result = strops_contains_string(input, "suck");
if (result != expected) {
printf("test_ failed\n");
printf("Got = %d\nExpected = %d\n", result, expected);
ret = 0;
}
return ret;
}
int test_to_lowercase() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "sTrInG";
expected = "string";
result = strops_to_lowercase(input);
if (strcmp(result, expected) != 0) {
printf("test_to_lowercase failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_to_uppercase() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "sTrInG";
expected = "STRING";
result = strops_to_uppercase(input);
if (strcmp(result, expected) != 0) {
printf("test_to_uppercase failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_is_lowercase() {
int ret = 1;
char* input;
int expected;
int result;
input = "string";
expected = 1;
result = strops_is_lowercase(input);
if (result != expected) {
printf("test_is_lowercase failed\n");
printf("Got = %d\nExpected = %d\n", result, expected);
ret = 0;
}
return ret;
}
int test_is_uppercase() {
int ret = 1;
char* input;
int expected;
int result;
input = "sTrInG";
expected = 0;
result = strops_is_uppercase(input);
if (result != expected) {
printf("test_is_uppercase failed\n");
printf("Got = %d\nExpected = %d\n", result, expected);
ret = 0;
}
return ret;
}
int test_insert_at_pos_string() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "Heo, World!";
expected = "Hello, World!";
result = strops_insert_at_pos_string(input, "ll", 2);
if (strcmp(result, expected) != 0) {
printf("test_insert_at_pos_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
input = "llo";
expected = "Hello";
result = strops_insert_at_pos_string(input, "He", 0);
if (strcmp(result, expected) != 0) {
printf("test_insert_at_pos_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
input = "He";
expected = "Hello";
result = strops_insert_at_pos_string(input, "llo", 2);
if (strcmp(result, expected) != 0) {
printf("test_insert_at_pos_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_remove_at_pos_char() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "Hello";
expected = "Hllo";
result = strops_remove_at_pos_char(input, 1);
if (strcmp(result, expected) != 0) {
printf("test_remove_at_pos_char failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
input = "_adad";
expected = "adad";
result = strops_remove_at_pos_char(input, 0);
if (strcmp(result, expected) != 0) {
printf("test_remove_at_pos_char failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
input = "adad_";
expected = "adad";
result = strops_remove_at_pos_char(input, 4);
if (strcmp(result, expected) != 0) {
printf("test_remove_at_pos_char failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_trim_right_whitespace() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "String \t\f\v\r\n ";
expected = "String";
result = strops_trim_right_whitespace(input);
if (strcmp(result, expected) != 0) {
printf("\ntest_trim_right_whitespace failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_trim_left_whitespace() {
int ret = 1;
char* input;
char* expected;
char* result;
input = " \t\f\v\r\n String";
expected = "String";
result = strops_trim_left_whitespace(input);
if (strcmp(result, expected) != 0) {
printf("\ntest_trim_left_whitespace failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_trim_both_whitespace() {
int ret = 1;
char* input;
char* expected;
char* result;
input = " \t\f\v String \r\n ";
expected = "String";
result = strops_trim_both_whitespace(input);
if (strcmp(result, expected) != 0) {
printf("\ntest_trim_both_whitespace failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_trim_right_chars() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "banana";
expected = "b";
result = strops_trim_right_chars(input, "na");
if (strcmp(result, expected) != 0) {
printf("test_right_chars failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_trim_left_chars() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "banana";
expected = "nana";
result = strops_trim_left_chars(input, "ba");
if (strcmp(result, expected) != 0) {
printf("test_left_chars failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_trim_both_chars() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "anna";
expected = "nn";
result = strops_trim_both_chars(input, "a");
if (strcmp(result, expected) != 0) {
printf("test_trim_both_chars failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_trim_right_string() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "adad_artist";
expected = "adad_";
result = strops_trim_right_string(input, "artist");
if (strcmp(result, expected) != 0) {
printf("test_trim_right_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_trim_left_string() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "adad_artist";
expected = "_artist";
result = strops_trim_left_string(input, "adad");
if (strcmp(result, expected) != 0) {
printf("test_trim_left_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_trim_both_string() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "NULLNULL Bruh NULLNULL";
expected = " Bruh ";
result = strops_trim_both_string(input, "NULL");
if (strcmp(result, expected) != 0) {
printf("test_trim_both_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_remove_chars() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "banana";
expected = "bnn";
result = strops_remove_chars(input, "a");
if (strcmp(result, expected) != 0) {
printf("test_remove_chars failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_remove_string() {
int ret = 1;
char* input;
char* expected;
char* result;
input = "I hate you";
expected = "I you";
result = strops_remove_string(input, "hate");
if (strcmp(result, expected) != 0) {
printf("test_remove_string failed\n");
printf("Got = '%s'\nExpected = '%s'\n", result, expected);
ret = 0;
}
return ret;
}
int test_word_count() {
int ret = 1;
char* input;
size_t expected;
size_t result;
input = "Hello, World!";
expected = 2;
result = strops_word_count(input);
if (result != expected) {
printf("test_word_count failed\n");
printf("Got = %ld\nExpected = %ld\n", result, expected);
ret = 0;
}
return ret;
}
int main() {
Tests tests = { 0 };
da_append(&tests, test_contains_char);
da_append(&tests, test_contains_string);
da_append(&tests, test_to_lowercase);
da_append(&tests, test_to_uppercase);
da_append(&tests, test_is_lowercase);
da_append(&tests, test_is_uppercase);
da_append(&tests, test_insert_at_pos_string);
da_append(&tests, test_remove_at_pos_char);
da_append(&tests, test_trim_right_whitespace);
da_append(&tests, test_trim_left_whitespace);
da_append(&tests, test_trim_both_whitespace);
da_append(&tests, test_trim_right_chars);
da_append(&tests, test_trim_left_chars);
da_append(&tests, test_trim_both_chars);
da_append(&tests, test_trim_right_string);
da_append(&tests, test_trim_left_string);
da_append(&tests, test_trim_both_string);
da_append(&tests, test_remove_chars);
da_append(&tests, test_remove_string);
da_append(&tests, test_word_count);
size_t i;
for (i = 0; i < tests.count; i++) {
tests.amount_successful += tests.items[i]();
}
if (tests.amount_successful != tests.count) {
printf("%d/%d tests passed successfully\n", tests.amount_successful, tests.count);
return 1;
} else {
printf("All tests passed successfully\n");
return 0;
}
}