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);
}
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);
}
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);
}
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 {
#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) \
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)
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"
"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
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
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++) {
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;
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);
* 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;
}
#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
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
//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
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';
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) {
}
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;
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[]) {
}
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) {
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) {
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';
}
}
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;
}
/*
}
*/
-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) {
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) {
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);
}
}
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';
size_t size = 0;
int full_line;
-// sanity check:
+ // sanity check:
if (!file)
return 0;
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) {
* 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;
};
/**
*/
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.
*
/**
* 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)
* @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)
/**
* 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.
//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.
*
* @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
*
/**
* 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
* @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);
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.
*/
void cstring_rtrim(cstring *self, char car);
-
/**
* Trim this cstring of all 'car' instances from the start and/or the
* end of the string.
*/
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).
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, '.');
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);
slash = rindex(me->name, '/');
}
if (slash) {
- char *copy = utils_strdup(slash + 1);
+ char *copy = strdup(slash + 1);
free(me->name);
me->name = copy;
}
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, '%')) {
n = strlen(startsWith);
if (!strncmp(line, startsWith, n)) {
free(me->icon);
- me->icon = utils_strdup(line + n);
+ me->icon = strdup(line + n);
}
}
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);
return NULL;
// exact match
- tmp = utils_strdup(basename);
+ tmp = strdup(basename);
if (desktop_test_file(tmp))
return tmp;
free(tmp);
#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
* @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
#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