From 9dfca6f3c190ffc565a963d4d0d9dfe875f60fc2 Mon Sep 17 00:00:00 2001 From: Nick Chambers Date: Sun, 19 Jun 2022 00:13:49 -0500 Subject: [PATCH] Find the appropriate entry for long options --- Makefile | 2 +- include/gargoyle.h | 18 +++--------------- include/gargoyle/codex.h | 10 ++++++++++ include/gargoyle/sleuth.h | 26 ++++++++++++++++++++++++++ include/gargoyle/twine.h | 12 ++++++++++++ src/gargoyle.c | 26 ++++++++++++++++++++------ src/sleuth.c | 13 +++++++++++++ src/twine.c | 24 ++++++++++++++++++++++++ 8 files changed, 109 insertions(+), 22 deletions(-) create mode 100644 include/gargoyle/codex.h create mode 100644 include/gargoyle/sleuth.h create mode 100644 include/gargoyle/twine.h create mode 100644 src/sleuth.c create mode 100644 src/twine.c diff --git a/Makefile b/Makefile index 00a6bcc..d35a504 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CFLAGS ?= -Wall -Wextra -g -O1 -fpic LDFLAGS ?= -g -O1 -shared -GARGOYLE_OBJS := gargoyle +GARGOYLE_OBJS := gargoyle sleuth twine .PHONY: all gargoyle init docs test clean diff --git a/include/gargoyle.h b/include/gargoyle.h index b8b304a..9e7698a 100644 --- a/include/gargoyle.h +++ b/include/gargoyle.h @@ -1,22 +1,10 @@ #ifndef __GARGOYLE_H_ #define __GARGOYLE_H_ +#include +#include #include -const uint8_t GARGOYLE_TYPE_UINT = 1 << 0; -const uint8_t GARGOYLE_TYPE_BOOL = 1 << 1; -const uint8_t GARGOYLE_TYPE_FILE = 1 << 2; -const uint8_t GARGOYLE_TYPE_ROPE = 1 << 3; -const uint8_t GARGOYLE_TYPE_DBLE = 1 << 4; - -struct gargoyle_opt { - const char *brand; - uint16_t length; - const char emblem; - void *value; - uint8_t type; -}; - -uint8_t gargoyle_digest(struct gargoyle_opt *args, uint16_t *argc, const char ***argv); +uint8_t gargoyle_digest(uint16_t optc, struct gargoyle_opt *optv, int *argc, char ***argv); #endif diff --git a/include/gargoyle/codex.h b/include/gargoyle/codex.h new file mode 100644 index 0000000..00a187e --- /dev/null +++ b/include/gargoyle/codex.h @@ -0,0 +1,10 @@ +#ifndef __GARGOYLE_CODEX_H_ +#define __GARGOYLE_CODEX_H_ + +#include + +const uint8_t GARGOYLE_ERR_SUCCESS = 0; +const uint8_t GARGOYLE_ERR_RESERVED = 1; +const uint8_t GARGOYLE_ERR_UNKNOWN_OPT = 2; + +#endif diff --git a/include/gargoyle/sleuth.h b/include/gargoyle/sleuth.h new file mode 100644 index 0000000..b88dbd3 --- /dev/null +++ b/include/gargoyle/sleuth.h @@ -0,0 +1,26 @@ +#ifndef __GARGOYLE_SLEUTH_H_ +#define __GARGOYLE_SLEUTH_H_ + +#include + +static const uint8_t GARGOYLE_TYPE_UINT = 1 << 0; +static const uint8_t GARGOYLE_TYPE_BOOL = 1 << 1; +static const uint8_t GARGOYLE_TYPE_FILE = 1 << 2; +static const uint8_t GARGOYLE_TYPE_ROPE = 1 << 3; +static const uint8_t GARGOYLE_TYPE_DBLE = 1 << 4; + +struct gargoyle_opt { + const char *brand; + uint16_t brand_sz; + const char emblem; + void *val; + uint16_t val_sz; + uint8_t type; +}; + +#define GARGOYLE_MK_OPT(brand) brand, (sizeof(brand) - 1) +#define GARGOYLE_EZ_OPT(brand) brand, (sizeof(brand) - 1), 0[brand] // >:) + +struct gargoyle_opt *gargoyle_find_brand(uint16_t optc, struct gargoyle_opt *optv, const char *brand); + +#endif diff --git a/include/gargoyle/twine.h b/include/gargoyle/twine.h new file mode 100644 index 0000000..30757d8 --- /dev/null +++ b/include/gargoyle/twine.h @@ -0,0 +1,12 @@ +#ifndef __GARGOYLE_TWINE_H_ +#define __GARGOYLE_TWINE_H_ + +#include + +static const uint8_t GARGOYLE_CMP_ICASE = 1 << 0; +static const uint8_t GARGOYLE_CMP_SYMBL = 1 << 1; +static const uint8_t GARGOYLE_CMP_FLXBL = GARGOYLE_CMP_ICASE | GARGOYLE_CMP_SYMBL; + +uint8_t gargoyle_cmp(const char *s1, const char *s2, uint16_t len, uint8_t flags); + +#endif diff --git a/src/gargoyle.c b/src/gargoyle.c index aa30240..298e4d5 100644 --- a/src/gargoyle.c +++ b/src/gargoyle.c @@ -1,18 +1,32 @@ #include +#include -uint8_t gargoyle_digest(struct gargoyle_opt *args, uint16_t *argc, const char ***argv) { - uint8_t parsing = 1; +uint8_t gargoyle_digest(uint16_t optc, struct gargoyle_opt *optv, int *argc, char ***argv) { + uint8_t status = 1; - while(parsing) { + while(status) { const char *arg = **argv; if(!arg || *arg != '-' || !*(arg + 1)) { - parsing = 0; + status = 0; break; } else if(*arg == '-' && *(arg + 1) == '-' && !*(arg + 2)) { *argc -= 1; *argv += 1; - parsing = 0; + status = 0; + break; + } + + struct gargoyle_opt *opt = NULL; + + if(*(arg + 1) == '-') { + opt = gargoyle_find_brand(optc, optv, arg + 2); + } else { + /* loop through short opts */ + } + + if(!opt) { + status = GARGOYLE_ERR_UNKNOWN_OPT; break; } @@ -20,5 +34,5 @@ uint8_t gargoyle_digest(struct gargoyle_opt *args, uint16_t *argc, const char ** *argv += 1; } - return parsing; + return status; } diff --git a/src/sleuth.c b/src/sleuth.c new file mode 100644 index 0000000..a42267b --- /dev/null +++ b/src/sleuth.c @@ -0,0 +1,13 @@ +#include +#include +#include + +struct gargoyle_opt *gargoyle_find_brand(uint16_t optc, struct gargoyle_opt *optv, const char *brand) { + for(; optc; optc -= 1, optv += 1) { + if(gargoyle_cmp(brand, optv->brand, optv->brand_sz, GARGOYLE_CMP_FLXBL)) { + return optv; + } + } + + return NULL; +} diff --git a/src/twine.c b/src/twine.c new file mode 100644 index 0000000..19a095a --- /dev/null +++ b/src/twine.c @@ -0,0 +1,24 @@ +#include +#include + +static uint8_t is_sep(char tok) { + return (tok == '_' || tok == '-'); +} + +uint8_t gargoyle_cmp(const char *s1, const char *s2, uint16_t len, uint8_t flags) { + while(*s1 && *s2 && len) { + if(flags & GARGOYLE_CMP_ICASE && isalpha(*s1) && tolower(*s1) == tolower(*s2)) { + s1 += 1, s2 += 1; + } else if(flags & GARGOYLE_CMP_SYMBL && is_sep(*s1) && is_sep(*s2)) { + s1 += 1, s2 += 1; + } else if(*s1 == *s2) { + s1 += 1, s2 += 1; + } else { + return 0; + } + + len -= 1; + } + + return *s1 == *s2; +} \ No newline at end of file