#include #include #include #if defined(TEST_TARGET_tree) #include #include #include #else #include "init.h" #include "command.h" #include "unitt.h" #include "kern.h" #include "tree.h" #endif /************************************************************************************/ /************************************* Unit Test ************************************/ /************************************************************************************/ // #define EXIT_TEST extern uint64_t unitt_clock(void); static int test_0(void) { for (int i = 0; i < 100; i++) { if (0) { #if defined (EXIT_TEST) exit(0); #endif return UNITT_E_FAIL; } } return UNITT_E_OK; } static void unitt_task(void) { static UNITT_TCASE rand_tests[] = { UNITT_TCASE(test_0), // UNITT_TCASE(test_1), // UNITT_TCASE(test_2), }; static UNITT suites[] = { { "xxx suite", rand_tests, sizeof(rand_tests) / sizeof(rand_tests[0]) , unitt_clock }, }; UNITT_EXE(suites); } /************************************************************************************/ /************************************* Base Test ************************************/ /************************************************************************************/ static void print_int(tree_t tree) { if (tree_data(tree)) printf("%d", *(int *)tree_data(tree)); } static void print_string(tree_t tree) { if (tree_data(tree)) printf("%s", (char *)tree_data(tree)); } static void print_dir(tree_t tree) { if (tree_data(tree)) printf("%s", (char *)tree_data(tree)); } static void print_ini(tree_t tree) { if (!tree_asize(tree)) return; printf("%s", (char *)tree_attribute(tree)); if (tree_dsize(tree)) printf(" = %s", (char *)tree_data(tree)); } static void print_bitree(tree_t tree) { if (tree_dsize(tree)) printf("%s", (char *)tree_data(tree)); } #if 0 #include "ini.h" static tree_t tree_from_ini(const char *filename) { tree_t tree = NULL, section, pair; ini_t ini; char *section_name, *key, *value; int i, j; ini = ini_file_load(filename); if (!ini) goto FAIL; tree = tree_create(); if (!tree) goto FAIL; for (i = 0; i < ini_section_count(ini); i++) { section = tree_create(); if (!section) goto FAIL; tree_insert(tree, tree_csize(tree)); tree_attach(tree, tree_csize(tree) - 1, section); section_name = (char*)ini_section_name(ini, i); tree_set_attribute(section, section_name, strlen(section_name) + 1); for (j = 0; j < ini_pair_count(ini, section_name); j++) { pair = tree_create(); if (!pair) goto FAIL; tree_insert(section, tree_csize(section)); tree_attach(section, tree_csize(section) - 1, pair); key = (char *)ini_key_name(ini, section_name, j); tree_set_attribute(pair, key, strlen(key) + 1); value = (char *)ini_get_value(ini, section_name, key); tree_set_data(pair, value, strlen(value) + 1); } } ini_delete(ini); return tree; FAIL: if (ini) ini_delete(ini); if (tree) tree_delete(tree, NULL); return NULL; } static void test_ini(void) { tree_t tree, n; tree = tree_from_ini("../source/application/test/file/read.ini"); if (!tree) { printf("transfer fail!\r\n"); } tree_print(tree_child(tree, 0), 0, print_ini); tree_delete(tree, NULL); } #endif #include #include static tree_t tree_directory(const char *directory, int depth) { tree_t tree = NULL, n; DIR *dirptr; struct dirent* dircontent; if (depth < 0) return NULL; tree = tree_create(); if (!tree) return NULL; dirptr = opendir(directory); if (!dirptr) goto FAIL; while (1) { dircontent = readdir(dirptr); if (dircontent == NULL) break; if (strcmp(dircontent->d_name,".") == 0 || strcmp(dircontent->d_name,"..") == 0) continue; struct stat statinfo; char fullname[1024]; sprintf(fullname, "%s/%s", directory, dircontent->d_name); if (stat(fullname, &statinfo)) continue; if (S_ISDIR(statinfo.st_mode) && depth != 1) n = tree_directory(fullname, depth ? depth - 1 : 0); else if (S_ISREG(statinfo.st_mode)) n = tree_create(); else continue; if (n) { if (!tree_insert(tree, tree_csize(tree))) goto FAIL; tree_attach(tree, tree_csize(tree) - 1, n); } tree_set_data(n, dircontent->d_name, strlen(dircontent->d_name) + 1); } if (!tree_data(tree)) tree_set_data(tree, directory, strlen(directory) + 1); return tree; FAIL: if (tree) tree_delete(tree, NULL); return NULL; } static void test_dir(void) { tree_t tree; tree = tree_directory("./", 0); if (!tree) { printf("load fail!\r\n"); } // tree_insert(tree, 1); // printf("name %s, %d\r\n", tree_data(tree), tree_size(tree)); tree_print(tree, 0, print_dir); tree_delete(tree, NULL); } static void test_create(void) { tree_t tree = tree_create(); if (tree) { printf("tree create success!!!\r\n"); } else { printf("[ERROR] tree create fail!!!\r\n"); } tree_delete(tree, NULL); } static void test_set(void) { tree_t tree = tree_create(); int set = 100; int get = 0; tree_set_data(tree, &set, sizeof(set)); tree_get_data(tree, &get, sizeof(get)); printf("get %d\r\n", get); printf("data %d\r\n", *(int *)tree_data(tree)); tree_delete(tree, NULL); } static void test_insert(void) { tree_t tree = tree_create(); tree_insert(tree, 0); tree_insert(tree, 1); tree_insert(tree, 2); tree_insert(tree, 3); printf("tree child size %d\r\n", tree_csize(tree)); tree_erase(tree, 2); printf("tree child size %d\r\n", tree_csize(tree)); tree_delete(tree, NULL); } static void test_attach(void) { tree_t tree = tree_create(); tree_t node = NULL; int data = 0; tree_insert(tree, 0); tree_insert(tree, 1); tree_insert(tree, 2); tree_insert(tree, 3); for (int i = 0; i < tree_csize(tree); i++) { node = tree_create(); data = 1000 + i; tree_attach(tree, i, node); tree_set_data(node, &data, sizeof(data)); } tree_print(tree, 0, print_int); node = tree_detach(tree, 1); tree_delete(node, NULL); tree_print(tree, 0, print_int); tree_delete(tree, NULL); } static void test_parent(void) { tree_t tree = tree_create(); tree_t node = NULL; tree_t parent, child; tree_insert(tree, 0); tree_insert(tree, 1); tree_insert(tree, 2); tree_insert(tree, 3); tree_set_data(tree, "Parent", 7); node = tree_create(); tree_set_data(node, "Child0", 7); tree_attach(tree, 0, node); node = tree_create(); tree_set_data(node, "Child1", 7); tree_attach(tree, 1, node); node = tree_create(); tree_set_data(node, "Child2", 7); tree_attach(tree, 2, node); node = tree_create(); tree_set_data(node, "Child3", 7); tree_attach(tree, 3, node); tree_print(tree, 0, print_string); parent = tree_parent(node); print_string(parent); printf("\r\n"); child = tree_child(tree, 0); print_string(child); printf("\r\n"); child = tree_child(tree, 1); print_string(child); printf("\r\n"); child = tree_child(tree, 2); print_string(child); printf("\r\n"); child = tree_child(tree, 3); print_string(child); printf("\r\n"); tree_delete(tree, NULL); } static void test_attr(void) { tree_t tree = tree_create(); char attr[20]; tree_set_attribute(tree, "This attribute!!!", 18); tree_get_attribute(tree, attr, sizeof(attr)); printf("attr %s\r\n", attr); tree_delete(tree, NULL); } static void test_depth(void) { tree_t root = tree_create(); tree_t node, temp; tree_insert(root, 0); tree_insert(root, 1); tree_insert(root, 2); tree_attach(root, 0, tree_create()); tree_attach(root, 1, tree_create()); node = tree_child(root, 0); tree_insert(node, 0); tree_insert(node, 1); node = tree_child(root, 1); tree_insert(node, 0); tree_insert(node, 1); tree_attach(node, 0, tree_create()); tree_attach(node, 1, tree_create()); tree_print(root, 0, NULL); printf("depth %d\r\n", tree_depth(root)); tree_delete(root, NULL); } static void test_to(void) { tree_t root = tree_create(); tree_t node, temp; tree_insert(root, 0); tree_insert(root, 1); tree_insert(root, 2); tree_attach(root, 0, tree_create()); tree_attach(root, 1, tree_create()); node = tree_child(root, 0); tree_insert(node, 0); tree_insert(node, 1); node = tree_child(root, 1); tree_insert(node, 0); tree_insert(node, 1); tree_attach(node, 0, tree_create()); tree_attach(node, 1, tree_create()); temp = tree_to(root, 1, 1); tree_set_data(temp, "To function!!!", 15); tree_print(root, 0, print_string); tree_delete(root, NULL); } static void test_common(void) { tree_t root, n, t; int i, data; root = tree_create(); data = 1024; tree_set_data(root, &data, sizeof(data)); for (i = 0; i < 12; i++) { n = tree_create(); if (!n) break; tree_insert(root, tree_csize(root)); tree_attach(root, tree_csize(root) - 1, n); data = i; tree_set_data(n, &data, sizeof(data)); } t = tree_to(root, 3); for (i = 0; i < 8; i++) { n = tree_create(); if (!n) break; tree_insert(t, tree_csize(t)); tree_attach(t, tree_csize(t) - 1, n); data = i + 30; tree_set_data(n, &data, sizeof(data)); } t = tree_to(root, 3, 6); for (i = 0; i < 4; i++) { n = tree_create(); if (!n) break; tree_insert(t, tree_csize(t)); tree_attach(t, tree_csize(t) - 1, n); data = i + 360; tree_set_data(n, &data, sizeof(data)); } printf("tree size %d\r\n", tree_size(root)); printf("tree depth %d\r\n", tree_depth(root)); /* show */ tree_print(root, 0, print_int); tree_delete(root, NULL); } static tree_t bitree_gen(int depth) { tree_t tree; if (depth <= 0) return NULL; tree = tree_create(); tree_insert(tree, 0); tree_insert(tree, 0); tree_attach(tree, 0, bitree_gen(depth - 1)); tree_attach(tree, 1, bitree_gen(depth - 1)); return tree; } static void test_bitree(void) { tree_t tree = bitree_gen(5); tree_set_data(tree_to(tree, 0, 0, 0), "123", strlen("123") + 1); tree_print(tree, 0, print_bitree); tree_delete(tree, NULL); } static void test_base(void) { // test_common(); test_dir(); // test_ini(); // test_bitree(); } /************************************************************************************/ /************************************* Command ************************************/ /************************************************************************************/ static void usage(void) { printf( "Usage: tree [opt] [arg] ...\n" "\n" "options:\n" " -e Specifies the function to execute, the default is the test\n" " Test base function\n" " Unit test\n" " Test create and delete functions\n" " Test set and get data function\n" " Test insert and erase child function\n" " Test attach and dettach child function\n" " Test get parent and child node function\n" " Test set and get attrubute function\n" " Test get tree depth function\n" " Test locate to specify node function\n" " -h Print help\n" " -v Print version\n" " -u [] Unit test period, unit ms, the default is 1000ms\n" "\n" ); } static int test(int argc, char *argv[]) { char *execute = NULL; int ut_period = 1000; /* reset getopt */ command_opt_init(); while (1) { int opt = command_getopt(argc, argv, "e:hvu::"); if (opt == -1) break; switch (opt) { case 'u' : if (command_optarg) ut_period = atoi(command_optarg); break; case 'e' : execute = command_optarg; break; case 'v' : printf("tree version %d.%d.%d\r\n", TREE_V_MAJOR, TREE_V_MINOR, TREE_V_PATCH); return 0; case '?': printf("Unknown option `%c`\r\n", command_optopt); return -1; case 'h' : default: usage(); return 0; } } if (execute) { if (!strcmp(execute, "base")) { test_base(); } else if (!strcmp(execute, "ut")) { srand((unsigned int)time(NULL)); #if defined(TEST_TARGET_tree) while (1) { unitt_task(); usleep(1000 * ut_period); } #else printf("create task %d\r\n", task_create(ut_period, unitt_task)); #endif } else if (!strcmp(execute, "create")) { test_create(); } else if (!strcmp(execute, "set")) { test_set(); } else if (!strcmp(execute, "insert")) { test_insert(); } else if (!strcmp(execute, "attach")) { test_attach(); } else if (!strcmp(execute, "parent")) { test_parent(); } else if (!strcmp(execute, "attr")) { test_attr(); } else if (!strcmp(execute, "depth")) { test_depth(); } else if (!strcmp(execute, "to")) { test_to(); } } else { test_base(); } return 0; } /************************************************************************************/ /************************************ Test entry ************************************/ /************************************************************************************/ #if defined(TEST_TARGET_tree) int main(int argc, char *argv[]) { return test(argc, argv); } #else void test_tree(void) { command_export("tree", test); } init_export_app(test_tree); #endif