Skip to content

Commit

Permalink
Strings: operaciones para string arrays (#133)
Browse files Browse the repository at this point in the history
* string: added string array tad

* string: added string array destroy
RaniAgus authored Aug 18, 2021
1 parent a741a66 commit 6ddfcdb
Showing 5 changed files with 207 additions and 44 deletions.
3 changes: 1 addition & 2 deletions src/commons/config.c
Original file line number Diff line number Diff line change
@@ -59,9 +59,8 @@ t_config *config_create(char *path) {
}
}
string_iterate_lines(lines, add_cofiguration);
string_iterate_lines(lines, (void*) free);

free(lines);
string_array_destroy(lines);
free(buffer);
fclose(file);

67 changes: 56 additions & 11 deletions src/commons/string.c
Original file line number Diff line number Diff line change
@@ -27,7 +27,8 @@ 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));

static void _string_array_push(char*** array, char* text, int size);
static char* _string_array_replace(char** array, int pos, char* text);

char *string_repeat(char character, int count) {
char *text = calloc(count + 1, 1);
@@ -214,6 +215,44 @@ bool string_contains(char* text, char *substring) {
return strstr(text, substring) != NULL;
}

char** string_array_new() {
char** array = malloc(sizeof(char*));
array[0] = NULL;

return array;
}

void string_array_destroy(char** array) {
string_iterate_lines(array, (void*) free);
free(array);
}

int string_array_size(char** array) {
int size = 0;
void _count_lines(char* _) {
size++;
}
string_iterate_lines(array, _count_lines);

return size;
}

bool string_array_is_empty(char** array) {
return array[0] == NULL;
}

void string_array_push(char*** array, char* text) {
_string_array_push(array, text, string_array_size(*array));
}

char* string_array_replace(char** array, int pos, char* text) {
return string_array_size(array) > pos && pos >= 0 ? _string_array_replace(array, pos, text) : NULL;
}

char* string_array_pop(char** array) {
return string_array_size(array) > 0 ? _string_array_replace(array, string_array_size(array) - 1, NULL) : NULL;
}

/** PRIVATE FUNCTIONS **/

static void _string_upper_element(char* ch) {
@@ -248,7 +287,7 @@ void _string_append_with_format_list(const char* format, char** original, va_lis
}

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

char *text_to_iterate = string_duplicate(text);
@@ -259,21 +298,27 @@ char** _string_split(char* text, char* separator, bool(*condition)(char*, int))
if(token == NULL) {
break;
}
_string_array_push(&substrings, string_duplicate(token), size);
size++;
substrings = realloc(substrings, sizeof(char*) * size);
substrings[size - 1] = string_duplicate(token);
};

if (next != NULL) {
size++;
substrings = realloc(substrings, sizeof(char*) * size);
substrings[size - 1] = string_duplicate(next);
_string_array_push(&substrings, string_duplicate(next), size);
}

size++;
substrings = realloc(substrings, sizeof(char*) * size);
substrings[size - 1] = NULL;

free(text_to_iterate);
return substrings;
}

static void _string_array_push(char*** array, char* text, int size) {
*array = realloc(*array, sizeof(char*) * (size + 2));
(*array)[size] = text;
(*array)[size + 1] = NULL;
}

static char* _string_array_replace(char** array, int pos, char* text) {
char* old_text = array[pos];
array[pos] = text;

return old_text;
}
44 changes: 44 additions & 0 deletions src/commons/string.h
Original file line number Diff line number Diff line change
@@ -249,4 +249,48 @@
*/
bool string_contains(char* text, char *substring);

/**
* @NAME: string_array_new
* @DESC: Crea un array de strings vacio
*/
char** string_array_new();

/**
* @NAME: string_array_destroy
* @DESC: Destruye un array con sus strings
*/
void string_array_destroy(char** array);

/**
* @NAME: string_array_size
* @DESC: Retorna la cantidad de líneas del
* array de strings
*/
int string_array_size(char** array);

/**
* @NAME: string_array_is_empty
* @DESC: Verifica si el array de strings está vacío
*/
bool string_array_is_empty(char** array);

/**
* @NAME: string_array_push
* @DESC: Agrega un string al final del array
*/
void string_array_push(char*** array, char* text);

/**
* @NAME: string_array_replace
* @DESC: Reemplaza un string en un array por otro, retornando
* el anterior
*/
char* string_array_replace(char** array, int pos, char* text);

/**
* @NAME: string_array_pop
* @DESC: Quita el último string del array y lo retorna
*/
char* string_array_pop(char** array);

#endif /* STRING_UTILS_H_ */
9 changes: 3 additions & 6 deletions tests/unit-tests/test_config.c
Original file line number Diff line number Diff line change
@@ -92,8 +92,7 @@ context (test_config) {
char* empty_array_expected[] = {NULL};
_assert_equals_array(empty_array_expected, empty_array, 0);

string_iterate_lines(empty_array, (void*) free);
free(empty_array);
string_array_destroy(empty_array);
} end

