/* * Example program for the Allegro library. * * Stress test path routines. */ #include #include #include "common.c" #ifdef ALLEGRO_MSVC #pragma warning (disable: 4066) #endif typedef void (*test_t)(void); int error = 0; #define CHECK(x) \ do { \ bool ok = (bool)(x); \ if (!ok) { \ log_printf("FAIL %s\n", #x); \ error++; \ } else { \ log_printf("OK %s\n", #x); \ } \ } while (0) #define CHECK_EQ(x,y) CHECK(0 == strcmp(x, y)) /*---------------------------------------------------------------------------*/ /* Test al_create_path, al_get_path_num_components, al_get_path_component, * al_get_path_drive, al_get_path_filename, al_destroy_path. */ static void t1(void) { ALLEGRO_PATH *path; CHECK(path = al_create_path(NULL)); al_destroy_path(path); CHECK(path = al_create_path("")); CHECK(al_get_path_num_components(path) == 0); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* . is a directory component. */ CHECK(path = al_create_path(".")); CHECK(al_get_path_num_components(path) == 1); CHECK_EQ(al_get_path_component(path, 0), "."); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* .. is a directory component. */ CHECK(path = al_create_path("..")); CHECK(al_get_path_num_components(path) == 1); CHECK_EQ(al_get_path_component(path, 0), ".."); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* Relative path. */ CHECK(path = al_create_path("abc/def/..")); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "def"); CHECK_EQ(al_get_path_component(path, 2), ".."); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* Absolute path. */ CHECK(path = al_create_path("/abc/def/..")); CHECK(al_get_path_num_components(path) == 4); CHECK_EQ(al_get_path_component(path, 0), ""); CHECK_EQ(al_get_path_component(path, 1), "abc"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_component(path, 3), ".."); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), ""); al_destroy_path(path); /* Directories + filename. */ CHECK(path = al_create_path("/abc/def/ghi")); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), ""); CHECK_EQ(al_get_path_component(path, 1), "abc"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_drive(path), ""); CHECK_EQ(al_get_path_filename(path), "ghi"); al_destroy_path(path); } /* Test parsing UNC paths. */ static void t2(void) { #ifdef ALLEGRO_WINDOWS ALLEGRO_PATH *path; /* The mixed slashes are deliberate. */ /* Good paths. */ CHECK(path = al_create_path("//server\\share name/dir/filename")); CHECK_EQ(al_get_path_drive(path), "//server"); CHECK(al_get_path_num_components(path) == 2); CHECK_EQ(al_get_path_component(path, 0), "share name"); CHECK_EQ(al_get_path_component(path, 1), "dir"); CHECK_EQ(al_get_path_filename(path), "filename"); al_destroy_path(path); /* Bad paths. */ CHECK(! al_create_path("//")); CHECK(! al_create_path("//filename")); CHECK(! al_create_path("///share/name/filename")); #else log_printf("Skipping Windows-only test...\n"); #endif } /* Test parsing drive letter paths. */ static void t3(void) { #ifdef ALLEGRO_WINDOWS ALLEGRO_PATH *path; /* The mixed slashes are deliberate. */ CHECK(path = al_create_path("c:abc\\def/ghi")); CHECK_EQ(al_get_path_drive(path), "c:"); CHECK(al_get_path_num_components(path) == 2); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "def"); CHECK_EQ(al_get_path_filename(path), "ghi"); CHECK_EQ(al_path_cstr(path, '\\'), "c:abc\\def\\ghi"); al_destroy_path(path); CHECK(path = al_create_path("c:\\abc/def\\ghi")); CHECK_EQ(al_get_path_drive(path), "c:"); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), ""); CHECK_EQ(al_get_path_component(path, 1), "abc"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_filename(path), "ghi"); CHECK_EQ(al_path_cstr(path, '\\'), "c:\\abc\\def\\ghi"); al_destroy_path(path); #else log_printf("Skipping Windows-only test...\n"); #endif } /* Test al_append_path_component. */ static void t4(void) { ALLEGRO_PATH *path = al_create_path(NULL); CHECK(al_get_path_num_components(path) == 0); al_append_path_component(path, "abc"); al_append_path_component(path, "def"); al_append_path_component(path, "ghi"); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "def"); CHECK_EQ(al_get_path_component(path, 2), "ghi"); CHECK_EQ(al_get_path_component(path, -1), "ghi"); CHECK_EQ(al_get_path_component(path, -2), "def"); CHECK_EQ(al_get_path_component(path, -3), "abc"); al_destroy_path(path); } /* Test al_replace_path_component. */ static void t5(void) { ALLEGRO_PATH *path = al_create_path(NULL); al_append_path_component(path, "abc"); al_append_path_component(path, "INKY"); al_append_path_component(path, "def"); al_append_path_component(path, "BLINKY"); al_append_path_component(path, "ghi"); CHECK(al_get_path_num_components(path) == 5); al_replace_path_component(path, 1, "PINKY"); al_replace_path_component(path, -2, "CLYDE"); CHECK(al_get_path_num_components(path) == 5); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "PINKY"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_component(path, 3), "CLYDE"); CHECK_EQ(al_get_path_component(path, 4), "ghi"); al_destroy_path(path); } /* Test al_remove_path_component. */ static void t6(void) { ALLEGRO_PATH *path = al_create_path(NULL); al_append_path_component(path, "abc"); al_append_path_component(path, "INKY"); al_append_path_component(path, "def"); al_append_path_component(path, "BLINKY"); al_append_path_component(path, "ghi"); CHECK(al_get_path_num_components(path) == 5); al_remove_path_component(path, 1); CHECK(al_get_path_num_components(path) == 4); al_remove_path_component(path, -2); CHECK(al_get_path_num_components(path) == 3); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "def"); CHECK_EQ(al_get_path_component(path, 2), "ghi"); al_destroy_path(path); } /* Test al_insert_path_component. */ static void t7(void) { ALLEGRO_PATH *path = al_create_path("INKY/BLINKY/"); al_insert_path_component(path, 0, "abc"); al_insert_path_component(path, 2, "def"); al_insert_path_component(path, 4, "ghi"); CHECK(al_get_path_num_components(path) == 5); CHECK_EQ(al_get_path_component(path, 0), "abc"); CHECK_EQ(al_get_path_component(path, 1), "INKY"); CHECK_EQ(al_get_path_component(path, 2), "def"); CHECK_EQ(al_get_path_component(path, 3), "BLINKY"); CHECK_EQ(al_get_path_component(path, 4), "ghi"); al_destroy_path(path); } /* Test al_get_path_tail, al_drop_path_tail. */ static void t8(void) { ALLEGRO_PATH *path = al_create_path(NULL); CHECK(! al_get_path_tail(path)); al_append_path_component(path, "abc"); al_append_path_component(path, "def"); al_append_path_component(path, "ghi"); CHECK_EQ(al_get_path_tail(path), "ghi"); al_drop_path_tail(path); CHECK_EQ(al_get_path_tail(path), "def"); al_drop_path_tail(path); al_drop_path_tail(path); CHECK(! al_get_path_tail(path)); /* Drop tail from already empty path. */ al_drop_path_tail(path); CHECK(! al_get_path_tail(path)); al_destroy_path(path); } /* Test al_set_path_drive, al_set_path_filename, al_path_cstr. */ static void t9(void) { ALLEGRO_PATH *path = al_create_path(NULL); CHECK_EQ(al_path_cstr(path, '/'), ""); /* Drive letters. */ al_set_path_drive(path, "c:"); CHECK_EQ(al_path_cstr(path, '/'), "c:"); CHECK_EQ(al_get_path_drive(path), "c:"); al_set_path_drive(path, "d:"); CHECK_EQ(al_path_cstr(path, '/'), "d:"); /* Plus directory components. */ al_append_path_component(path, "abc"); al_append_path_component(path, "def"); CHECK_EQ(al_path_cstr(path, '/'), "d:abc/def/"); /* Plus filename. */ al_set_path_filename(path, "uvw"); CHECK_EQ(al_path_cstr(path, '/'), "d:abc/def/uvw"); CHECK_EQ(al_get_path_filename(path), "uvw"); /* Replace filename. */ al_set_path_filename(path, "xyz"); CHECK_EQ(al_path_cstr(path, '/'), "d:abc/def/xyz"); /* Remove drive. */ al_set_path_drive(path, NULL); CHECK_EQ(al_path_cstr(path, '/'), "abc/def/xyz"); /* Remove filename. */ al_set_path_filename(path, NULL); CHECK_EQ(al_path_cstr(path, '/'), "abc/def/"); al_destroy_path(path); } /* Test al_join_paths. */ static void t10(void) { ALLEGRO_PATH *path1; ALLEGRO_PATH *path2; /* Both empty. */ path1 = al_create_path(NULL); path2 = al_create_path(NULL); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), ""); al_destroy_path(path1); al_destroy_path(path2); /* Both just filenames. */ path1 = al_create_path("file1"); path2 = al_create_path("file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "file2"); al_destroy_path(path1); al_destroy_path(path2); /* Both relative paths. */ path1 = al_create_path("dir1a/dir1b/file1"); path2 = al_create_path("dir2a/dir2b/file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); #ifdef ALLEGRO_WINDOWS /* Both relative paths with drive letters. */ path1 = al_create_path("d:dir1a/dir1b/file1"); path2 = al_create_path("e:dir2a/dir2b/file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "d:dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); #endif /* Path1 absolute, path2 relative. */ path1 = al_create_path("/dir1a/dir1b/file1"); path2 = al_create_path("dir2a/dir2b/file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "/dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); /* Both paths absolute. */ path1 = al_create_path("/dir1a/dir1b/file1"); path2 = al_create_path("/dir2a/dir2b/file2"); al_join_paths(path1, path2); CHECK_EQ(al_path_cstr(path1, '/'), "/dir1a/dir1b/file1"); al_destroy_path(path1); al_destroy_path(path2); } /* Test al_rebase_path. */ static void t11(void) { ALLEGRO_PATH *path1; ALLEGRO_PATH *path2; /* Both empty. */ path1 = al_create_path(NULL); path2 = al_create_path(NULL); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), ""); al_destroy_path(path1); al_destroy_path(path2); /* Both just filenames. */ path1 = al_create_path("file1"); path2 = al_create_path("file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "file2"); al_destroy_path(path1); al_destroy_path(path2); /* Both relative paths. */ path1 = al_create_path("dir1a/dir1b/file1"); path2 = al_create_path("dir2a/dir2b/file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); #ifdef ALLEGRO_WINDOWS /* Both relative paths with drive letters. */ path1 = al_create_path("d:dir1a/dir1b/file1"); path2 = al_create_path("e:dir2a/dir2b/file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "d:dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); #endif /* Path1 absolute, path2 relative. */ path1 = al_create_path("/dir1a/dir1b/file1"); path2 = al_create_path("dir2a/dir2b/file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "/dir1a/dir1b/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); /* Both paths absolute. */ path1 = al_create_path("/dir1a/dir1b/file1"); path2 = al_create_path("/dir2a/dir2b/file2"); al_rebase_path(path1, path2); CHECK_EQ(al_path_cstr(path2, '/'), "/dir2a/dir2b/file2"); al_destroy_path(path1); al_destroy_path(path2); } /* Test al_set_path_extension, al_get_path_extension. */ static void t12(void) { ALLEGRO_PATH *path = al_create_path(NULL); /* Get null extension. */ CHECK_EQ(al_get_path_extension(path), ""); /* Set extension on null filename. */ CHECK(! al_set_path_extension(path, "ext")); CHECK_EQ(al_get_path_filename(path), ""); /* Set extension on extension-less filename. */ al_set_path_filename(path, "abc"); CHECK(al_set_path_extension(path, ".ext")); CHECK_EQ(al_get_path_filename(path), "abc.ext"); /* Replacing extension. */ al_set_path_filename(path, "abc.def"); CHECK(al_set_path_extension(path, ".ext")); CHECK_EQ(al_get_path_filename(path), "abc.ext"); CHECK_EQ(al_get_path_extension(path), ".ext"); /* Filename with multiple dots. */ al_set_path_filename(path, "abc.def.ghi"); CHECK(al_set_path_extension(path, ".ext")); CHECK_EQ(al_get_path_filename(path), "abc.def.ext"); CHECK_EQ(al_get_path_extension(path), ".ext"); al_destroy_path(path); } /* Test al_get_path_basename. */ static void t13(void) { ALLEGRO_PATH *path = al_create_path(NULL); /* No filename. */ al_set_path_filename(path, NULL); CHECK_EQ(al_get_path_basename(path), ""); /* No extension. */ al_set_path_filename(path, "abc"); CHECK_EQ(al_get_path_basename(path), "abc"); /* Filename with a single dot. */ al_set_path_filename(path, "abc.ext"); CHECK_EQ(al_get_path_basename(path), "abc"); /* Filename with multiple dots. */ al_set_path_filename(path, "abc.def.ghi"); CHECK_EQ(al_get_path_basename(path), "abc.def"); al_destroy_path(path); } /* Test al_clone_path. */ static void t14(void) { ALLEGRO_PATH *path1; ALLEGRO_PATH *path2; path1 = al_create_path("/abc/def/ghi"); path2 = al_clone_path(path1); CHECK_EQ(al_path_cstr(path1, '/'), al_path_cstr(path2, '/')); al_replace_path_component(path2, 2, "DEF"); al_set_path_filename(path2, "GHI"); CHECK_EQ(al_path_cstr(path1, '/'), "/abc/def/ghi"); CHECK_EQ(al_path_cstr(path2, '/'), "/abc/DEF/GHI"); al_destroy_path(path1); al_destroy_path(path2); } static void t15(void) { /* nothing */ log_printf("Skipping empty test...\n"); } static void t16(void) { /* nothing */ log_printf("Skipping empty test...\n"); } /* Test al_make_path_canonical. */ static void t17(void) { ALLEGRO_PATH *path; path = al_create_path("/../.././abc/./def/../../ghi/jkl"); CHECK(al_make_path_canonical(path)); CHECK(al_get_path_num_components(path) == 6); CHECK_EQ(al_path_cstr(path, '/'), "/abc/def/../../ghi/jkl"); al_destroy_path(path); path = al_create_path("../.././abc/./def/../../ghi/jkl"); CHECK(al_make_path_canonical(path)); CHECK(al_get_path_num_components(path) == 7); CHECK_EQ(al_path_cstr(path, '/'), "../../abc/def/../../ghi/jkl"); al_destroy_path(path); } /*---------------------------------------------------------------------------*/ const test_t all_tests[] = { NULL, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17 }; #define NUM_TESTS (int)(sizeof(all_tests) / sizeof(all_tests[0])) int main(int argc, char **argv) { int i; if (!al_init()) { abort_example("Could not initialise Allegro.\n"); } open_log(); if (argc < 2) { for (i = 1; i < NUM_TESTS; i++) { log_printf("# t%d\n\n", i); all_tests[i](); log_printf("\n"); } } else { i = atoi(argv[1]); if (i > 0 && i < NUM_TESTS) { all_tests[i](); } } log_printf("Done\n"); close_log(true); if (error) { exit(EXIT_FAILURE); } return 0; } /* vim: set sts=3 sw=3 et: */