diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d7157b..c9369c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,3 +17,4 @@ endfunction() add_subdirectory(lib) add_subdirectory(tests) +add_subdirectory(demo) diff --git a/README b/README index 782d924..9cede98 100644 --- a/README +++ b/README @@ -27,7 +27,7 @@ tests. I use Clang but the code is ISO C11, it should compile just fine with GCC. You might need to faff with CMakeLists.txt to get it to work with another compiler due to command-line flag nonsense. - scripts/build.sh # Compile library and tests + scripts/build.sh # Compile library, demo and tests scripts/test.sh # Run tests There is also an entr.sh script which will watch all the project's diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt new file mode 100644 index 0000000..7c78451 --- /dev/null +++ b/demo/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(shitgrep shitgrep.c) +set_default_target_options(shitgrep) +target_link_libraries(shitgrep PRIVATE lib) diff --git a/demo/shitgrep.c b/demo/shitgrep.c new file mode 100644 index 0000000..1064c22 --- /dev/null +++ b/demo/shitgrep.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) Camden Dixie O'Brien + * SPDX-License-Identifier: AGPL-3.0-only + */ + +#include "compile.h" + +#include +#include +#include +#include + +#define BUFFER_START_CAPACITY 128 + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + fprintf(stderr, "Usage: %s REGEX\n", argv[0]); + return EXIT_FAILURE; + } + + fsa_t dfa; + if (!compile(argv[1], strlen(argv[1]), &dfa)) { + fprintf(stderr, "Failed to parse regex\n"); + return EXIT_FAILURE; + } + + int len = 0, capacity = BUFFER_START_CAPACITY; + char *buffer = malloc(capacity); + assert(NULL != buffer); + + int c; + while ((c = getchar()) != EOF) { + if (capacity < len + 1) { + capacity *= 2; + buffer = realloc(buffer, capacity); + assert(NULL != buffer); + } + if ('\n' == c) { + if (fsa_accepts(&dfa, buffer, len)) { + buffer[len++] = '\n'; + fwrite(buffer, 1, len, stdout); + } + len = 0; + } else { + buffer[len++] = c; + } + } + + fsa_free(&dfa); + free(buffer); + return EXIT_SUCCESS; +}