mirror of https://github.com/attractivechaos/klib
revert to a single-header library
This commit is contained in:
parent
c3ff4d3a1b
commit
24557595f2
74
ketopt.c
74
ketopt.c
|
@ -1,74 +0,0 @@
|
|||
#include <string.h> /* for strchr() and strncmp() */
|
||||
#include "ketopt.h"
|
||||
|
||||
ketopt_t KETOPT_INIT = { 1, 0, 0, -1, 1, 0, 0 };
|
||||
|
||||
static void ketopt_permute(char *argv[], int j, int n) /* move argv[j] over n elements to the left */
|
||||
{
|
||||
int k;
|
||||
char *p = argv[j];
|
||||
for (k = 0; k < n; ++k)
|
||||
argv[j - k] = argv[j - k - 1];
|
||||
argv[j - k] = p;
|
||||
}
|
||||
|
||||
/* WARNING: O(mn) algorithm; m=#main arguments before options; n=#options after main arguments; no trial fix */
|
||||
int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *ostr, const ko_longopt_t *longopts)
|
||||
{
|
||||
int opt = -1, i0, j;
|
||||
if (permute) {
|
||||
while (s->i < argc && (argv[s->i][0] != '-' || argv[s->i][1] == '\0'))
|
||||
++s->i, ++s->n_args;
|
||||
}
|
||||
s->arg = 0, s->longidx = -1, i0 = s->i;
|
||||
if (s->i >= argc || argv[s->i][0] != '-' || argv[s->i][1] == '\0') {
|
||||
s->ind = s->i - s->n_args;
|
||||
return -1;
|
||||
}
|
||||
if (argv[s->i][0] == '-' && argv[s->i][1] == '-') { /* "--" or a long option */
|
||||
if (argv[s->i][2] == '\0') { /* a bare "--" */
|
||||
ketopt_permute(argv, s->i, s->n_args);
|
||||
++s->i, s->ind = s->i - s->n_args;
|
||||
return -1;
|
||||
}
|
||||
s->opt = 0, opt = '?', s->pos = -1;
|
||||
if (longopts) { /* parse long options */
|
||||
int k, n_matches = 0;
|
||||
const ko_longopt_t *o = 0;
|
||||
for (j = 2; argv[s->i][j] != '\0' && argv[s->i][j] != '='; ++j) {} /* find the end of the option name */
|
||||
for (k = 0; longopts[k].name != 0; ++k)
|
||||
if (strncmp(&argv[s->i][2], longopts[k].name, j - 2) == 0)
|
||||
++n_matches, o = &longopts[k];
|
||||
if (n_matches == 1) {
|
||||
s->opt = opt = o->val, s->longidx = o - longopts;
|
||||
if (argv[s->i][j] == '=') s->arg = &argv[s->i][j + 1];
|
||||
if (o->has_arg == 1 && argv[s->i][j] == '\0') {
|
||||
if (s->i < argc - 1) s->arg = argv[++s->i];
|
||||
else opt = ':'; /* missing option argument */
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* a short option */
|
||||
char *p;
|
||||
if (s->pos == 0) s->pos = 1;
|
||||
opt = s->opt = argv[s->i][s->pos++];
|
||||
p = strchr(ostr, opt);
|
||||
if (p == 0) {
|
||||
opt = '?'; /* unknown option */
|
||||
} else if (p[1] == ':') {
|
||||
if (argv[s->i][s->pos] == 0) {
|
||||
if (s->i < argc - 1) s->arg = argv[++s->i];
|
||||
else opt = ':'; /* missing option argument */
|
||||
} else s->arg = &argv[s->i][s->pos];
|
||||
s->pos = -1;
|
||||
}
|
||||
}
|
||||
if (s->pos < 0 || argv[s->i][s->pos] == 0) {
|
||||
++s->i, s->pos = 0;
|
||||
if (s->n_args > 0) /* permute */
|
||||
for (j = i0; j < s->i; ++j)
|
||||
ketopt_permute(argv, j, s->n_args);
|
||||
}
|
||||
s->ind = s->i - s->n_args;
|
||||
return opt;
|
||||
}
|
77
ketopt.h
77
ketopt.h
|
@ -1,6 +1,8 @@
|
|||
#ifndef KETOPT_H
|
||||
#define KETOPT_H
|
||||
|
||||
#include <string.h> /* for strchr() and strncmp() */
|
||||
|
||||
#define ko_no_argument 0
|
||||
#define ko_required_argument 1
|
||||
#define ko_optional_argument 2
|
||||
|
@ -20,11 +22,16 @@ typedef struct {
|
|||
int val;
|
||||
} ko_longopt_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
static ketopt_t KETOPT_INIT = { 1, 0, 0, -1, 1, 0, 0 };
|
||||
|
||||
extern ketopt_t KETOPT_INIT;
|
||||
static void ketopt_permute(char *argv[], int j, int n) /* move argv[j] over n elements to the left */
|
||||
{
|
||||
int k;
|
||||
char *p = argv[j];
|
||||
for (k = 0; k < n; ++k)
|
||||
argv[j - k] = argv[j - k - 1];
|
||||
argv[j - k] = p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse command-line options and arguments
|
||||
|
@ -46,10 +53,64 @@ extern ketopt_t KETOPT_INIT;
|
|||
* argv[] is fully processed; '?' for an unknown option or an ambiguous
|
||||
* long option; ':' if an option argument is missing
|
||||
*/
|
||||
int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *ostr, const ko_longopt_t *longopts);
|
||||
|
||||
#ifdef __cplusplus
|
||||
static int ketopt(ketopt_t *s, int argc, char *argv[], int permute, const char *ostr, const ko_longopt_t *longopts)
|
||||
{
|
||||
int opt = -1, i0, j;
|
||||
if (permute) {
|
||||
while (s->i < argc && (argv[s->i][0] != '-' || argv[s->i][1] == '\0'))
|
||||
++s->i, ++s->n_args;
|
||||
}
|
||||
s->arg = 0, s->longidx = -1, i0 = s->i;
|
||||
if (s->i >= argc || argv[s->i][0] != '-' || argv[s->i][1] == '\0') {
|
||||
s->ind = s->i - s->n_args;
|
||||
return -1;
|
||||
}
|
||||
if (argv[s->i][0] == '-' && argv[s->i][1] == '-') { /* "--" or a long option */
|
||||
if (argv[s->i][2] == '\0') { /* a bare "--" */
|
||||
ketopt_permute(argv, s->i, s->n_args);
|
||||
++s->i, s->ind = s->i - s->n_args;
|
||||
return -1;
|
||||
}
|
||||
s->opt = 0, opt = '?', s->pos = -1;
|
||||
if (longopts) { /* parse long options */
|
||||
int k, n_matches = 0;
|
||||
const ko_longopt_t *o = 0;
|
||||
for (j = 2; argv[s->i][j] != '\0' && argv[s->i][j] != '='; ++j) {} /* find the end of the option name */
|
||||
for (k = 0; longopts[k].name != 0; ++k)
|
||||
if (strncmp(&argv[s->i][2], longopts[k].name, j - 2) == 0)
|
||||
++n_matches, o = &longopts[k];
|
||||
if (n_matches == 1) {
|
||||
s->opt = opt = o->val, s->longidx = o - longopts;
|
||||
if (argv[s->i][j] == '=') s->arg = &argv[s->i][j + 1];
|
||||
if (o->has_arg == 1 && argv[s->i][j] == '\0') {
|
||||
if (s->i < argc - 1) s->arg = argv[++s->i];
|
||||
else opt = ':'; /* missing option argument */
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* a short option */
|
||||
char *p;
|
||||
if (s->pos == 0) s->pos = 1;
|
||||
opt = s->opt = argv[s->i][s->pos++];
|
||||
p = strchr(ostr, opt);
|
||||
if (p == 0) {
|
||||
opt = '?'; /* unknown option */
|
||||
} else if (p[1] == ':') {
|
||||
if (argv[s->i][s->pos] == 0) {
|
||||
if (s->i < argc - 1) s->arg = argv[++s->i];
|
||||
else opt = ':'; /* missing option argument */
|
||||
} else s->arg = &argv[s->i][s->pos];
|
||||
s->pos = -1;
|
||||
}
|
||||
}
|
||||
if (s->pos < 0 || argv[s->i][s->pos] == 0) {
|
||||
++s->i, s->pos = 0;
|
||||
if (s->n_args > 0) /* permute */
|
||||
for (j = i0; j < s->i; ++j)
|
||||
ketopt_permute(argv, j, s->n_args);
|
||||
}
|
||||
s->ind = s->i - s->n_args;
|
||||
return opt;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,5 +62,5 @@ kthread_test:kthread_test.c ../kthread.c
|
|||
kthread_test2:kthread_test2.c ../kthread.c
|
||||
$(CC) $(CFLAGS) -o $@ kthread_test2.c ../kthread.c
|
||||
|
||||
ketopt_test:ketopt_test.c ../ketopt.c
|
||||
$(CC) $(CFLAGS) -o $@ ketopt_test.c ../ketopt.c
|
||||
ketopt_test:ketopt_test.c ../ketopt.h
|
||||
$(CC) $(CFLAGS) -o $@ ketopt_test.c
|
||||
|
|
Loading…
Reference in New Issue