it ("should get an array with values") {
@@ -103,8 +102,7 @@ context (test_config) {
char** numbers = config_get_array_value(config, "NUMBERS");
_assert_equals_array(numbers_expected, numbers, 5);

string_iterate_lines(numbers, (void*) free);
free(numbers);
string_array_destroy(numbers);
} end

it ("should get an array with values without spaces between entries") {
@@ -114,8 +112,7 @@ context (test_config) {
char** strings = config_get_array_value(config, "NO_SPACES");
_assert_equals_array(strings_expected, strings, 5);

string_iterate_lines(strings, (void*) free);
free(strings);
string_array_destroy(strings);
} end

} end
128 changes: 103 additions & 25 deletions tests/unit-tests/test_string.c
Original file line number Diff line number Diff line change
@@ -192,8 +192,7 @@ context (test_string) {
should_string(substrings[2]) be equal to ("file");
should_ptr(substrings[3]) be null;

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

it("split_starting_with_delimitator") {
@@ -207,8 +206,7 @@ context (test_string) {
should_string(substrings[3]) be equal to ("file");
should_ptr(substrings[4]) be null;

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

it("split_ending_with_delimitator") {
@@ -222,8 +220,7 @@ context (test_string) {
should_string(substrings[3]) be equal to ("");
should_ptr(substrings[4]) be null;

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

it("split_having_delimitators_in_between") {
@@ -237,8 +234,7 @@ context (test_string) {
should_string(substrings[3]) be equal to ("file");
should_ptr(substrings[4]) be null;

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

it("split_is_empty") {
@@ -249,8 +245,7 @@ context (test_string) {
should_string(substrings[0]) be equal to("");
should_ptr(substrings[1]) be null;

string_iterate_lines(substrings, (void*) free);
free(substrings);
string_array_destroy(substrings);

} end

@@ -263,8 +258,7 @@ context (test_string) {
should_string(substrings[1]) be equal to("planeta tierra");
should_ptr(substrings[2]) be null;

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

it("n_split_when_n_is_equals_than_splitted_elements") {
@@ -277,8 +271,7 @@ context (test_string) {
should_string(substrings[2]) be equal to("tierra");
should_ptr(substrings[3]) be null;

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

it("n_split_when_separator_isnt_included") {
@@ -289,8 +282,7 @@ context (test_string) {
should_string(substrings[0]) be equal to(line);
should_ptr(substrings[1]) be null;

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

it("n_split_when_n_is_greather_than_splitted_elements") {
@@ -303,8 +295,7 @@ context (test_string) {
should_string(substrings[2]) be equal to("tierra");
should_ptr(substrings[3]) be null;

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

it("n_split_is_empty") {
@@ -314,8 +305,7 @@ context (test_string) {
should_ptr(substrings) not be null;
should_string(substrings[0]) be equal to("");

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

} end
@@ -428,8 +418,7 @@ context (test_string) {
should_ptr(empty_array) not be null;
should_ptr(empty_array[0]) be null;

string_iterate_lines(empty_array, (void*) free);
free(empty_array);
string_array_destroy(empty_array);
} end

it("get_string_full_array") {
@@ -445,8 +434,7 @@ context (test_string) {
free(value);
}

string_iterate_lines(numbers_array, (void*) free);
free(numbers_array);
string_array_destroy(numbers_array);

} end

@@ -489,6 +477,96 @@ context (test_string) {
should_bool(string_contains("", "")) be truthy;
} end

} end
describe ("String array") {
char** names;

before {
names = string_array_new();

string_array_push(&names, "Gaston");
string_array_push(&names, "Matias");
string_array_push(&names, "Sebastian");
string_array_push(&names, "Daniela");
} end

after {
free(names);
} end

it ("add an element at the end") {
string_array_push(&names, "Agustin");

should_int(string_array_size(names)) be equal to (5);
should_ptr(names[5]) be null;

char* expected[] = {"Gaston", "Matias", "Sebastian", "Daniela", "Agustin"};
int i = 0;
void _assert_names(char* name) {
should_ptr(name) not be null;
should_string(name) be equal to (expected[i]);
i++;
}
string_iterate_lines(names, _assert_names);
} end

it("remove the last element") {
char* name = string_array_pop(names);

should_string(name) be equal to ("Daniela");

should_int(string_array_size(names)) be equal to (3);
should_ptr(names[3]) be null;

char* expected[] = {"Gaston", "Matias", "Sebastian"};
int i = 0;
void _assert_names(char* name) {
should_ptr(name) not be null;
should_string(name) be equal to (expected[i]);
i++;
}
string_iterate_lines(names, _assert_names);
} end

it ("not to remove elements in an empty array") {
for(int i = 0; i < 10; i++) {
string_array_pop(names);
}

should_int(string_array_size(names)) be equal to (0);
should_bool(string_array_is_empty(names)) be truthy;
} end

it("replace an element") {
char* name = string_array_replace(names, 2, "Damian");

should_string(name) be equal to ("Sebastian");

char* expected[] = {"Gaston", "Matias", "Damian", "Daniela"};
int i = 0;
void _assert_names(char* name) {
should_ptr(name) not be null;
should_string(name) be equal to (expected[i]);
i++;
}
string_iterate_lines(names, _assert_names);
} end

it("not to replace an element outside the array") {
char* name = string_array_replace(names, 4, "Damian");

should_ptr(name) be null;
should_int(string_array_size(names)) be equal to (4);
should_ptr(names[4]) be null;

char* expected[] = {"Gaston", "Matias", "Sebastian", "Daniela"};
int i = 0;
void _assert_names(char* name) {
should_ptr(name) not be null;
should_string(name) be equal to (expected[i]);
i++;
}
string_iterate_lines(names, _assert_names);
} end
} end
} end
}

0 comments on commit 6ddfcdb

Please sign in to comment.