int test_clear(void) { bool good = true; int i = 10; char *s = "abfda"; sh_list_clear(&il); sh_list_clear(&sl); if (il.size != 0 || sl.size != 0) goto exit_test_fail; good = good && sh_list_append(&il, &i) == 0; good = good && sh_list_append(&sl, s) == 0; if (!good) goto exit_test_fail; sh_list_clear(&il); sh_list_clear(&sl); good = good && sh_list_init(&il, _intptrcpy, sizeof(int *)) == 0; good = good && sh_list_init(&sl, _charptrcpy, sizeof(char *)) == 0; if (!good) goto exit_not_reinitializable; return 0; exit_test_fail: fprintf(stderr, "clear: clear did not return object to a usable state\n"); goto exit_fail; exit_not_reinitializable: fprintf(stderr, "clear: clear did not return object to a reinitializable state\n"); exit_fail: dump_data(DUMP_FILE); return -1; }
int test_duplicate(void) { bool good = true; shList il1, sl1, il2, sl2; /* test empty copy */ sh_list_init(&il1, _intptrcpy, sizeof(int *)); sh_list_init(&sl1, _charptrcpy, sizeof(char *)); good = good && sh_list_duplicate(&il1, &il2) == 0; good = good && sh_list_duplicate(&sl1, &sl2) == 0; if (!good) goto exit_bad_empty_duplicate; good = good && test_idata(&il2, NULL, 0) == 0; good = good && test_sdata(&sl2, NULL, 0) == 0; if (!good) goto exit_test_empty; sh_list_clear(&il2); sh_list_clear(&sl2); /* test full copy */ good = good && sh_list_duplicate(&il, &il2) == 0; good = good && sh_list_duplicate(&sl, &sl2) == 0; if (!good) goto exit_bad_full_duplicate; good = good && test_idata(&il2, idata, idata_count) == 0; good = good && test_sdata(&sl2, sdata, sdata_count) == 0; if (!good) goto exit_test_full; goto exit_cleanup; exit_bad_empty_duplicate: fprintf(stderr, "duplicate: bad duplication of empty list\n"); goto exit_fail; exit_test_empty: fprintf(stderr, "duplicate: duplicated empty array data mismatch\n"); goto exit_fail; exit_bad_full_duplicate: fprintf(stderr, "duplicate: bad duplication of non-empty list\n"); goto exit_fail; exit_test_full: fprintf(stderr, "duplicate: duplicated full array data mismatch\n"); goto exit_fail; exit_fail: dump_data(DUMP_FILE); exit_cleanup: sh_list_free(&il1); sh_list_free(&sl1); sh_list_free(&il2); sh_list_free(&sl2); return good?0:-1; }
/* initialize structure */ int test_init(void) { bool good = true; shNode c; sh_list_free(&il); sh_list_free(&sl); good = good && sh_list_init(&il, _intptrcpy, sizeof(int *)) == 0; good = good && sh_list_init(&sl, _charptrcpy, sizeof(char *)) == 0; /* it's ok to reinitialize with these attributes */ good = good && sh_list_init(&il, _intptrcpy, sizeof(int *)) == 0; good = good && sh_list_init(&sl, _charptrcpy, sizeof(char *)) == 0; good = good && sh_list_init(&il, _intptrcpy, sizeof(int *)) == 0; good = good && sh_list_init(&sl, _charptrcpy, sizeof(char *)) == 0; good = good && sh_list_init(&il, _intptrcpy, sizeof(int *), ipcmp) == 0; good = good && sh_list_init(&sl, _charptrcpy, sizeof(char *), scmp) == 0; if (!sh_list_get_first(&il, &c) || !sh_list_get_last(&il, &c)) goto exit_not_empty; if (!sh_list_get_first(&sl, &c) || !sh_list_get_last(&sl, &c)) goto exit_not_empty; if (!good) goto exit_fail; return 0; exit_not_empty: fprintf(stderr, "init: initialized list is not empty"); exit_fail: dump_data(DUMP_FILE); return -1; }
int test_compare(void) { shList il1; shList sl1; bool good = true; sh_list_init(&il1, _intptrcpy, sizeof(int *), ipcmp); sh_list_init(&sl1, _charptrcpy, sizeof(char *), scmp); if (sh_list_compare(&il, &il) != 0 || sh_list_compare(&sl, &sl) != 0 || sh_list_compare_lexic(&il, &il) != 0 || sh_list_compare_lexic(&sl, &sl) != 0) goto exit_bad_equal; duplicate_list(&il1, &il, &sl1, &sl); if (sh_list_append(&il1, &idata[0]) || sh_list_append(&sl1, sdata[0])) goto exit_no_mem; if (sh_list_compare(&il, &il1) == 0 || sh_list_compare(&sl, &sl1) == 0) goto exit_bad_inequal; if (sh_list_compare_lexic(&il, &il1) != -1 || sh_list_compare_lexic(&il1, &il) != 1 || sh_list_compare_lexic(&sl, &sl1) != -1 || sh_list_compare_lexic(&sl1, &sl) != 1) goto exit_bad_lexic; goto exit_cleanup; exit_no_mem: fprintf(stderr, "compare: out of memory\n"); goto exit_fail; exit_bad_equal: fprintf(stderr, "compare: failed to recognize equal lists\n"); goto exit_fail; exit_bad_inequal: fprintf(stderr, "compare: failed to recognize inequal lists\n"); goto exit_fail; exit_bad_lexic: fprintf(stderr, "compare: incorrect lexicographical comparison\n"); goto exit_fail; exit_fail: dump_data(DUMP_FILE); good = false; exit_cleanup: sh_list_free(&il1); sh_list_free(&sl1); return good?0:-1; }
int test_concat(void) { shList il1, il2, il3, il4; shList sl1, sl2, sl3, sl4; shList itemp, stemp; int ret; size_t i; int *ext_idata = NULL; size_t ext_idata_count; char **ext_sdata = NULL; size_t ext_sdata_count; bool good = true; sh_list_init(&il1, _intptrcpy, sizeof(int *)); sh_list_init(&il2, _intptrcpy, sizeof(int *)); sh_list_init(&il3, _intptrcpy, sizeof(int *)); sh_list_init(&il4, _intptrcpy, sizeof(int *)); sh_list_init(&sl1, _charptrcpy, sizeof(char *)); sh_list_init(&sl2, _charptrcpy, sizeof(char *)); sh_list_init(&sl3, _charptrcpy, sizeof(char *)); sh_list_init(&sl4, _charptrcpy, sizeof(char *)); sh_list_init(&itemp, _intptrcpy, sizeof(int *)); sh_list_init(&stemp, _charptrcpy, sizeof(char *)); /* {} + {} */ ret = concat_and_test(&il1, &il2, &sl1, &sl2, NULL, 0, NULL, 0); if (ret == -1) goto exit_test_fail_both_empty; /* l + {} */ ret = concat_and_test(&il, &il1, &sl, &sl1, idata, idata_count, sdata, sdata_count); if (ret == -1) goto exit_test_fail_empty_right; /* {} + l */ ret = concat_and_test(&il2, &il, &sl2, &sl, idata, idata_count, sdata, sdata_count); if (ret == -1) goto exit_test_fail_empty_left; sh_list_concat(&il, &il2); sh_list_concat(&sl, &sl2); /* l + l/2 */ ext_idata_count = idata_count / 2; ext_sdata_count = sdata_count / 2; ext_idata = malloc((idata_count + ext_idata_count) * sizeof *ext_idata); ext_sdata = malloc((sdata_count + ext_sdata_count) * sizeof *ext_sdata); if (ext_idata == NULL || ext_sdata == NULL) goto exit_no_mem; memcpy(ext_idata, idata, idata_count * sizeof *idata); memcpy(ext_sdata, sdata, sdata_count * sizeof *sdata); for (i = 0; i < ext_idata_count; ++i) { ext_idata[i + idata_count] = idata[i]; sh_list_append(&il3, &idata[i]); } for (i = 0; i < ext_sdata_count; ++i) { ext_sdata[i + sdata_count] = sdata[i]; sh_list_append(&sl3, sdata[i]); } duplicate_list(&itemp, &il, &stemp, &sl); ret = concat_and_test(&itemp, &il3, &stemp, &sl3, ext_idata, idata_count + ext_idata_count, ext_sdata, sdata_count + ext_sdata_count); if (ret == -1) goto exit_test_fail_smaller_right; /* l/2 + l */ memcpy(ext_idata + ext_idata_count, idata, idata_count * sizeof *idata); memcpy(ext_sdata + ext_sdata_count, sdata, sdata_count * sizeof *sdata); for (i = 0; i < ext_idata_count; ++i) { ext_idata[i] = idata[i]; sh_list_append(&il4, &idata[i]); } for (i = 0; i < ext_sdata_count; ++i) { ext_sdata[i] = sdata[i]; sh_list_append(&sl4, sdata[i]); } duplicate_list(&itemp, &il, &stemp, &sl); ret = concat_and_test(&il4, &itemp, &sl4, &stemp, ext_idata, idata_count + ext_idata_count, ext_sdata, sdata_count + ext_sdata_count); if (ret == -1) goto exit_test_fail_smaller_left; /* l/2 + l/2 */ memcpy(ext_idata + ext_idata_count, ext_idata, ext_idata_count * sizeof *ext_idata); memcpy(ext_sdata + ext_sdata_count, ext_sdata, ext_sdata_count * sizeof *ext_sdata); for (i = 0; i < ext_idata_count; ++i) sh_list_append(&il3, &idata[i]); for (i = 0; i < ext_sdata_count; ++i) sh_list_append(&sl3, sdata[i]); duplicate_list(&itemp, &il3, &stemp, &sl3); ret = concat_and_test(&il3, &itemp, &sl3, &stemp, ext_idata, ext_idata_count * 2, ext_sdata, ext_sdata_count * 2); if (ret == -1) goto exit_test_fail_equal_size; if (!sh_list_concat(&il3, &il3) || !sh_list_concat(&sl3, &sl3)) goto exit_accepted_duplicate; good = true; goto exit_cleanup; exit_no_mem: fprintf(stderr, "concat: out of memory\n"); goto exit_fail; exit_test_fail_empty_right: fprintf(stderr, "concat: bad concatenation with empty list on the right\n"); goto exit_fail; exit_test_fail_empty_left: fprintf(stderr, "concat: bad concatenation with empty list on the left\n"); goto exit_fail; exit_test_fail_smaller_right: fprintf(stderr, "concat: bad concatenation with smaller list on the right\n"); goto exit_fail; exit_test_fail_smaller_left: fprintf(stderr, "concat: bad concatenation with smaller list on the left\n"); goto exit_fail; exit_test_fail_both_empty: fprintf(stderr, "concat: bad concatenation with two empty lists\n"); goto exit_fail; exit_test_fail_equal_size: fprintf(stderr, "concat: bad concatenation with lists of same size\n"); goto exit_fail; exit_accepted_duplicate: fprintf(stderr, "concat: accepted concatenation with itself (causes loop)\n"); exit_fail: dump_data(DUMP_FILE); good = false; exit_cleanup: sh_list_free(&il1); sh_list_free(&il2); sh_list_free(&il3); sh_list_free(&il4); sh_list_free(&sl1); sh_list_free(&sl2); sh_list_free(&sl3); sh_list_free(&sl4); sh_list_free(&itemp); sh_list_free(&stemp); free(ext_idata); free(ext_sdata); return good?0:-1; }
void sh_stack_init(sh_stack_t *s) { sh_list_init(&(s->_list)); }