utils changes + tests (not yet ok)
authorNiki Roo <niki@nikiroo.be>
Mon, 28 Feb 2022 20:30:23 +0000 (21:30 +0100)
committerNiki Roo <niki@nikiroo.be>
Mon, 28 Feb 2022 20:30:23 +0000 (21:30 +0100)
src/nsub/nsub.c
src/nsub/nsub_read_lrc.c
src/tests/launcher.h
src/tests/utils/cstring.c
src/utils/base64.c
src/utils/base64.h
src/utils/cstring.c
src/utils/cstring.h
src/utils/desktop.c
src/utils/utils.c
src/utils/utils.h

index 2d91c62d73ac01cfd864062b44955a9cd350658d..ce88cf5efc2abe2bdd38adda0a2973e09e64a1b0 100644 (file)
@@ -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);
 }
 
index c245d27208c56eb1a2e771b0331e262286c706de..24938f8214b0fb6dd44047d1f2a31d36ac1c72e9 100644 (file)
@@ -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 {
index 750a8422c64b66ec8db62f9fa7365f32580ba3b7..9a05a6bfdb628d3d3b27c8dac6a0342bfa5015a8 100644 (file)
@@ -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) \
index 2df7764f7b6f05bd1caf9a24fad4f749164a9b0d..1e899e62d1b75456c0f77a488903b1f392d075dc 100644 (file)
 
 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);
index cf6657c081fd1695ff22b5b5a8abbdfb29340da8..c05a284f96a772a1f71ac7f81296cd543fc58521 100644 (file)
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-#include <stdint.h>
+#include "base64.h"
+
+#include <bits/stdint-uintn.h>
+#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 
-#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;
 }
 
index 7bd9afe2d1021322fa01ff502fa1cc8732709cf7..84226ab35879addbf4b27333b1c01c8b6fcb3345 100644 (file)
@@ -25,33 +25,14 @@ extern "C" {
 #define BASE64_H
 
 #include <stdlib.h>
-#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
 
index c7f2548627345bca7f47e30f6e59406ac9a92e1a..56a79fe9845303186337c5145ce46caab36930b1 100644 (file)
  Description: cstring is a collection of helper functions to manipulate string of text
  */
 
+#include "cstring.h"
+
+#include <stdarg.h>
 #include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
-#include <math.h>
 #include <wchar.h>
 #include <wctype.h>
-#include <stddef.h>
-#include <stdarg.h>
-
-/* 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) {
index 1ceb888201562baa0a7b349bba457794ff8c6552..7a378f03640719757fa82300807e357cf151a079 100644 (file)
@@ -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).
index f1081ceb954d95db68044d31762869a2da3395fe..fbf0a3159d80961fdb0af005a63c336a36111914 100644 (file)
@@ -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);
index ab7ccb1faaf4054dc341ee7f29207627694324c6..f9586f9a9b702d114cbc64d090558faf2529590a 100644 (file)
 #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
index d23639352be24b05fb164a2e2bd07dc1aa270f78..667407c3dbeaa16042a8034d6b36c6ae37a286aa 100644 (file)
@@ -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 <tt>strdup</tt> function (i.e., a <tt>strdup</tt> 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 <tt>strdup</tt> function (i.e., a <tt>strdup</tt> 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