From e1849a06557846f5fad77ada36d959a258f2c3dd Mon Sep 17 00:00:00 2001 From: Randy Jordan Date: Fri, 3 Jul 2026 10:43:46 -0500 Subject: [PATCH] Initial commit --- LICENSE.md | 21 ++++++++ README.md | 45 ++++++++++++++++ spp.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++ spp.h | 53 +++++++++++++++++++ 4 files changed, 270 insertions(+) create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 spp.c create mode 100644 spp.h diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..074265c --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [2026] [Randy Jordan] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..80057c9 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# spp + +## Description +spp - single pass parser. + +## Table of Contents + +* [Features](#features) +* [Todos](#todos) +* [Usage](#usage) +* [Acknowledgments](#acknowledgments) +* [License](#license) + + +## Features + +## Todos + +## Usage + +```c +int main(void) +{ + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + const char* path = argv[1]; + const char* buffer = read_file_into_mem(path); + + struct SPP_Stream stream = { .cursor = &buffer }; + line_count(stream, path); + + return EXIT_SUCCESS; +} + +``` + +## Acknowledgments + + +## License +This project is licensed under the MIT License - see the [MIT License](LICENSE.md) file for details. + diff --git a/spp.c b/spp.c new file mode 100644 index 0000000..ec020b6 --- /dev/null +++ b/spp.c @@ -0,0 +1,151 @@ +/* - | Copyright | ------------------------------------------------------------ + Copyright (c) 2026 Randy Jordan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * --------------------------------------------------------------------------*/ +#include "spp.h" +#include +#include +#include +#include + +static char* +read_file_into_mem(const char* path) +{ + FILE* file = fopen(path, "rb"); + if (file == NULL) { + fprintf(stderr, "Could not open file \"%s\".\n", path); + exit(74); + } + + fseek(file, 0L, SEEK_END); + size_t fileSize = ftell(file); + rewind(file); + + char* buffer = (char*)malloc(fileSize + 1); + if (buffer == NULL) { + fprintf(stderr, "Not enough memory to read \"%s\".\n", path); + exit(74); + } + + size_t bytesRead = fread(buffer, sizeof(char), fileSize, file); + if (bytesRead < fileSize) { + fprintf(stderr, "Could not read file \"%s\".\n", path); + exit(74); + } + + buffer[bytesRead] = '\0'; + fclose(file); + return buffer; +} + +static size_t +line_count(const struct SPP_Stream s, const char* path) +{ + + size_t lines = 0; + while (!spp_eof(s)) { + if (spp_is(s, "\n")) { + lines++; + printf("%s - Line Count: %lld\r", path, lines); + fflush(stdout); + (*s.cursor)++; + + } else { + (*s.cursor)++; + } + } + printf("%s - Line Count: %lld\n", path, lines); + fflush(stdout); + return lines; +} + +bool +spp_is(const struct SPP_Stream s, const char* list) +{ + assert(list != NULL); + assert(s.cursor != NULL && *s.cursor != NULL); + + return strchr(list, **s.cursor); +} + +bool +spp_eof(const struct SPP_Stream s) +{ + assert(s.cursor != NULL && *s.cursor != NULL); + + return **s.cursor == 0; +} + +char +spp_take(const struct SPP_Stream s, const char* list) +{ + if (!spp_is(s, list)) + return 0; + + const char r = **s.cursor; + (*s.cursor)++; + return r; +} + +size_t +spp_skip(const struct SPP_Stream s, const char* list) +{ + size_t size = 0; + for (; !spp_eof(s) && spp_is(s, list); size++) { + (*s.cursor)++; + } + + return size; +} + +size_t +spp_until(const struct SPP_Stream s, const char* list) +{ + size_t size = 0; + for (; !spp_eof(s) && !spp_is(s, list); size++) { + (*s.cursor)++; + } + + return size; +} + +const char* +spp_cursor(struct SPP_Stream s) +{ + return *s.cursor; +} + +int +main(int argc, char* argv[]) +{ + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + const char* path = argv[1]; + const char* buffer = read_file_into_mem(path); + + struct SPP_Stream stream = { .cursor = &buffer }; + line_count(stream, path); + + return EXIT_SUCCESS; +} diff --git a/spp.h b/spp.h new file mode 100644 index 0000000..c5d7257 --- /dev/null +++ b/spp.h @@ -0,0 +1,53 @@ +/* - | Copyright | ------------------------------------------------------------ + Copyright (c) 2026 Randy Jordan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * --------------------------------------------------------------------------*/ +#ifndef SPP_H +#define SPP_H + +#include +#include + +struct SPP_Stream +{ + const char** cursor; +}; +typedef struct SPP_Stream SPP_Stream; + +extern bool +spp_is(struct SPP_Stream s, const char* list); + +extern bool +spp_eof(struct SPP_Stream s); + +extern char +spp_take(struct SPP_Stream s, const char* list); + +extern size_t +spp_skip(struct SPP_Stream s, const char* list); + +extern size_t +spp_until(struct SPP_Stream s, const char* list); + +extern const char* +spp_cursor(struct SPP_Stream s); + +#endif // spp.h