From 2ec82fface9ddc64ab5112fb5ca5b538dcf34a35 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Mon, 28 Feb 2022 21:30:23 +0100 Subject: [PATCH] utils changes + tests (not yet ok) --- src/nsub/nsub.c | 12 +- src/nsub/nsub_read_lrc.c | 2 +- src/tests/launcher.h | 2 +- src/tests/utils/cstring.c | 362 ++++++++++++++++++++++++++------- src/utils/base64.c | 236 ++++++---------------- src/utils/base64.h | 23 +-- src/utils/cstring.c | 413 ++++++++++++++++---------------------- src/utils/cstring.h | 190 ++++-------------- src/utils/desktop.c | 22 +- src/utils/utils.c | 22 +- src/utils/utils.h | 30 +-- 11 files changed, 609 insertions(+), 705 deletions(-) diff --git a/src/nsub/nsub.c b/src/nsub/nsub.c index 2d91c62..ce88cf5 100644 --- a/src/nsub/nsub.c +++ b/src/nsub/nsub.c @@ -70,7 +70,7 @@ void song_add_unknown(song_t *song, char *text) { lyric.start = 0; lyric.stop = 0; lyric.name = NULL; - lyric.text = text ? utils_strdup(text) : NULL; + lyric.text = text ? strdup(text) : NULL; array_add(song->lyrics, &lyric); } @@ -92,7 +92,7 @@ void song_add_comment(song_t *song, char *comment) { lyric.start = 0; lyric.stop = 0; lyric.name = NULL; - lyric.text = comment ? utils_strdup(comment) : NULL; + lyric.text = comment ? strdup(comment) : NULL; array_add(song->lyrics, &lyric); } @@ -104,15 +104,15 @@ void song_add_lyric(song_t *song, int start, int stop, char *name, char *text) { lyric.num = song->current_num; lyric.start = start; lyric.stop = stop; - lyric.name = name ? utils_strdup(name) : NULL; - lyric.text = text ? utils_strdup(text) : NULL; + lyric.name = name ? strdup(name) : NULL; + lyric.text = text ? strdup(text) : NULL; array_add(song->lyrics, &lyric); } void song_add_meta(song_t *song, char *key, char *value) { meta_t meta; - meta.key = key ? utils_strdup(key) : NULL; - meta.value = value ? utils_strdup(value) : NULL; + meta.key = key ? strdup(key) : NULL; + meta.value = value ? strdup(value) : NULL; array_add(song->metas, &meta); } diff --git a/src/nsub/nsub_read_lrc.c b/src/nsub/nsub_read_lrc.c index c245d27..24938f8 100644 --- a/src/nsub/nsub_read_lrc.c +++ b/src/nsub/nsub_read_lrc.c @@ -87,7 +87,7 @@ int nsub_read_lrc(song_t *song, char *line) { line[colon] = '\0'; line[end] = '\0'; if (!strcmp("language", line + 1)) { - song->lang = utils_strdup(line + text_offset); + song->lang = strdup(line + text_offset); }else if (!strcmp("created_by", line + 1)) { // skip (we KNOW what program we are) } else { diff --git a/src/tests/launcher.h b/src/tests/launcher.h index 750a842..9a05a6b 100644 --- a/src/tests/launcher.h +++ b/src/tests/launcher.h @@ -22,7 +22,7 @@ ck_abort_msg("%s\n\tExpected: <%s>\n\tReceived: <%s>", title, expected, received #define ASSERT_EQUALS_INT(title, expected, received) \ if (expected != received) { \ -ck_abort_msg("%s\n\tExpected: %d\n\tReceived: %d", title, expected, received); \ +ck_abort_msg("%s\n\tExpected: %lld\n\tReceived: %lld", title, (long long)expected, (long long)received); \ } #define ASSERT_EQUALS_SIZE(title, expected, received) \ diff --git a/src/tests/utils/cstring.c b/src/tests/utils/cstring.c index 2df7764..1e899e6 100644 --- a/src/tests/utils/cstring.c +++ b/src/tests/utils/cstring.c @@ -24,18 +24,18 @@ cstring *s; -void test_cstring_setup() { +static void setup() { s = new_cstring(); } -void test_cstring_teardown() { +static void teardown() { free_cstring(s); s = NULL; } -void cstring_reset() { - test_cstring_teardown(); - test_cstring_setup(); +static void reset() { + teardown(); + setup(); } START(init) @@ -59,34 +59,34 @@ START(add_car) END -START(adds) +START(add_all_but_p) char *str; str = "testy"; cstring_add(s, str); ASSERT_EQUALS_STR("Short string", str, s->string); - cstring_reset(); + reset(); str = "Fanfan entre dans un bar"; cstring_add(s, str); ASSERT_EQUALS_STR("Medium string", str, s->string); - cstring_reset(); + reset(); str = "Ligne 1\nLigne 2\nLigne 3, attention 4 = vide\n"; cstring_add(s, str); ASSERT_EQUALS_STR("Multi-line", str, s->string); - cstring_reset(); + reset(); str = "Les accents en français sont bien là et se retrouvent avec une fréquence élevée"; cstring_add(s, str); ASSERT_EQUALS_STR("accents", str, s->string); - cstring_reset(); + reset(); str = "cents: ¢, copyright: ©, arrows: →↓↑←"; cstring_add(s, str); ASSERT_EQUALS_STR("UTF-8", str, s->string); - cstring_reset(); + reset(); str = "Os iusti meditabitur sapientiam,\n" "Et lingua\n" @@ -117,16 +117,49 @@ START(adds) "O castitatis lilium.\n"; cstring_add(s, str); ASSERT_EQUALS_STR("Long, multi-line string", str, s->string); - cstring_reset(); - - END - -START(clear) - if (!s) - FAIL("new_cstring returned NULL"); - - if (s->length) - FAIL("empty cstring has a size of %zu", s->length); + reset(); + + str = "String 1, String 2"; + cstring_add(s, "String 1, "); + cstring_add(s, "String 2"); + ASSERT_EQUALS_STR("Concat with add", str, s->string); + reset(); + + str = "0123456789"; + cstring_addf(s, str, 4); + ASSERT_EQUALS_STR("addf error (start at 4)", "456789", s->string); + reset(); + + str = "0123456789"; + cstring_addf(s, str, 4); + cstring_addf(s, str, 8); + str = "45678989"; + ASSERT_EQUALS_STR("Concat with addf", str, s->string); + reset(); + + str = "0123456789"; + cstring_addn(s, str, 4); + ASSERT_EQUALS_STR("addn error (4)", "0123", s->string); + reset(); + + str = "0123456789"; + cstring_addn(s, str, 4); + cstring_addn(s, str, 2); + str = "012301"; + ASSERT_EQUALS_STR("Concat with addn", str, s->string); + reset(); + + str = "0123456789"; + cstring_addfn(s, str, 4, 3); + ASSERT_EQUALS_STR("addf error (4, 3)", "456", s->string); + reset(); + + str = "0123456789"; + cstring_addfn(s, str, 4, 3); + cstring_addfn(s, str, 2, 2); + str = "45623"; + ASSERT_EQUALS_STR("Concat with addfn", str, s->string); + reset(); END @@ -135,79 +168,146 @@ START(addp) cstring_addp(s, "%d", 42); ASSERT_EQUALS_STR("Simple int", "42", s->string); - cstring_reset(); + reset(); cstring_addp(s, "%02d", 1); ASSERT_EQUALS_STR("Leading zero int", "01", s->string); - cstring_reset(); + reset(); cstring_addp(s, "%d", 352646); ASSERT_EQUALS_STR("Large int", "352646", s->string); - cstring_reset(); + reset(); str = "Simple test string"; cstring_addp(s, "%s", str); ASSERT_EQUALS_STR("Simple string", str, s->string); - cstring_reset(); + reset(); + str = "String 1, String 2"; cstring_addp(s, "%s", "String 1, "); - str = "String 2"; cstring_addp(s, "%s", "String 2"); - ASSERT_EQUALS_STR("Cumulative strings", "String 1, String 2", s->string); - cstring_reset(); + ASSERT_EQUALS_STR("Cumulative strings", str, s->string); + reset(); END -START(readln) - int read; - FILE *testin = fopen(TEST_FILE_READLN, "r"); - if (!testin) - FAIL("Test file not found: test_readln.txt"); +START(cut_at) + cstring_add(s, "0123456789"); + cstring_cut_at(s, 4); + ASSERT_EQUALS_STR("cut at failed", "0123", s->string); - read = cstring_readline(s, testin); - if (!read) - FAIL("first line should not be last"); - ASSERT_EQUALS_STR("first line incorrect", "ligne 1", s->string); - cstring_reset(); + END - read = cstring_readline(s, testin); - if (!read) - FAIL("second line should not be last"); - ASSERT_EQUALS_STR("second line incorrect", "", s->string); - cstring_reset(); +START(substring) + free_cstring(s); + s = cstring_substring("0123456789", 4, 2); + ASSERT_EQUALS_STR("substring failed 4,2", "45", s->string); - read = cstring_readline(s, testin); - if (!read) - FAIL("third line should not be last"); - ASSERT_EQUALS_STR("third line incorrect", "ligne 3", s->string); - cstring_reset(); + free_cstring(s); + s = cstring_substring("0123456789", 0, 4); + ASSERT_EQUALS_STR("substring failed 0,4", "0123", s->string); - if (cstring_readline(s, testin)) { - FAIL("fourth line should not exist"); - } + free_cstring(s); + s = cstring_substring("0123456789", 3, 0); + ASSERT_EQUALS_STR("substring failed 3,0", "3456789", s->string); + + free_cstring(s); + s = cstring_substring("0123456789", 0, 0); + ASSERT_EQUALS_STR("substring failed 0,0", "0123456789", s->string); END -START(ends_with) - char *end; +START(reverse) + cstring_add(s, "kayak"); + cstring_reverse(s->string); + ASSERT_EQUALS_STR("reversing a palyndrome failed", "kayak", s->string); + reset(); - cstring_add(s, "fichier.ext"); + cstring_add(s, "plantigrade"); + cstring_reverse(s->string); + ASSERT_EQUALS_STR("reverse failed", "edargitnalp", s->string); + reset(); - end = ".ext"; - if (!cstring_ends_with(s, end)) - FAIL("fichier.ext does not end in %s", end); + cstring_add(s, "123"); + cstring_reverse(s->string); + ASSERT_EQUALS_STR("reverse failed", "321", s->string); + reset(); - end = ".ex"; - if (cstring_ends_with(s, end)) - FAIL("fichier.ext ends in %s", end); + cstring_add(s, "1234"); + cstring_reverse(s->string); + ASSERT_EQUALS_STR("reverse failed", "4321", s->string); + reset(); - end = "aext"; - if (cstring_ends_with(s, end)) - FAIL("fichier.ext does not end in %s", end); + END - end = ""; - if (!cstring_ends_with(s, end)) - FAIL("fichier.ext does not end with nothing"); +START(replace) + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(a) Bad number of replacements returned", 0, + cstring_replace(s, "", "")); + ASSERT_EQUALS_STR("Replacement failed", "test string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(b) Bad number of replacements returned", 1, + cstring_replace(s, "AC/DC", "AC/DC")); + ASSERT_EQUALS_STR("Replacement failed", "test string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(c) Bad number of replacements returned", 1, + cstring_replace(s, "AC/DC", "woof")); + ASSERT_EQUALS_STR("Replacement failed", "test string woof", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(d) Bad number of replacements returned", 2, + cstring_replace(s, "C", "*")); + ASSERT_EQUALS_STR("Replacement failed", "test string A*/D*", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(e) Bad number of replacements returned", 1, + cstring_replace(s, "test ", "")); + ASSERT_EQUALS_STR("Replacement failed", "string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(f) Bad number of replacements returned", 1, + cstring_replace(s, "test ", "longer test ")); + ASSERT_EQUALS_STR("Replacement failed", "longer test string AC/DC", + s->string); + + END + +START(replace_car) + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(a) Bad number of replacements returned", 0, + cstring_replace_car(s->string, '?', '!')); + ASSERT_EQUALS_STR("Replacement failed", "test string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(b) Bad number of replacements returned", 1, + cstring_replace_car(s->string, '/', '/')); + ASSERT_EQUALS_STR("Replacement failed", "test string AC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(c) Bad number of replacements returned", 1, + cstring_replace_car(s->string, 'A', 'a')); + ASSERT_EQUALS_STR("Replacement failed", "test string aC/DC", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(d) Bad number of replacements returned", 2, + cstring_replace_car(s->string, 'C', '*')); + ASSERT_EQUALS_STR("Replacement failed", "test string A*/D*", s->string); + + reset(); + cstring_add(s, "test string AC/DC"); + ASSERT_EQUALS_INT("(e) Bad number of replacements returned", 1, + cstring_replace_car(s->string, '/', '\0')); + ASSERT_EQUALS_STR("Replacement failed", "test string AC", s->string); END @@ -217,27 +317,128 @@ START(starts_with) cstring_add(s, "fichier.ext"); start = "fichier"; - if (!cstring_starts_with(s, start, 0)) + if (!cstring_starts_with(s->string, start, 0)) FAIL("fichier.ext does not start with %s", start); start = "ichier"; - if (cstring_starts_with(s, start, 0)) + if (cstring_starts_with(s->string, start, 0)) FAIL("fichier.ext starts with %s", start); start = "afichier"; - if (cstring_starts_with(s, start, 0)) + if (cstring_starts_with(s->string, start, 0)) FAIL("fichier.ext starts with %s", start); start = ""; - if (!cstring_starts_with(s, start, 0)) + if (!cstring_starts_with(s->string, start, 0)) FAIL("fichier.ext does not start with nothing"); start = "chier"; - if (!cstring_starts_with(s, start, 2)) + if (!cstring_starts_with(s->string, start, 2)) FAIL("fichier.ext +2 does not start with %s", start); END +START(ends_with) + char *end; + + cstring_add(s, "fichier.ext"); + + end = ".ext"; + if (!cstring_ends_with(s->string, end)) + FAIL("fichier.ext does not end in %s", end); + + end = ".ex"; + if (cstring_ends_with(s->string, end)) + FAIL("fichier.ext ends in %s", end); + + end = "aext"; + if (cstring_ends_with(s->string, end)) + FAIL("fichier.ext does not end in %s", end); + + end = ""; + if (!cstring_ends_with(s->string, end)) + FAIL("fichier.ext does not end with nothing"); + + END + +START(find) + char *str = "Une petite string pour y chercher des choses"; + + ASSERT_EQUALS_INT("(a) find error", 0, cstring_find(str, "Une", 0)); + ASSERT_EQUALS_INT("(b) find error", -1, cstring_find(str, "Une", 1)); + ASSERT_EQUALS_INT("(c) find error", 4, cstring_find(str, "petite", 0)); + ASSERT_EQUALS_INT("(d) find error", 4, cstring_find(str, "petite", 1)); + ASSERT_EQUALS_INT("(e) find error", 4, cstring_find(str, "petite", 2)); + ASSERT_EQUALS_INT("(f) find error", 4, cstring_find(str, "petite", 3)); + ASSERT_EQUALS_INT("(g) find error", 4, cstring_find(str, "petite", 4)); + ASSERT_EQUALS_INT("(h) find error", -1, cstring_find(str, "petite", 5)); + ASSERT_EQUALS_INT("(i) find error", 38, cstring_find(str, "choses", 0)); + ASSERT_EQUALS_INT("(j) find error", -1, cstring_find(str, "Oops", 0)); + ASSERT_EQUALS_INT("(k) find error", 2, cstring_find(str, "e", 0)); + ASSERT_EQUALS_INT("(l) find error", 2, cstring_find(str, "e", 1)); + ASSERT_EQUALS_INT("(m) find error", 2, cstring_find(str, "e", 2)); + ASSERT_EQUALS_INT("(n) find error", 5, cstring_find(str, "e", 3)); + ASSERT_EQUALS_INT("(o) find error", 9, cstring_find(str, "e", 6)); + + END + +START(rfind) + char *str = "Une petite string pour y chercher des choses"; + + ASSERT_EQUALS_INT("(a) find error", 0, cstring_rfind(str, "Une", 0)); + ASSERT_EQUALS_INT("(b) find error", 0, cstring_rfind(str, "Une", 1)); + ASSERT_EQUALS_INT("(c) find error", 4, cstring_rfind(str, "petite", 0)); + ASSERT_EQUALS_INT("(d) find error", 4, cstring_rfind(str, "petite", 11)); + ASSERT_EQUALS_INT("(e) find error", -1, cstring_rfind(str, "petite", 2)); + ASSERT_EQUALS_INT("(f) find error", 38, cstring_rfind(str, "choses", 0)); + ASSERT_EQUALS_INT("(g) find error", -1, cstring_rfind(str, "Oops", 0)); + ASSERT_EQUALS_INT("(h) find error", 42, cstring_rfind(str, "e", 0)); + ASSERT_EQUALS_INT("(i) find error", 42, cstring_rfind(str, "e", -1)); + //ASSERT_EQUALS_INT("(j) find error", 35, cstring_rfind(str, "e", -2)); + ASSERT_EQUALS_INT("(k) find error", 35, cstring_rfind(str, "e", -3)); + ASSERT_EQUALS_INT("(l) find error", 35, cstring_rfind(str, "e", 38)); + + END + +START(clear) + if (!s) + FAIL("new_cstring returned NULL"); + + if (s->length) + FAIL("empty cstring has a size of %zu", s->length); + + END + +START(readln) + int read; + FILE *testin = fopen(TEST_FILE_READLN, "r"); + if (!testin) + FAIL("Test file not found: test_readln.txt"); + + read = cstring_readline(s, testin); + if (!read) + FAIL("first line should not be last"); + ASSERT_EQUALS_STR("first line incorrect", "ligne 1", s->string); + reset(); + + read = cstring_readline(s, testin); + if (!read) + FAIL("second line should not be last"); + ASSERT_EQUALS_STR("second line incorrect", "", s->string); + reset(); + + read = cstring_readline(s, testin); + if (!read) + FAIL("third line should not be last"); + ASSERT_EQUALS_STR("third line incorrect", "ligne 3", s->string); + reset(); + + if (cstring_readline(s, testin)) { + FAIL("fourth line should not exist"); + } + + END + START(many_adds) size_t count = 50000000; for (size_t i = 0; i < count; i++) { @@ -252,16 +453,25 @@ Suite *test_cstring(const char title[]) { Suite *suite = suite_create(title); TCase *core = tcase_create("core"); - tcase_add_checked_fixture(core, test_cstring_setup, test_cstring_teardown); + tcase_add_checked_fixture(core, setup, teardown); tcase_add_test(core, init); tcase_add_test(core, add_car); - tcase_add_test(core, adds); - tcase_add_test(core, clear); + tcase_add_test(core, add_all_but_p); tcase_add_test(core, addp); - tcase_add_test(core, readln); + tcase_add_test(core, cut_at); + tcase_add_test(core, substring); + tcase_add_test(core, reverse); + tcase_add_test(core, replace); + tcase_add_test(core, replace_car); tcase_add_test(core, ends_with); tcase_add_test(core, starts_with); + tcase_add_test(core, find); + tcase_add_test(core, rfind); + + tcase_add_test(core, clear); + tcase_add_test(core, readln); + suite_add_tcase(suite, core); return suite; @@ -271,7 +481,7 @@ Suite *test_cstring_more(const char title[]) { Suite *suite = suite_create(title); TCase *tmore = tcase_create("more"); - tcase_add_checked_fixture(tmore, test_cstring_setup, test_cstring_teardown); + tcase_add_checked_fixture(tmore, setup, teardown); tcase_add_test(tmore, many_adds); suite_add_tcase(suite, tmore); diff --git a/src/utils/base64.c b/src/utils/base64.c index cf6657c..c05a284 100644 --- a/src/utils/base64.c +++ b/src/utils/base64.c @@ -17,216 +17,108 @@ * along with this program. If not, see . */ -#include +#include "base64.h" + +#include +#include #include #include -#include "base64.h" -#include "cstring.h" - -cstring *base64_decodesi(base64 *self, char *data, size_t len); -//cstring *base64_encodesi(base64 *self, char *data, size_t len); - -char *b64_encode(const char *data, const char *encoding_table, - size_t input_length, - size_t *output_length); - -char *b64_decode(const char *data, const char *decoding_table, - size_t input_length, - size_t *output_length); - -static char b64_encoding_table[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/'}; - -static int b64_mod_table[] = {0, 2, 1}; - -base64 *base64_new() { - base64 *self; - int i; - - self = (base64 *)malloc(sizeof(base64)); - self->table = malloc(256 * sizeof(char)); - - for (i = 0; i < 64; i++) - self->table[(unsigned char)b64_encoding_table[i]] = i; - - return self; -} -void base64_free(base64 *self) { - if (!self) - return; - - free(self->table); - free(self); -} +static char *create_dtable(); -cstring *base64_encode(base64 *self, cstring *data) { - if (!data) - return NULL; - - return base64_encodesi(self, data->string, data->length); -} +static char encoding_table[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; -cstring *base64_decode(base64 *self, cstring *data) { - if (!data) - return NULL; - - return base64_decodesi(self, data->string, data->length); -} +static char *decoding_table = NULL; -cstring *base64_encodes(base64 *self, char *data) { - size_t len; - - if (!data) - return NULL; - - len = strlen(data); - - return base64_encodesi(self, data, len); -} +static int b64_mod_table[] = { 0, 2, 1 }; -cstring *base64_decodes(base64 *self, char *data) { - size_t len; - - if (data) - len = strlen(data); - - return base64_decodesi(self, data, len); -} +static char *create_dtable() { + char *decoding_table = malloc(256 * sizeof(char)); + for (int i = 0; i < 64; i++) + decoding_table[(unsigned char) encoding_table[i]] = i; -cstring *base64_encodesi(base64 *self, char *data, size_t len) { - cstring *rep; - char *encoded; - size_t size; - - rep = NULL; - size = 0; - encoded = b64_encode(data, b64_encoding_table, len, &size); - - if (encoded) { - rep = new_cstring(); - free(rep->string); - rep->string = encoded; - rep->length = size; - cstring_compact(rep); - } - - return rep; -} - -cstring *base64_decodesi(base64 *self, char *data, size_t len) { - cstring *rep; - char *decoded; - size_t size; - - rep = NULL; - size = 0; - decoded = b64_decode(data, self->table, len, &size); - - if (decoded) { - rep = new_cstring(); - free(rep->string); - rep->string = decoded; - rep->length = size; - cstring_compact(rep); - } - - return rep; + return decoding_table; } -char *b64_encode(const char *data, const char *encoding_table, - size_t input_length, - size_t *output_length) { - unsigned int i, j; - - *output_length = 4 * ((input_length + 2) / 3) + 1; +char *base64_encode(const char *data) { + size_t input_length = strlen(data); + size_t output_length = 4 * ((input_length + 2) / 3) + 1; - char *encoded_data = malloc(*output_length); + char *encoded_data = malloc(output_length); if (encoded_data == NULL) return NULL; - for (i = 0, j = 0 ; i < input_length ; ) { - uint32_t octet_a = i < input_length ? - (unsigned char)data[i++] : 0; - uint32_t octet_b = i < input_length ? - (unsigned char)data[i++] : 0; - uint32_t octet_c = i < input_length ? - (unsigned char)data[i++] : 0; - - uint32_t triple = (octet_a << 0x10) - + (octet_b << 0x08) - + octet_c; - - encoded_data[j++] = - (char)encoding_table[(triple >> 3 * 6) & 0x3F]; - encoded_data[j++] = - (char)encoding_table[(triple >> 2 * 6) & 0x3F]; - encoded_data[j++] = - (char)encoding_table[(triple >> 1 * 6) & 0x3F]; - encoded_data[j++] = - (char)encoding_table[(triple >> 0 * 6) & 0x3F]; + for (unsigned int i = 0, j = 0; i < input_length;) { + uint32_t octet_a = i < input_length ? (unsigned char) data[i++] : 0; + uint32_t octet_b = i < input_length ? (unsigned char) data[i++] : 0; + uint32_t octet_c = i < input_length ? (unsigned char) data[i++] : 0; + + uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; + + encoded_data[j++] = (char) encoding_table[(triple >> 3 * 6) & 0x3F]; + encoded_data[j++] = (char) encoding_table[(triple >> 2 * 6) & 0x3F]; + encoded_data[j++] = (char) encoding_table[(triple >> 1 * 6) & 0x3F]; + encoded_data[j++] = (char) encoding_table[(triple >> 0 * 6) & 0x3F]; } - for (i = 0 ; (int)i < b64_mod_table[input_length % 3] ; i++) - encoded_data[*output_length - 2 - i] = '='; - encoded_data[*output_length - 1] = '\0'; + for (unsigned int i = 0; (int) i < b64_mod_table[input_length % 3]; i++) + encoded_data[output_length - 2 - i] = '='; + + encoded_data[output_length - 1] = '\0'; return encoded_data; } +char *base64_decode(const char *data) { + if (!decoding_table) + decoding_table=create_dtable(); -char *b64_decode(const char *data, const char *decoding_table, - size_t input_length, - size_t *output_length) { - - unsigned int i, j; + size_t input_length = strlen(data); + size_t output_length = 4 * ((input_length + 2) / 3) + 1; if (input_length % 4 != 0) return NULL; - *output_length = (input_length / 4 * 3) + 1; - if (data[input_length - 2] == '=') (*output_length)--; - if (data[input_length - 3] == '=') (*output_length)--; + output_length = (input_length / 4 * 3) + 1; + if (data[input_length - 2] == '=') + output_length--; + if (data[input_length - 3] == '=') + output_length--; - char *decoded_data = malloc(*output_length); + char *decoded_data = malloc(output_length); if (decoded_data == NULL) return NULL; - i = j = 0; - for ( ; i < input_length ; i += 4) { + for (unsigned int i = 0, j = 0; i < input_length; i += 4) { uint32_t sextet_a = 0; uint32_t sextet_b = 0; uint32_t sextet_c = 0; uint32_t sextet_d = 0; - + if (data[i] != '=') { - sextet_a = decoding_table[(unsigned char)data[i + 0]]; - sextet_b = decoding_table[(unsigned char)data[i + 1]]; - sextet_c = decoding_table[(unsigned char)data[i + 2]]; - sextet_d = decoding_table[(unsigned char)data[i + 3]]; + sextet_a = decoding_table[(unsigned char) data[i + 0]]; + sextet_b = decoding_table[(unsigned char) data[i + 1]]; + sextet_c = decoding_table[(unsigned char) data[i + 2]]; + sextet_d = decoding_table[(unsigned char) data[i + 3]]; } - - uint32_t triple = (sextet_a << 3 * 6) - + (sextet_b << 2 * 6) - + (sextet_c << 1 * 6) - + (sextet_d << 0 * 6); - - if (j + 1 < *output_length) - decoded_data[j++] = (char)((triple >> 2 * 8) & 0xFF); - if (j + 1 < *output_length) - decoded_data[j++] = (char)((triple >> 1 * 8) & 0xFF); - if (j + 1 < *output_length) - decoded_data[j++] = (char)((triple >> 0 * 8) & 0xFF); + + uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + + (sextet_c << 1 * 6) + (sextet_d << 0 * 6); + + if (j + 1 < output_length) + decoded_data[j++] = (char) ((triple >> 2 * 8) & 0xFF); + if (j + 1 < output_length) + decoded_data[j++] = (char) ((triple >> 1 * 8) & 0xFF); + if (j + 1 < output_length) + decoded_data[j++] = (char) ((triple >> 0 * 8) & 0xFF); } - decoded_data[*output_length - 1] = '\0'; + decoded_data[output_length - 1] = '\0'; return decoded_data; } diff --git a/src/utils/base64.h b/src/utils/base64.h index 7bd9afe..84226ab 100644 --- a/src/utils/base64.h +++ b/src/utils/base64.h @@ -25,33 +25,14 @@ extern "C" { #define BASE64_H #include -#include "cstring.h" typedef struct { char *table; } base64; -/** - * Create a new base64 codec. - * - * @return a new codec - */ -base64 *base64_new(); - -/** - * Free the given code. - */ -void base64_free(base64 *self); - -cstring *base64_encode(base64 *self, cstring *data); - -cstring *base64_decode(base64 *self, cstring *data); - -cstring *base64_encodes(base64 *self, char *data); - -cstring *base64_encodesi(base64 *self, char *data, size_t size); +char *base64_encode(const char data[]); -cstring *base64_decodes(base64 *self, char *data); +char *base64_decode(const char data[]); #endif diff --git a/src/utils/cstring.c b/src/utils/cstring.c index c7f2548..56a79fe 100644 --- a/src/utils/cstring.c +++ b/src/utils/cstring.c @@ -25,32 +25,13 @@ Description: cstring is a collection of helper functions to manipulate string of text */ +#include "cstring.h" + +#include #include -#include #include -#include #include #include -#include -#include - -/* Windows (and maybe others?) doesn't know about strnlen */ -#ifndef strnlen -size_t strnlen(const char *s, size_t maxlen); -size_t strnlen(const char *s, size_t maxlen) { - size_t i; - for (i = 0; s[i]; i++) { - if (i >= maxlen) - return maxlen; - } - - return i; -} -#endif - -#include "cstring.h" -#include "net.h" -#include "base64.h" #ifndef BUFFER_SIZE #define BUFFER_SIZE 81 @@ -64,11 +45,14 @@ size_t strnlen(const char *s, size_t maxlen) { //start of private prototypes -struct cstring_private_struct { +typedef struct { size_t buffer_length; -}; +} priv_t; -void cstring_change_case(cstring *self, int up); +/** Swap the data */ +static void cstring_swap(cstring *a, cstring *b); +/** Change the case to upper -or- lower case (UTF8-compatible) */ +static void cstring_change_case(cstring *self, int up); //end of private prototypes @@ -77,9 +61,9 @@ cstring *new_cstring() { string = malloc(sizeof(cstring)); strcpy(string->CNAME, "[CString]"); - string->priv = malloc(sizeof(struct cstring_private_struct)); + string->priv = malloc(sizeof(priv_t)); string->length = 0; - string->priv->buffer_length = BUFFER_SIZE; + ((priv_t *) string->priv)->buffer_length = BUFFER_SIZE; string->string = malloc(sizeof(char) * BUFFER_SIZE); string->string[0] = '\0'; @@ -96,8 +80,28 @@ void free_cstring(cstring *string) { free(string); } +void cstring_swap(cstring *a, cstring *b) { + void *tmp_p; + char *tmp_s; + size_t tmp_l; + + tmp_s = a->string; + tmp_l = a->length; + tmp_p = a->priv; + + a->string = b->string; + a->length = b->length; + a->priv = b->priv; + + b->string = tmp_s; + b->length = tmp_l; + b->priv = tmp_p; +} + int cstring_grow(cstring *self, int min_extra) { - size_t sz = self->priv->buffer_length; + priv_t *priv = ((priv_t *) self->priv); + + size_t sz = priv->buffer_length; size_t req = self->length + min_extra; if (req > sz) { @@ -112,10 +116,11 @@ int cstring_grow(cstring *self, int min_extra) { } int cstring_grow_to(cstring *self, int min_buffer) { - void *mem; - if (min_buffer > self->priv->buffer_length) { - self->priv->buffer_length = min_buffer; - mem = realloc(self->string, sizeof(char) * self->priv->buffer_length); + priv_t *priv = ((priv_t *) self->priv); + + if (min_buffer > priv->buffer_length) { + priv->buffer_length = min_buffer; + void *mem = realloc(self->string, sizeof(char) * priv->buffer_length); if (mem) self->string = (char *) mem; @@ -126,13 +131,24 @@ int cstring_grow_to(cstring *self, int min_buffer) { return 1; } +void cstring_compact(cstring *self) { + if (self != NULL) { + priv_t *priv = ((priv_t *) self->priv); + + priv->buffer_length = self->length + 1; + self->string = (char *) realloc(self->string, self->length + 1); + } +} + int cstring_add_car(cstring *self, char source) { - char source2[2]; + if (!cstring_grow(self, 1)) + return 0; - source2[0] = source; - source2[1] = '\0'; + self->string[self->length] = source; + self->length++; + self->string[self->length] = '\0'; - return cstring_add(self, source2); + return 1; } int cstring_add(cstring *self, const char source[]) { @@ -140,8 +156,7 @@ int cstring_add(cstring *self, const char source[]) { } int cstring_addf(cstring *self, const char source[], size_t idx) { - // Note: negative 'n' is not promised by the .h file - return cstring_addfn(self, source, idx, -1); + return cstring_addfn(self, source, idx, 0); } int cstring_addn(cstring *self, const char source[], size_t n) { @@ -155,8 +170,7 @@ int cstring_addfn(cstring *self, const char source[], size_t idx, size_t n) { if (source && ss > idx && idx >= 0) { ss -= idx; - // Note: negative 'n' is not promised by the .h file - if (n >= 0 && n < ss) + if (n && n < ss) ss = n; if (ss) { @@ -165,8 +179,8 @@ int cstring_addfn(cstring *self, const char source[], size_t idx, size_t n) { return 0; memcpy(self->string + self->length, source + idx, ss); - self->string[ss] = '\0'; - self->length += ss + 1; + self->length += ss; + self->string[self->length] = '\0'; } } @@ -195,64 +209,27 @@ int cstring_addp(cstring *self, const char *fmt, ...) { return ok; } -char *cstring_convert(cstring *self) { - char *string; - - if (!self) - return NULL; - - // Note: this could be skipped. - cstring_compact(self); - - free(self->priv); - string = (self->string); - free(self); - - return string; -} - -cstring *cstring_clone(cstring *self) { - if (self == NULL) - return NULL; - - return cstring_clones(self->string); -} - -char *cstring_sclone(cstring *self) { - if (self == NULL) - return NULL; - - return cstring_convert(cstring_clone(self)); -} - -char *cstring_sclones(const char self[]) { - return cstring_convert(cstring_clones(self)); +void cstring_cut_at(cstring *self, size_t size) { + if (self->length > size) { + self->string[size] = '\0'; + self->length = size; + } } -cstring *cstring_clones(const char self[]) { - cstring *clone; - - if (self == NULL) - return NULL; - - clone = new_cstring(); - cstring_add(clone, self); +cstring *cstring_substring(const char self[], size_t start, size_t length) { + size_t sz = strlen(self); + cstring * sub = new_cstring(); - return clone; -} + if (start <= sz) { + const char *source = (self + start); -void cstring_compact(cstring *self) { - if (self != NULL) { - self->priv->buffer_length = self->length + 1; - self->string = (char *) realloc(self->string, self->length + 1); + if (!length) + cstring_add(sub, source); + else + cstring_addn(sub, source, length); } -} -void cstring_cut_at(cstring *self, size_t size) { - if (self->length > size) { - self->string[size] = '\0'; - self->length = size; - } + return sub; } /* @@ -337,50 +314,87 @@ void cstring_cut_at(cstring *self, size_t size) { } */ -cstring *cstring_substring(cstring *self, size_t start, size_t length) { - cstring *sub; - char *source; +void cstring_reverse(char *self) { + size_t i; + size_t last; + char tmp; - if (length == 0) { - length = self->length - start; + size_t sz = strlen(self); + if (sz) { + last = sz - 1; + for (i = 0; i <= (last / 2); i++) { + tmp = self[i]; + self[i] = self[last - i]; + self[last - i] = tmp; + } } +} - sub = new_cstring(); - source = self->string; - source = source + start; +int cstring_replace(cstring *self, const char from[], const char to[]) { + cstring *buffer; + size_t i; + size_t step; + char *swap; + int occur; - cstring_addn(sub, source, length); + // easy optimization: + if (!from || !from[0]) + return 0; + if (from && to && from[0] && to[0] && !from[1] && !to[1]) + return cstring_replace_car(self->string, from[0], to[0]); - return sub; + // optimize for same-size strings? + + step = strlen(from) - 1; + buffer = new_cstring(); + occur = 0; + for (i = 0; i < self->length; i++) { + if (cstring_starts_with(self->string, from, i)) { + cstring_add(buffer, to); + i += step; + occur++; + } else { + cstring_add_car(buffer, self->string[i]); + } + } + + // not clean, but quicker: + swap = self->string; + self->string = buffer->string; + buffer->string = swap; + self->length = buffer->length; + + free_cstring(buffer); + return occur; } -int cstring_starts_with(cstring *self, const char find[], size_t start_index) { - return cstring_sstarts_with(self->string, find, start_index); +int cstring_replace_car(char *self, char from, char to) { + size_t i; + int occur = 0; + + for (i = 0; self[i]; i++) { + if (self[i] == from) { + self[i] = to; + occur++; + } + } + + return occur; } -int cstring_sstarts_with(const char string[], const char find[], - size_t start_index) { +int cstring_starts_with(const char string[], const char find[], + size_t start_idx) { size_t i; for (i = 0; - string[start_index + i] == find[i] - && string[start_index + i] != '\0' && find[i] != '\0'; i++) + string[start_idx + i] == find[i] && string[start_idx + i] != '\0' + && find[i] != '\0'; i++) ; return find[i] == '\0'; } -int cstring_ends_with(cstring *self, const char find[]) { - size_t sz_needle = strlen(find); - if (sz_needle <= self->length) { - if (!strcmp(self->string + (self->length - sz_needle), find)) - return 1; - } - - return 0; -} - -int cstring_sends_with(const char self[], const char find[]) { +int cstring_ends_with(const char self[], const char find[]) { size_t sz = strlen(self); size_t sz_needle = strlen(find); if (sz_needle <= sz) { @@ -403,91 +417,56 @@ long cstring_find(const char self[], const char find[], size_t start_index) { return -1; } -long cstring_rfind(char self[], const char find[], size_t rstart_index) { +long cstring_rfind(char self[], const char find[], long rstart_index) { size_t sz = strlen(self); size_t sz_needle = strlen(find); if (rstart_index <= 0) - rstart_index += (sz - 1); + rstart_index = (sz - 1); if (sz > rstart_index && sz_needle <= sz) { - for (size_t i = sz - sz_needle; i; i--) { - if (cstring_sstarts_with(self, find, i)) + for (size_t i = rstart_index;; i--) { + if (cstring_starts_with(self, find, i)) return i; + + if (!i) + break; } } return -1; } -int cstring_replace_car(cstring *self, char from, char to) { - size_t i; - int occur = 0; - - for (i = 0; i < self->length; i++) { - if (self->string[i] == from) { - self->string[i] = to; - occur++; - } - } - - return occur; +void cstring_clear(cstring *self) { + self->length = 0; + self->string[0] = '\0'; } -int cstring_replace(cstring *self, const char from[], const char to[]) { - cstring *buffer; - size_t i; - size_t step; - char *swap; - int occur; +char *cstring_convert(cstring *self) { + char *string; - // easy optimization: - if (from && to && from[0] && to[0] && !from[1] && !to[1]) - return cstring_replace_car(self, from[0], to[0]); + if (!self) + return NULL; - // optimize for same-size strings? + // Note: this could be skipped. + cstring_compact(self); - step = strlen(from) - 1; - buffer = new_cstring(); - occur = 0; - for (i = 0; i < self->length; i++) { - if (cstring_starts_with(self, from, i)) { - cstring_add(buffer, to); - i += step; - occur++; - } else { - cstring_add_car(buffer, self->string[i]); - } - } + string = (self->string); + self->string = NULL; - // not clean, but quicker: - swap = self->string; - self->string = buffer->string; - buffer->string = swap; - self->length = buffer->length; + free_cstring(self); - free_cstring(buffer); - return occur; + return string; } -void cstring_clear(cstring *self) { - self->length = 0; - self->string[0] = '\0'; -} +cstring *cstring_clone(cstring *self) { + if (self == NULL) + return NULL; -void cstring_reverse(cstring *self) { - size_t i; - size_t last; - char tmp; + cstring *clone = new_cstring(); + cstring_add(clone, self->string); - if (self->length > 0) { - last = self->length - 1; - for (i = 0; i <= (last / 2); i++) { - tmp = self->string[i]; - self->string[i] = self->string[last - i]; - self->string[last - i] = tmp; - } - } + return clone; } void cstring_rtrim(cstring *self, char car) { @@ -513,10 +492,7 @@ void cstring_trim(cstring *self, char car) { cstring *tmp = new_cstring(); cstring_add(tmp, self->string + i); - free(self->string); - self->priv->buffer_length = tmp->priv->buffer_length; - self->string = tmp->string; - tmp->string = NULL; + cstring_swap(self, tmp); free_cstring(tmp); } } @@ -559,10 +535,10 @@ void cstring_change_case(cstring *self, int up) { size_t s, i; mbstate_t state; -// init the state (passing NULL is not thread-safe) + // init the state (passing NULL is not thread-safe) memset(&state, '\0', sizeof(mbstate_t)); -// won't contain MORE chars (but maybe less) + // won't contain MORE chars (but maybe less) wide = (wchar_t *) malloc((self->length + 1) * sizeof(wchar_t)); s = mbsrtowcs(wide, &src, self->length, &state); wide[s] = (wchar_t) '\0'; @@ -584,7 +560,7 @@ int cstring_readline(cstring *self, FILE *file) { size_t size = 0; int full_line; -// sanity check: + // sanity check: if (!file) return 0; @@ -679,65 +655,20 @@ cstring *cstring_getfile(cstring *path) { if (i < 0 || (size_t) (i + 1) >= path->length) return new_cstring(); - result = cstring_clones(path->string + i + 1); + result = new_cstring(); + cstring_add(result, path->string + i + 1); return result; } cstring *cstring_getfiles(const char path[]) { - cstring *copy, *result; - - copy = cstring_clones(path); - result = cstring_getfile(copy); - free_cstring(copy); - return result; -} - -cstring *cstring_to_b64(cstring *self) { - static base64 *cstring_b64 = NULL; - if (!cstring_b64) - cstring_b64 = base64_new(); - - return base64_encode(cstring_b64, self); -} + cstring *copy = new_cstring(); + cstring_add(copy, path); -char *cstring_to_sb64(cstring *self) { - static base64 *cstring_b64 = NULL; - if (!cstring_b64) - cstring_b64 = base64_new(); + cstring *result = cstring_getfile(copy); - return cstring_convert(base64_encode(cstring_b64, self)); -} - -char *cstring_to_sb64s(char *self, size_t size) { - static base64 *cstring_b64 = NULL; - if (!cstring_b64) - cstring_b64 = base64_new(); - - return cstring_convert(base64_encodesi(cstring_b64, self, size)); -} - -cstring *cstring_from_b64(cstring *self) { - static base64 *cstring_b64 = NULL; - if (!cstring_b64) - cstring_b64 = base64_new(); - - return base64_decode(cstring_b64, self); -} - -char *cstring_from_sb64(cstring *self) { - static base64 *cstring_b64 = NULL; - if (!cstring_b64) - cstring_b64 = base64_new(); - - return cstring_convert(base64_decode(cstring_b64, self)); -} - -char *cstring_from_sb64s(char *self) { - static base64 *cstring_b64 = NULL; - if (!cstring_b64) - cstring_b64 = base64_new(); + free_cstring(copy); - return cstring_convert(base64_decodes(cstring_b64, self)); + return result; } int cstring_is_whole(cstring *self) { diff --git a/src/utils/cstring.h b/src/utils/cstring.h index 1ceb888..7a378f0 100644 --- a/src/utils/cstring.h +++ b/src/utils/cstring.h @@ -34,13 +34,12 @@ extern "C" { * MUST NOT be used again, and you are responsible for freeing the said char*). */ typedef struct cstring_struct cstring; -typedef struct cstring_private_struct cstring_private; struct cstring_struct { char CNAME[32]; char *string; size_t length; - cstring_private *priv; + void *priv; }; /** @@ -83,6 +82,13 @@ int cstring_grow(cstring *self, int min_extra); */ int cstring_grow_to(cstring *self, int min_buffer); +/** + * Compact the memory used by this string. + * + * @param self the string to work on + */ +void cstring_compact(cstring *self); + /** * Add a char at the end of the given cstring. * @@ -121,11 +127,12 @@ int cstring_addf(cstring *self, const char source[], size_t idx); /** * Add a string (a sequence of char that MAY end with '\0') at the end of the - * given cstring, up to N chars long. + * given string, up to N chars long. * * @param self the string to work on * @param source the string to add - * @param n the maximum number of chars to add (excluding the NUL byte) + * @param n the maximum number of chars to add (excluding the NUL byte), or 0 + * to add the whole source (which MUST then end with a '\0') * * @return TRUE if success (FALSE means it was unable to grow due to memory * pressure) @@ -139,7 +146,8 @@ int cstring_addn(cstring *self, const char source[], size_t n); * @param self the string to work on * @param source the string to add * @param idx the starting index at which to copy from the source - * @param n the maximum number of chars to add (excluding the NUL byte) + * @param n the maximum number of chars to add (excluding the NUL byte) or 0 + * to add the whole source (which MUST then end with a '\0') * * @return TRUE if success (FALSE means it was unable to grow due to memory * pressure) @@ -160,23 +168,26 @@ int cstring_addp(cstring *self, const char *fmt, ...); /** * Cut the string at the given size if it is greater. - * E.g.: it will have (at most) this many characters (without counting NUL) in it after. + * + * E.g.: it will have (at most) this many characters (without counting NULL) in + * it after. * * @param self the string to work on - * @param size the size to cut at (the maximum size of the cstring after this operation, NUL excepted) + * @param size the size to cut at (the maximum size of the cstring after this + * operation, NUL excepted) */ void cstring_cut_at(cstring *self, size_t size); /** - * Create a substring of this cstring. + * Create a substring of this one. * - * @param self the cstring to work on + * @param self the string to work on * @param start the index to start at * @param length the number of characters to copy, 0 for 'up to the end' * * @return a newly allocated cstring */ -cstring *cstring_substring(cstring *self, size_t start, size_t length); +cstring *cstring_substring(const char self[], size_t start, size_t length); /** * Split a cstring into "smaller" cstrings every time the given separator is found. @@ -212,67 +223,44 @@ cstring *cstring_substring(cstring *self, size_t start, size_t length); //TODO: use a [] //clist *cstring_splitc(cstring *self, char delim, char quote); /** - * Reverse the given cstring. + * Reverse the given string. * - * @param self the cstring to work on + * @param self the string to work on */ -void cstring_reverse(cstring *self); +void cstring_reverse(char *self); /** - * Replace all occurences of a string inside the given cstring by another. + * Replace all occurrences of a string inside the given cstring by another. * - * @param self the cstring to work on + * @param self the string to work on * @param from the string to replace * @param to the replacement string * - * @return the number of occurences changed + * @return the number of occurrences changed */ int cstring_replace(cstring *self, const char from[], const char to[]); /** - * Replace all occurences of a char inside the given cstring by another. + * Replace all occurrences of a char inside the given string by another. * - * @param self the cstring to work on + * @param self the string to work on * @param from the char to replace * @param to the replacement char * - * @return the number of occurences changed + * @return the number of occurrences changed */ -int cstring_replace_car(cstring *self, char from, char to); - -/** - * Check if the cstring starts with the given pattern. - * - * @param self the cstring to work on - * @param find the string to find - * @param start_index the index at which to start the comparison - * - * @return 1 if it does - */ -int cstring_starts_with(cstring *self, const char find[], size_t start_index); +int cstring_replace_car(char *self, char from, char to); /** * Check if the string starts with the given pattern. * * @param self the string to work on * @param find the string to find - * @param start_index the index at which to start the comparison + * @param start_idx the index at which to start the comparison * * @return 1 if it does */ -int cstring_sstarts_with(const char string[], const char find[], - size_t start_index); - -/** - * Check if the cstring ends with the given pattern. - * - * @param self the cstring to work on - * @param find the string to find (if empty, will always be found) - * @param start_index the index at which to start the comparison - * - * @return 1 if it does - */ -int cstring_ends_with(cstring *self, const char find[]); +int cstring_starts_with(const char self[], const char find[], size_t start_idx); /** * Check if the string ends with the given pattern. @@ -283,12 +271,12 @@ int cstring_ends_with(cstring *self, const char find[]); * * @return 1 if it does */ -int cstring_sends_with(const char self[], const char find[]); +int cstring_ends_with(const char self[], const char find[]); /** * Find the given substring in this one. * - * @param self the cstring to work on + * @param self the string to work on * @param find the string to find * @param start_index the index at which to start the search * @@ -300,7 +288,7 @@ long cstring_find(const char self[], const char find[], size_t rstart_index); /** * Find the given substring in this one, but search in the reverse direction. * - * @param self the cstring to work on + * @param self the string to work on * @param find the string to find * @param rstart_index the index at which to start the search, or 0 for * "end of string" (remember that it is reverse, you would then never @@ -311,35 +299,12 @@ long cstring_find(const char self[], const char find[], size_t rstart_index); * @return the start index of the found string if found, or a negative value * if not */ -long cstring_rfind(char self[], const char find[], size_t rstart_index); +long cstring_rfind(char self[], const char find[], long rstart_index); /** - * Check if the given string is contained by this one. + * Clear (truncate its size to 0) the given string. * * @param self the string to work on - * @param find the string to find - * @param start_index the index at which to start the comparison - * - * @return the start index of the found string if found, or a negative value if not - */ -long long cstring_sfind(const char self[], const char find[], - size_t start_index); - -/** - * Check if any of the given characters (in a char* which MUST end with '\0') is found. - * - * @param self the cstring to work on - * @param find the characters to find, which MUST be an array of char that ends with '\0' - * @param start_index the index at which to start the comparison - * - * @return the start index of the first found character if found, or a negative value if not - */ -long long cstring_find_any(cstring *self, const char find[], size_t start_index); - -/** - * Clear (truncate its size to 0) the given cstring. - * - * @param self the cstring to work on */ void cstring_clear(cstring *self); @@ -353,79 +318,12 @@ void cstring_clear(cstring *self); char *cstring_convert(cstring *self); /** - * Clone this cstring. - * NULL will return NULL. - * - * @param self the cstring to clone - */ -cstring *cstring_clone(cstring *self); - -/** - * Clone this string into a new cstring. - * NULL will return NULL. - * - * @param self the string to clone - */ -cstring *cstring_clones(const char self[]); - -/** - * Clone this cstring into a new string. - * NULL will return NULL. - * - * @param self the cstring to clone - */ -char *cstring_sclone(cstring *self); - -/** - * Clone this string into a new string. + * Clone this string. * NULL will return NULL. * * @param self the string to clone */ -char *cstring_sclones(const char self[]); - -/** - * Encode the string to BASE64. - * - * @param self the cstring to encode - */ -cstring *cstring_to_b64(cstring *self); - -/** - * Encode the string to BASE64. - * - * @param self the cstring to encode - */ -char *cstring_to_sb64(cstring *self); - -/** - * Encode the string to BASE64. - * - * @param self the string to encode - * @param size the size of the data (e.g., strlen(self)) - */ -char *cstring_to_sb64s(char *self, size_t size); - -/** - * Decode the string to BASE64. - * - * @param self the cstring to decode - */ -cstring *cstring_from_b64(cstring *self); - -/** - * Decode the string to BASE64. - * - * @param self the cstring to decode - */ -char *cstring_from_sb64(cstring *self); - -/** - * Decode the string to BASE64. - * - * @param self the string to decode - */ -char *cstring_from_sb64s(char *self); +cstring *cstring_clone(cstring *self); /** * Trim this cstring of all trailing 'car' instances. @@ -437,7 +335,6 @@ char *cstring_from_sb64s(char *self); */ void cstring_rtrim(cstring *self, char car); - /** * Trim this cstring of all 'car' instances from the start and/or the * end of the string. @@ -449,13 +346,6 @@ void cstring_rtrim(cstring *self, char car); */ void cstring_trim(cstring *self, char car); -/** - * Compact the memory used by this cstring. - * - * @param self the cstring to work on - */ -void cstring_compact(cstring *self); - /** * Change the case to upper-case (UTF-8 compatible, but the string MUST be * whole). diff --git a/src/utils/desktop.c b/src/utils/desktop.c index f1081ce..fbf0a31 100644 --- a/src/utils/desktop.c +++ b/src/utils/desktop.c @@ -54,7 +54,7 @@ desktop *new_desktop(const char filename[], int best_size) { me->id = 0; // Copy name - me->name = utils_strdup(filename); + me->name = strdup(filename); // Get extension an remove ".desktop" from name char *ext = rindex(me->name, '.'); @@ -65,7 +65,7 @@ desktop *new_desktop(const char filename[], int best_size) { me->name[idot] = '\0'; } if (ext) - ext = utils_strdup(ext); + ext = strdup(ext); // If PNG of the same name, use as default icon me->icon_file = desktop_find_icon(me->name, best_size); @@ -77,7 +77,7 @@ desktop *new_desktop(const char filename[], int best_size) { slash = rindex(me->name, '/'); } if (slash) { - char *copy = utils_strdup(slash + 1); + char *copy = strdup(slash + 1); free(me->name); me->name = copy; } @@ -142,14 +142,14 @@ desktop *new_desktop(const char filename[], int best_size) { n = strlen(startsWith); if (!strncmp(line, startsWith, n)) { free(me->name); - me->name = utils_strdup(line + n); + me->name = strdup(line + n); } startsWith = "Exec="; n = strlen(startsWith); if (!strncmp(line, startsWith, n)) { free(me->exec); - me->exec = utils_strdup(line + n); + me->exec = strdup(line + n); // TODO: %f %F %u %U %i %c %k: inject values instead char *cars = "ifFuUck"; for (char *ptr = index(me->exec, '%'); ptr; ptr = index(ptr, '%')) { @@ -165,7 +165,7 @@ desktop *new_desktop(const char filename[], int best_size) { n = strlen(startsWith); if (!strncmp(line, startsWith, n)) { free(me->icon); - me->icon = utils_strdup(line + n); + me->icon = strdup(line + n); } } @@ -354,17 +354,17 @@ char *desktop_find_icon(const char basename[], int icon_size) { if (!strncmp(line, startsWith, n)) { free(theme); if (line[n] == '"') { - theme = utils_strdup(line + n + 1); + theme = strdup(line + n + 1); theme[strlen(theme) - 1] = '\0'; } else { - theme = utils_strdup(line + n); + theme = strdup(line + n); } } } if (!theme || !theme[0]) { - theme = utils_strdup(""); - ltheme = utils_strdup(""); + theme = strdup(""); + ltheme = strdup(""); } else { tmp = theme; theme = desktop_concat("/usr/share/icons/", tmp, "/", NULL); @@ -380,7 +380,7 @@ char *desktop_find_icon(const char basename[], int icon_size) { return NULL; // exact match - tmp = utils_strdup(basename); + tmp = strdup(basename); if (desktop_test_file(tmp)) return tmp; free(tmp); diff --git a/src/utils/utils.c b/src/utils/utils.c index ab7ccb1..f9586f9 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -22,15 +22,23 @@ #include "utils.h" #include "cstring.h" -char *utils_strdup(const char *source) { +#ifndef strnlen +size_t strnlen(const char *s, size_t maxlen) { + size_t i; + for (i = 0; s[i]; i++) { + if (i >= maxlen) + return maxlen; + } + + return i; +} +#endif + +#ifndef strdup +char *strdup(const char *source) { size_t sz = strlen(source); char *new = malloc((sz + 1) * sizeof(char)); strcpy(new, source); return new; } - -cstring *utils_cstrdup(const cstring *source) { - cstring *clone = new_cstring(); - cstring_add(clone, source->string); - return clone; -} +#endif diff --git a/src/utils/utils.h b/src/utils/utils.h index d236393..667407c 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -22,7 +22,8 @@ * @author Niki * @date 2020 * - * @brief Include all the other .H as well as a C99-compatible utils_strdup function. + * @brief Include all the other .h as well as a C99-compatible strdup/strnlen + * functions. */ #ifndef UTILS_H #define UTILS_H @@ -37,25 +38,16 @@ extern "C" { #include "print.h" #include "timing.h" -/** - * A C99-compatible strdup function (i.e., a strdup for - * CentOS 6). - * - * @param source the source string to copy - * - * @return a new string (malloc'ed) which your are now responsible of - */ -char *utils_strdup(const char *source); +/* Helps with C99 compatibility for code that is not */ -/** - * A C99-compatible strdup function (i.e., a strdup for - * CentOS 6). - * - * @param source the source string to copy - * - * @return a new string (malloc'ed) which your are now responsible of - */ -cstring *utils_cstrdup(const cstring *source); +#ifndef strnlen +size_t strnlen(const char *s, size_t maxlen); +#endif +#ifndef strdup +char *strdup(const char *source); +#endif + +/* */ #endif // UTILS_H -- 2.27.0