| /*- |
| * Copyright (c) 2011 Tim Kientzle |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, |
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| #include "test.h" |
| __FBSDID("$FreeBSD$"); |
| |
| #define __LIBARCHIVE_TEST |
| #include "archive_string.h" |
| |
| #define EXTENT 32 |
| |
| #define assertStringSizes(strlen, buflen, as) \ |
| assertEqualInt(strlen, (as).length); \ |
| assertEqualInt(buflen, (as).buffer_length); |
| |
| #define assertExactString(strlen, buflen, data, as) \ |
| do { \ |
| assertStringSizes(strlen, buflen, as); \ |
| assertEqualString(data, (as).s); \ |
| } while (0) |
| |
| #define assertNonNULLString(strlen, buflen, as) \ |
| do { \ |
| assertStringSizes(strlen, buflen, as); \ |
| assert(NULL != (as).s); \ |
| } while (0) |
| |
| static void |
| test_archive_string_ensure(void) |
| { |
| struct archive_string s; |
| |
| archive_string_init(&s); |
| assertExactString(0, 0, NULL, s); |
| |
| /* single-extent allocation */ |
| assert(&s == archive_string_ensure(&s, 5)); |
| assertNonNULLString(0, EXTENT, s); |
| |
| /* what happens around extent boundaries? */ |
| assert(&s == archive_string_ensure(&s, EXTENT - 1)); |
| assertNonNULLString(0, EXTENT, s); |
| |
| assert(&s == archive_string_ensure(&s, EXTENT)); |
| assertNonNULLString(0, EXTENT, s); |
| |
| assert(&s == archive_string_ensure(&s, EXTENT + 1)); |
| assertNonNULLString(0, 2 * EXTENT, s); |
| |
| archive_string_free(&s); |
| } |
| |
| static void |
| test_archive_strcat(void) |
| { |
| struct archive_string s; |
| |
| archive_string_init(&s); |
| assertExactString(0, 0, NULL, s); |
| |
| /* null target, empty source */ |
| assert(&s == archive_strcat(&s, "")); |
| assertExactString(0, EXTENT, "", s); |
| |
| /* empty target, empty source */ |
| assert(&s == archive_strcat(&s, "")); |
| assertExactString(0, EXTENT, "", s); |
| |
| /* empty target, non-empty source */ |
| assert(&s == archive_strcat(&s, "fubar")); |
| assertExactString(5, EXTENT, "fubar", s); |
| |
| /* non-empty target, non-empty source */ |
| assert(&s == archive_strcat(&s, "baz")); |
| assertExactString(8, EXTENT, "fubarbaz", s); |
| |
| archive_string_free(&s); |
| } |
| |
| static void |
| test_archive_strappend_char(void) |
| { |
| struct archive_string s; |
| |
| archive_string_init(&s); |
| assertExactString(0, 0, NULL, s); |
| |
| /* null target */ |
| archive_strappend_char(&s, 'X'); |
| assertExactString(1, EXTENT, "X", s); |
| |
| /* non-empty target */ |
| archive_strappend_char(&s, 'Y'); |
| assertExactString(2, EXTENT, "XY", s); |
| |
| archive_string_free(&s); |
| } |
| |
| /* archive_strnXXX() tests focus on length handling. |
| * other behaviors are tested by proxy through archive_strXXX() |
| */ |
| |
| static void |
| test_archive_strncat(void) |
| { |
| struct archive_string s; |
| |
| archive_string_init(&s); |
| assertExactString(0, 0, NULL, s); |
| |
| /* perfect length */ |
| assert(&s == archive_strncat(&s, "snafu", 5)); |
| assertExactString(5, EXTENT, "snafu", s); |
| |
| /* short read */ |
| assert(&s == archive_strncat(&s, "barbazqux", 3)); |
| assertExactString(8, EXTENT, "snafubar", s); |
| |
| /* long read is ok too! */ |
| assert(&s == archive_strncat(&s, "snafu", 8)); |
| assertExactString(13, EXTENT, "snafubarsnafu", s); |
| |
| archive_string_free(&s); |
| } |
| |
| static void |
| test_archive_strncpy(void) |
| { |
| struct archive_string s; |
| |
| archive_string_init(&s); |
| assertExactString(0, 0, NULL, s); |
| |
| /* perfect length */ |
| assert(&s == archive_strncpy(&s, "fubar", 5)); |
| assertExactString(5, EXTENT, "fubar", s); |
| |
| /* short read */ |
| assert(&s == archive_strncpy(&s, "snafubar", 5)); |
| assertExactString(5, EXTENT, "snafu", s); |
| |
| /* long read is ok too! */ |
| assert(&s == archive_strncpy(&s, "snafu", 8)); |
| assertExactString(5, EXTENT, "snafu", s); |
| |
| archive_string_free(&s); |
| } |
| |
| static void |
| test_archive_strcpy(void) |
| { |
| struct archive_string s; |
| |
| archive_string_init(&s); |
| assertExactString(0, 0, NULL, s); |
| |
| /* null target */ |
| assert(&s == archive_strcpy(&s, "snafu")); |
| assertExactString(5, EXTENT, "snafu", s); |
| |
| /* dirty target */ |
| assert(&s == archive_strcpy(&s, "foo")); |
| assertExactString(3, EXTENT, "foo", s); |
| |
| /* dirty target, empty source */ |
| assert(&s == archive_strcpy(&s, "")); |
| assertExactString(0, EXTENT, "", s); |
| |
| archive_string_free(&s); |
| } |
| |
| static void |
| test_archive_string_concat(void) |
| { |
| struct archive_string s, t, u, v; |
| |
| archive_string_init(&s); |
| assertExactString(0, 0, NULL, s); |
| archive_string_init(&t); |
| assertExactString(0, 0, NULL, t); |
| archive_string_init(&u); |
| assertExactString(0, 0, NULL, u); |
| archive_string_init(&v); |
| assertExactString(0, 0, NULL, v); |
| |
| /* null target, null source */ |
| archive_string_concat(&t, &s); |
| assertExactString(0, 0, NULL, s); |
| assertExactString(0, EXTENT, "", t); |
| |
| /* null target, empty source */ |
| assert(&s == archive_strcpy(&s, "")); |
| archive_string_concat(&u, &s); |
| assertExactString(0, EXTENT, "", s); |
| assertExactString(0, EXTENT, "", u); |
| |
| /* null target, non-empty source */ |
| assert(&s == archive_strcpy(&s, "foo")); |
| archive_string_concat(&v, &s); |
| assertExactString(3, EXTENT, "foo", s); |
| assertExactString(3, EXTENT, "foo", v); |
| |
| /* empty target, empty source */ |
| assert(&s == archive_strcpy(&s, "")); |
| assert(&t == archive_strcpy(&t, "")); |
| archive_string_concat(&t, &s); |
| assertExactString(0, EXTENT, "", s); |
| assertExactString(0, EXTENT, "", t); |
| |
| /* empty target, non-empty source */ |
| assert(&s == archive_strcpy(&s, "snafu")); |
| assert(&t == archive_strcpy(&t, "")); |
| archive_string_concat(&t, &s); |
| assertExactString(5, EXTENT, "snafu", s); |
| assertExactString(5, EXTENT, "snafu", t); |
| |
| archive_string_free(&v); |
| archive_string_free(&u); |
| archive_string_free(&t); |
| archive_string_free(&s); |
| } |
| |
| static void |
| test_archive_string_copy(void) |
| { |
| struct archive_string s, t, u, v; |
| |
| archive_string_init(&s); |
| assertExactString(0, 0, NULL, s); |
| archive_string_init(&t); |
| assertExactString(0, 0, NULL, t); |
| archive_string_init(&u); |
| assertExactString(0, 0, NULL, u); |
| archive_string_init(&v); |
| assertExactString(0, 0, NULL, v); |
| |
| /* null target, null source */ |
| archive_string_copy(&t, &s); |
| assertExactString(0, 0, NULL, s); |
| assertExactString(0, EXTENT, "", t); |
| |
| /* null target, empty source */ |
| archive_string_copy(&u, &t); |
| assertExactString(0, EXTENT, "", t); |
| assertExactString(0, EXTENT, "", u); |
| |
| /* empty target, empty source */ |
| archive_string_copy(&u, &t); |
| assertExactString(0, EXTENT, "", t); |
| assertExactString(0, EXTENT, "", u); |
| |
| /* null target, non-empty source */ |
| assert(NULL != archive_strcpy(&s, "snafubar")); |
| assertExactString(8, EXTENT, "snafubar", s); |
| |
| archive_string_copy(&v, &s); |
| assertExactString(8, EXTENT, "snafubar", s); |
| assertExactString(8, EXTENT, "snafubar", v); |
| |
| /* empty target, non-empty source */ |
| assertExactString(0, EXTENT, "", t); |
| archive_string_copy(&t, &s); |
| assertExactString(8, EXTENT, "snafubar", s); |
| assertExactString(8, EXTENT, "snafubar", t); |
| |
| /* non-empty target, non-empty source */ |
| assert(NULL != archive_strcpy(&s, "fubar")); |
| assertExactString(5, EXTENT, "fubar", s); |
| |
| archive_string_copy(&t, &s); |
| assertExactString(5, EXTENT, "fubar", s); |
| assertExactString(5, EXTENT, "fubar", t); |
| |
| archive_string_free(&v); |
| archive_string_free(&u); |
| archive_string_free(&t); |
| archive_string_free(&s); |
| } |
| |
| static void |
| test_archive_string_sprintf(void) |
| { |
| struct archive_string s; |
| #define S16 "0123456789abcdef" |
| #define S32 S16 S16 |
| #define S64 S32 S32 |
| #define S128 S64 S64 |
| const char *s32 = S32; |
| const char *s33 = S32 "0"; |
| const char *s64 = S64; |
| const char *s65 = S64 "0"; |
| const char *s128 = S128; |
| const char *s129 = S128 "0"; |
| #undef S16 |
| #undef S32 |
| #undef S64 |
| #undef S128 |
| |
| archive_string_init(&s); |
| assertExactString(0, 0, NULL, s); |
| |
| archive_string_sprintf(&s, "%s", ""); |
| assertExactString(0, 2 * EXTENT, "", s); |
| |
| archive_string_empty(&s); |
| archive_string_sprintf(&s, "%s", s32); |
| assertExactString(32, 2 * EXTENT, s32, s); |
| |
| archive_string_empty(&s); |
| archive_string_sprintf(&s, "%s", s33); |
| assertExactString(33, 2 * EXTENT, s33, s); |
| |
| archive_string_empty(&s); |
| archive_string_sprintf(&s, "%s", s64); |
| assertExactString(64, 4 * EXTENT, s64, s); |
| |
| archive_string_empty(&s); |
| archive_string_sprintf(&s, "%s", s65); |
| assertExactString(65, 4 * EXTENT, s65, s); |
| |
| archive_string_empty(&s); |
| archive_string_sprintf(&s, "%s", s128); |
| assertExactString(128, 8 * EXTENT, s128, s); |
| |
| archive_string_empty(&s); |
| archive_string_sprintf(&s, "%s", s129); |
| assertExactString(129, 8 * EXTENT, s129, s); |
| |
| archive_string_empty(&s); |
| archive_string_sprintf(&s, "%d", 1234567890); |
| assertExactString(10, 8 * EXTENT, "1234567890", s); |
| |
| archive_string_free(&s); |
| } |
| |
| DEFINE_TEST(test_archive_string) |
| { |
| test_archive_string_ensure(); |
| test_archive_strcat(); |
| test_archive_strappend_char(); |
| test_archive_strncat(); |
| test_archive_strncpy(); |
| test_archive_strcpy(); |
| test_archive_string_concat(); |
| test_archive_string_copy(); |
| test_archive_string_sprintf(); |
| } |
| |
| static const char *strings[] = |
| { |
| "dir/path", |
| "dir/path2", |
| "dir/path3", |
| "dir/path4", |
| "dir/path5", |
| "dir/path6", |
| "dir/path7", |
| "dir/path8", |
| "dir/path9", |
| "dir/subdir/path", |
| "dir/subdir/path2", |
| "dir/subdir/path3", |
| "dir/subdir/path4", |
| "dir/subdir/path5", |
| "dir/subdir/path6", |
| "dir/subdir/path7", |
| "dir/subdir/path8", |
| "dir/subdir/path9", |
| "dir2/path", |
| "dir2/path2", |
| "dir2/path3", |
| "dir2/path4", |
| "dir2/path5", |
| "dir2/path6", |
| "dir2/path7", |
| "dir2/path8", |
| "dir2/path9", |
| NULL |
| }; |
| |
| DEFINE_TEST(test_archive_string_sort) |
| { |
| unsigned int i, j, size; |
| char **test_strings, *tmp; |
| |
| srand((unsigned int)time(NULL)); |
| size = sizeof(strings) / sizeof(char *); |
| assert((test_strings = (char **)calloc(1, sizeof(strings))) != NULL); |
| for (i = 0; i < (size - 1); i++) |
| assert((test_strings[i] = strdup(strings[i])) != NULL); |
| |
| /* Shuffle the test strings */ |
| for (i = 0; i < (size - 1); i++) |
| { |
| j = rand() % ((size - 1) - i); |
| j += i; |
| tmp = test_strings[i]; |
| test_strings[i] = test_strings[j]; |
| test_strings[j] = tmp; |
| } |
| |
| /* Sort and test */ |
| assertEqualInt(ARCHIVE_OK, archive_utility_string_sort(test_strings)); |
| for (i = 0; i < (size - 1); i++) |
| assertEqualString(test_strings[i], strings[i]); |
| |
| for (i = 0; i < (size - 1); i++) |
| free(test_strings[i]); |
| free(test_strings); |
| } |