Skip to content

Commit

Permalink
String: Usar delimitadores de más de un caracter en split (#142)
Browse files Browse the repository at this point in the history
* string: split with long delimitator

* string: split with empty string as separator

* string: split with null separator

* string: string array usage in string split

* string: split empty text and separator

* string: split code style
  • Loading branch information
RaniAgus authored Aug 21, 2021
1 parent 6ddfcdb commit 87a500e
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 28 deletions.
43 changes: 21 additions & 22 deletions src/commons/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static void _string_do(char *text, void (*closure)(char*));
static void _string_lower_element(char* ch);
static void _string_upper_element(char* ch);
void _string_append_with_format_list(const char* format, char** original, va_list arguments);
char** _string_split(char* text, char* separator, bool(*condition)(char*, int));
char** _string_split(char* text, char* separator, bool(*is_last_token)(int));
static void _string_array_push(char*** array, char* text, int size);
static char* _string_array_replace(char** array, int pos, char* text);

Expand Down Expand Up @@ -145,15 +145,15 @@ bool string_equals_ignore_case(char *actual, char *expected) {
}

char **string_split(char *text, char *separator) {
bool _is_last_token(char* next, int _) {
return next != NULL;
bool _is_last_token(int _) {
return false;
}
return _string_split(text, separator, _is_last_token);
}

char** string_n_split(char *text, int n, char* separator) {
bool _is_last_token(char* next, int index) {
return next != NULL && index < (n - 1);
bool _is_last_token(int index) {
return index == (n - 1);
}
return _string_split(text, separator, _is_last_token);
}
Expand Down Expand Up @@ -286,27 +286,26 @@ void _string_append_with_format_list(const char* format, char** original, va_lis
free(temporal);
}

char** _string_split(char* text, char* separator, bool(*condition)(char*, int)) {
char** _string_split(char* text, char* separator, bool(*is_last_token)(int)) {
char **substrings = string_array_new();
int size = 0;

char *text_to_iterate = string_duplicate(text);
char *next = text_to_iterate;

while(condition(next, size)) {
char* token = strsep(&next, separator);
if(token == NULL) {
break;
int index = 0;

char *end, *start = text;
if (separator != NULL) {
while ((end = strstr(start, separator)) != NULL && !is_last_token(index)) {
if (string_is_empty(separator)) {
if (string_length(start) > 1)
end = start + 1;
else
break;
}
_string_array_push(&substrings, string_substring_until(start, end - start), index++);
start = end + string_length(separator);
}
_string_array_push(&substrings, string_duplicate(token), size);
size++;
};

if (next != NULL) {
_string_array_push(&substrings, string_duplicate(next), size);
}

free(text_to_iterate);
_string_array_push(&substrings, string_duplicate(start), index);

return substrings;
}

Expand Down
52 changes: 46 additions & 6 deletions tests/unit-tests/test_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ context (test_string) {

describe("Split") {

it("split_with_delimitators") {
char *line = "path/to/file";
char** substrings = string_split(line, "/");
it("split_with_separators") {
char *line = "path//to//file";
char** substrings = string_split(line, "//");

should_ptr(substrings) not be null;
should_string(substrings[0]) be equal to ("path");
Expand All @@ -195,7 +195,35 @@ context (test_string) {
string_array_destroy(substrings);
} end

it("split_starting_with_delimitator") {
it("split_with_empty_string_as_separator") {
char *line = "hello";
char** substrings = string_split(line, "");

should_ptr(substrings) not be null;
should_string(substrings[0]) be equal to ("h");
should_string(substrings[1]) be equal to ("e");
should_string(substrings[2]) be equal to ("l");
should_string(substrings[3]) be equal to ("l");
should_string(substrings[4]) be equal to ("o");
should_ptr(substrings[5]) be null;

string_iterate_lines(substrings, (void*) free);
free(substrings);
} end

it("split_with_null_separator") {
char *line = "path/to/file";
char** substrings = string_split(line, NULL);

should_ptr(substrings) not be null;
should_string(substrings[0]) be equal to ("path/to/file");
should_ptr(substrings[1]) be null;

string_iterate_lines(substrings, (void*) free);
free(substrings);
} end

it("split_starting_with_separator") {
char* line = "/path/to/file";
char** substrings = string_split(line, "/");

Expand All @@ -209,7 +237,7 @@ context (test_string) {
string_array_destroy(substrings);
} end

it("split_ending_with_delimitator") {
it("split_ending_with_separator") {
char* line = "path/to/file/";
char** substrings = string_split(line, "/");

Expand All @@ -223,7 +251,7 @@ context (test_string) {
string_array_destroy(substrings);
} end

it("split_having_delimitators_in_between") {
it("split_having_separators_in_between") {
char* line = "path/to//file";
char** substrings = string_split(line, "/");

Expand All @@ -249,6 +277,18 @@ context (test_string) {

} end

it("split_is_empty_with_empty_separator") {
char* line = "";
char** substrings = string_split(line, "");

should_ptr(substrings) not be null;
should_string(substrings[0]) be equal to("");
should_ptr(substrings[1]) be null;

string_array_destroy(substrings);

} end

it("n_split_when_n_is_less_than_splitted_elements") {
char *line = "Hola planeta tierra";
char** substrings = string_n_split(line, 2, " ");
Expand Down

0 comments on commit 87a500e

Please sign in to comment.