Find the appropriate entry for long options
This commit is contained in:
parent
c9ee108cd5
commit
9dfca6f3c1
8 changed files with 109 additions and 22 deletions
2
Makefile
2
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
|
||||
|
||||
|
|
|
@ -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
10
include/gargoyle/codex.h
Normal 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
26
include/gargoyle/sleuth.h
Normal 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
12
include/gargoyle/twine.h
Normal 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
|
|
@ -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
13
src/sleuth.c
Normal 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
24
src/twine.c
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue