diff options
author | Joseph Hunkeler <jhunkeler@users.noreply.github.com> | 2020-03-28 15:24:17 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-28 15:24:17 -0400 |
commit | 81a87ac139e26b1746c0370a4453bf5938e8eba9 (patch) | |
tree | 32774a6d5601a06557a862a2e223b3f0be4b3438 | |
parent | 5048b9046afe0b48377a9862da9148165f7a0890 (diff) | |
parent | 04bfb70f4599c72f53406fd5fcfda570e30859fe (diff) | |
download | spmc-81a87ac139e26b1746c0370a4453bf5938e8eba9.tar.gz |
Merge pull request #7 from jhunkeler/strdup_array-test
strdup_array test
-rw-r--r-- | include/str.h | 1 | ||||
-rw-r--r-- | lib/str.c | 41 | ||||
-rw-r--r-- | lib/user_input.c | 73 | ||||
-rw-r--r-- | tests/framework.h | 1 | ||||
-rw-r--r-- | tests/test_str_strdup_array.c | 30 |
5 files changed, 92 insertions, 54 deletions
diff --git a/include/str.h b/include/str.h index 5e6d30d..468f674 100644 --- a/include/str.h +++ b/include/str.h @@ -33,5 +33,6 @@ int isempty(char *sptr); int isquoted(char *sptr); char *normalize_space(char *s); char **strdup_array(char **array); +int strcmp_array(const char **a, const char **b); #endif //SPM_STR_H @@ -776,3 +776,44 @@ char **strdup_array(char **array) { return result; } + +/** + * Compare two arrays of strings + * + * `a` and/or `b` may be `NULL`. You should test for `NULL` in advance if _your_ program considers this an error condition. + * + * @param a array of strings + * @param b array of strings + * @return 0 = identical + */ +int strcmp_array(const char **a, const char **b) { + size_t a_len = 0; + size_t b_len = 0; + + // This could lead to false-positives depending on what the caller plans to achieve + if (a == NULL && b == NULL) { + return 0; + } else if (a == NULL) { + return -1; + } else if (b == NULL) { + return 1; + } + + // Get length of arrays + for (a_len = 0; a[a_len] != NULL; a_len++); + for (b_len = 0; b[b_len] != NULL; b_len++); + + // Check lengths are equal + if (a_len < b_len) return (int)(b_len - a_len); + else if (a_len > b_len) return (int)(a_len - b_len); + + // Compare strings in the arrays returning the total difference in bytes + int result = 0; + for (size_t ai = 0, bi = 0 ;a[ai] != NULL || b[bi] != NULL; ai++, bi++) { + int status = 0; + if ((status = strcmp(a[ai], b[bi]) != 0)) { + result += status; + } + } + return result; +} diff --git a/lib/user_input.c b/lib/user_input.c index 3f358fa..416b59f 100644 --- a/lib/user_input.c +++ b/lib/user_input.c @@ -1,32 +1,6 @@ #include "spm.h" -/** - * Basic case-insensitive interactive choice function - * @param answer - * @param answer_default - * @return - */ -int spm_user_yesno(int answer, int empty_input_is_yes) { - int result = 0; - answer = tolower(answer); - - if (answer == 'y') { - result = 1; - } else if (answer == 'n') { - result = 0; - } else { - if (empty_input_is_yes) { - result = 1; - } else { - result = -1; - } - } - - return result; -} - int spm_prompt_user(const char *msg, int empty_input_is_yes) { - int user_choice = 0; int status_choice = 0; char ch_yes = 'y'; char ch_no = 'n'; @@ -38,38 +12,29 @@ int spm_prompt_user(const char *msg, int empty_input_is_yes) { } printf("\n%s [%c/%c] ", msg, ch_yes, ch_no); - while ((user_choice = getchar())) { - status_choice = spm_user_yesno(user_choice, 1); - if (status_choice == 0) { // No - break; - } else if (status_choice == 1) { // Yes - break; - } else { // Only triggers when spm_user_yesno's second argument is zero - puts("Please answer 'y' or 'n'..."); - } - } - puts(""); - - return status_choice; -} + char ch[2] = {0,}; + int input_count = 0; + while (scanf("%c", ch) == 1) { + ch[1] = '\0'; -void spm_user_yesno_test() { - int choice; - int status; - while ((choice = getchar())) { - status = spm_user_yesno(choice, 1); - if (status == -1) { - puts("Please answer Y or N"); + if (input_count != 0) { + input_count = 0; + ch[0] = '\0'; continue; } - else if (status == 0) { - puts("You answered no"); - break; - } - else if (status == 1) { - puts("You answered yes"); - break; + + if ((isempty(ch) && empty_input_is_yes != 0)) { + return 1; + } else if ((isempty(ch) && empty_input_is_yes == 0)) { + return 0; + } else if (tolower(ch[0]) == tolower(ch_yes)) { // Yes + return 1; + } else if (tolower(ch[0]) == tolower(ch_no)) { // No + return 0; + } else { + printf("Please answer '%c' or '%c'...\n", tolower(ch_yes), tolower(ch_no)); } + input_count++; } } diff --git a/tests/framework.h b/tests/framework.h index 1e5adaa..d317005 100644 --- a/tests/framework.h +++ b/tests/framework.h @@ -6,6 +6,7 @@ union TestValue { const char *sptr; char **slptr; + const char **cslptr; char character; unsigned int unsigned_integer; signed int signed_integer; diff --git a/tests/test_str_strdup_array.c b/tests/test_str_strdup_array.c new file mode 100644 index 0000000..5590a74 --- /dev/null +++ b/tests/test_str_strdup_array.c @@ -0,0 +1,30 @@ +#include "spm.h" +#include "framework.h" + +const char *testFmt = "case: (array){%s} expected (array){%s}, returned (array){%s} \n"; +struct TestCase testCase[] = { + {.caseValue.slptr = (char *[]){"a", "a", "c", "d", "e", NULL}, .truthValue.slptr = (char *[]){"a", "a", "c", "d", "e", NULL}}, + {.caseValue.slptr = (char *[]){"e", "d", "c", "b", "a", NULL}, .truthValue.slptr = (char *[]){"e", "d", "c", "b", "a", NULL}}, + {.caseValue.slptr = (char *[]){"ha", "haha", "hahaha", "hahahaha", "hahahahaha", NULL}, .truthValue.slptr = (char *[]){"ha", "haha", "hahaha", "hahahaha", "hahahahaha", NULL}}, + {.caseValue.slptr = NULL, .truthValue.sptr = NULL}, +}; +size_t numCases = sizeof(testCase) / sizeof(struct TestCase); + +int main(int argc, char *argv[]) { + for (size_t i = 0; i < numCases; i++) { + char **result = strdup_array(testCase[i].caseValue.slptr); + myassert(strcmp_array(result, testCase[i].truthValue.slptr) == 0, + testFmt, + array_to_string(testCase[i].caseValue.slptr, ", "), + array_to_string(testCase[i].truthValue.slptr, ", "), + array_to_string(result, ", ")); + + if (result != NULL) { + for (size_t r = 0; result[r] != NULL; r++) { + free(result[r]); + } + free(result); + } + } + return 0; +}
\ No newline at end of file |