diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2019-11-13 16:48:03 -0500 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2019-11-13 16:48:03 -0500 |
commit | 244fa85e98fa6f325025f49aca6e1fbb1e440582 (patch) | |
tree | 502ab3bbfb49749fad1cfaa5f2e20268d3f5c5e4 | |
parent | e801b594a18dbaf9283ad860c86e4a07b2b1e866 (diff) | |
download | reloc-244fa85e98fa6f325025f49aca6e1fbb1e440582.tar.gz |
Decouple main program and add initial tests
-rw-r--r-- | CMakeLists.txt | 16 | ||||
-rw-r--r-- | main.c | 72 | ||||
-rw-r--r-- | reloc.c | 69 | ||||
-rw-r--r-- | test/CMakeLists.txt | 12 | ||||
-rw-r--r-- | test/myassert.h | 11 | ||||
-rw-r--r-- | test/test_reloc_match.c | 90 | ||||
-rw-r--r-- | test/test_reloc_read.c | 38 |
7 files changed, 236 insertions, 72 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 583d65c..c718375 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,22 @@ cmake_minimum_required(VERSION 2.8.11) -project(reloc C) +project(relocate C) set(VERSION "1.0.0") - set(CMAKE_C_STANDARD 99) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra") +enable_testing() +add_subdirectory(test) + configure_file(version.h.in version.h) + include_directories("${CMAKE_BINARY_DIR}") -add_executable(reloc main.c reloc.h) + +add_library(relocate + STATIC reloc.c) + +add_executable(reloc main.c) + +target_link_libraries(reloc relocate) + install(TARGETS reloc RUNTIME DESTINATION bin) @@ -0,0 +1,72 @@ +#include "reloc.h" + + +void show_version() { + printf("%s\n", VERSION); +} + + +int main(int argc, char *argv[]) { + char *program = argv[0]; + char *program_relative = strrchr(program, DIRSEP); + if (program_relative) { + program = program_relative + 1; + } + + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-V")) { + show_version(); + exit(0); + } + } + + if (argc < 5) { + printf("usage: %s [-V] <str1> <str2> <input_file> <output_file>\n" + "\n" + "Options:\n" + "--version (-V) - Display version and exit\n" + "\n" + "Positional arguments:\n" + "str1 - Search string\n" + "str2 - Replacement string\n" + "input_file - Input file name\n" + "output_file - Output file name\n" + "\n" + "Example:\n" + "%s /original/string /new/string input.bin output.bin\n" + "\n", program, program); + exit(1); + } + + char *needle = strdup(argv[1]); + char *replacement = strdup(argv[2]); + char *input_file = strdup(argv[3]); + char *output_file = strdup(argv[4]); + RelocData *info = reloc_read(input_file); + size_t records = 0; + + for (size_t i = 0; i < info->size; i++) { + RelocMatch *match = NULL; + if (!(match = reloc_match(&info->data[i], needle))) { + // No match found + continue; + } + // Replace string + reloc_replace(match, replacement); + free(match); + records++; + } + + // Write output file to disk + reloc_write(info, output_file); + + // Report number of strings processed + printf(SIZE_T_FMT"\n", records); + + free(needle); + free(replacement); + free(input_file); + free(output_file); + reloc_deinit_data(info); + return 0; +} @@ -113,72 +113,3 @@ void reloc_replace(RelocMatch *match, const char *rstr) { // Destroy bytes between the end of the original data and the end of the replaced string memset(data, '\0', post - data); } - - -void show_version() { - printf("%s\n", VERSION); -} - - -int main(int argc, char *argv[]) { - char *program = argv[0]; - char *program_relative = strrchr(program, DIRSEP); - if (program_relative) { - program = program_relative + 1; - } - - for (int i = 0; i < argc; i++) { - if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-V")) { - show_version(); - exit(0); - } - } - - if (argc < 5) { - printf("%s [-V] <str1> <str2> <input_file> <output_file>\n" - "\n" - "Arguments:\n" - "--version (-V) - Display version and exit\n" - "str1 - Pattern to search for\n" - "str2 - Replace str1 with contents of str2\n" - "input_file - Path to input file\n" - "output_file - Path to output file\n" - "\n" - "Example:\n" - "%s /original/path /new/path input.bin output.bin\n" - "\n", program, program); - exit(1); - } - - char *needle = strdup(argv[1]); - char *replacement = strdup(argv[2]); - char *input_file = strdup(argv[3]); - char *output_file = strdup(argv[4]); - RelocData *info = reloc_read(input_file); - size_t records = 0; - - for (size_t i = 0; i < info->size; i++) { - RelocMatch *match = NULL; - if (!(match = reloc_match(&info->data[i], needle))) { - // No match found - continue; - } - // Replace string - reloc_replace(match, replacement); - free(match); - records++; - } - - // Write output file to disk - reloc_write(info, output_file); - - // Report number of strings processed - printf(SIZE_T_FMT"\n", records); - - free(needle); - free(replacement); - free(input_file); - free(output_file); - reloc_deinit_data(info); - return 0; -} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..6b79d98 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,12 @@ +project(tests) + +include_directories("${CMAKE_SOURCE_DIR}") +include_directories("${CMAKE_BINARY_DIR}") +add_executable(test_reloc_match test_reloc_match.c) +add_executable(test_reloc_read test_reloc_read.c) + +target_link_libraries(test_reloc_match relocate) +target_link_libraries(test_reloc_read relocate) + +add_test(test_reloc_match test_reloc_match) +add_test(test_reloc_read test_reloc_read) diff --git a/test/myassert.h b/test/myassert.h new file mode 100644 index 0000000..01e567e --- /dev/null +++ b/test/myassert.h @@ -0,0 +1,11 @@ +#define myassert(message, condition) \ + do { \ + if (!(condition)) { \ + fprintf(stderr, "%s:%d:%s :: %s\n", \ + __FILE__, \ + __LINE__, \ + __FUNCTION__, \ + message); \ + return 1; \ + } \ + } while (0); diff --git a/test/test_reloc_match.c b/test/test_reloc_match.c new file mode 100644 index 0000000..bb9d6b0 --- /dev/null +++ b/test/test_reloc_match.c @@ -0,0 +1,90 @@ +#include "reloc.h" +#include "myassert.h" + +char *test_cases[] = { + "I have a yellow pencil\x00", + "/one/two/three/four/five\x00\xAB\xCD\x00", + "\x09\x09\x09 1234567890\x00", + "123456789/0\x00", + NULL, +}; + +const char *test_patterns[] = { + "yellow", + "three", + "1234567890", + "/", + NULL, +}; + +const char *test_solution_begin[] = { + "yellow pencil", + "three/four/five", + "1234567890", + "/0", + NULL, +}; + +const char *test_solution_post[] = { + " pencil", + "/four/five", + "", + "0", + NULL, +}; + +const size_t test_solution_length[] = { + 6, + 5, + 10, + 1, +}; + +const size_t test_solution_post_length[] = { + 7, + 10, + 0, + 1, +}; + +const size_t test_solution_total_length[] = { + 13, + 15, + 10, + 2, +}; + +int test_reloc_match() { + for (int i = 0; test_cases[i] != NULL; i++) { + RelocMatch *match = NULL; + char *ptr = test_cases[i]; + + printf("case %d:\n", i); + while (*ptr != '\0') { + if (match) break; + printf("\tpattern=\"%s\", data=\"%s\"\n", test_patterns[i], ptr); + match = reloc_match(ptr, test_patterns[i]); + ptr++; + } + myassert("Failed to find pattern", match != NULL); + myassert("Invalid match->begin", !strcmp(match->begin, test_solution_begin[i])); + printf("\tend=\"%s\", data=\"%s\"\n", match->end, match->begin); + myassert("Invalid match->end", match->end != NULL); + printf("\tpost=\"%s\", data=\"%s\"\n", match->post, match->begin); + myassert("Invalid match->post", !strcmp(match->post, test_solution_post[i])); + printf("\tlength=%lu\n", match->length); + myassert("Invalid match->length", match->length == test_solution_length[i]); + printf("\tpost_length=%lu\n", match->post_length); + myassert("Invalid match->post_length", match->post_length == test_solution_post_length[i]); + printf("\ttotal_length=%lu\n", match->total_length); + myassert("Invalid match->total_length", match->total_length == test_solution_total_length[i]); + if (match) { + free(match); + } + } + return 0; +} + +int main() { + return test_reloc_match(); +} diff --git a/test/test_reloc_read.c b/test/test_reloc_read.c new file mode 100644 index 0000000..310370d --- /dev/null +++ b/test/test_reloc_read.c @@ -0,0 +1,38 @@ +#include "reloc.h" +#include "myassert.h" + +const char *input_file = "input.bin"; +const char *output_file = "output.bin"; +char test_case[] = + "\xAB\xCD\xEF the quick brown fox\n\x00" + "jumps over\n\x00 \xEE\x09" + "\xAB\xCD\xEF the quick brown fox\n\x00" + "jumps over\n\x00 \xEE\x09" + "\xBBthe lazy\n\x00 dog\n" + "\xAB\xCD\xEF the quick brown fox\n\x00" + "\xBBthe lazy\n\x00 dog\n"; + + +int test_reloc_read() { + RelocData *info = NULL; + if (!(info = reloc_read(input_file))) { + fprintf(stderr, "Failed to open '%s' for writing\n", input_file); + return 1; + } + myassert("info->size is incorrect", info->size == sizeof(test_case)); + myassert("info->path is incorrect", !strcmp(info->path, input_file)); + myassert("info->data is uninitialized", info->data); + return 0; +} + +int main() { + FILE *fp; + if (!(fp = fopen(input_file, "w+b"))) { + fprintf(stderr, "Failed to open '%s' for writing\n", input_file); + return 1; + } + fwrite(test_case, sizeof(char), sizeof(test_case), fp); + fclose(fp); + + return test_reloc_read(); +} |