Find the appropriate entry for long options

This commit is contained in:
Nick Chambers 2022-06-19 00:13:49 -05:00
parent c9ee108cd5
commit 9dfca6f3c1
8 changed files with 109 additions and 22 deletions

View File

@ -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

View File

@ -1,22 +1,10 @@
#ifndef __GARGOYLE_H_
#define __GARGOYLE_H_
#include <gargoyle/codex.h>
#include <gargoyle/sleuth.h>
#include <stdint.h>
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

10
include/gargoyle/codex.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __GARGOYLE_CODEX_H_
#define __GARGOYLE_CODEX_H_
#include <stdint.h>
const uint8_t GARGOYLE_ERR_SUCCESS = 0;
const uint8_t GARGOYLE_ERR_RESERVED = 1;
const uint8_t GARGOYLE_ERR_UNKNOWN_OPT = 2;
#endif

26
include/gargoyle/sleuth.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef __GARGOYLE_SLEUTH_H_
#define __GARGOYLE_SLEUTH_H_
#include <stdint.h>
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

12
include/gargoyle/twine.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef __GARGOYLE_TWINE_H_
#define __GARGOYLE_TWINE_H_
#include <stdint.h>
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

View File

@ -1,18 +1,32 @@
#include <gargoyle.h>
#include <stddef.h>
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;
}

13
src/sleuth.c Normal file
View File

@ -0,0 +1,13 @@
#include <gargoyle/sleuth.h>
#include <gargoyle/twine.h>
#include <stddef.h>
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;
}

24
src/twine.c Normal file
View File

@ -0,0 +1,24 @@
#include <ctype.h>
#include <gargoyle/twine.h>
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;
}