03b01d2 |
Jamozed |
2022-03-06 17:10:01 |
0
|
// util/optget.h, version 1.6.2 |
c01a723 |
Jamozed |
2022-02-05 19:04:03 |
1
|
// optget source file from libutil |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
2
|
// Copyright (C) 2020, Jakob Wakeling |
03b01d2 |
Jamozed |
2022-03-06 17:10:01 |
3
|
// MIT Licence |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
4
|
|
40437ba |
Jamozed |
2020-08-28 23:41:53 |
5
|
#include "error.h" |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
6
|
#include "optget.h" |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
7
|
|
40437ba |
Jamozed |
2020-08-28 23:41:53 |
8
|
#include <stddef.h> |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
9
|
#include <stdio.h> |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
10
|
#include <string.h> |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
11
|
|
40437ba |
Jamozed |
2020-08-28 23:41:53 |
12
|
#define cur av[opt->ind] |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
13
|
|
40437ba |
Jamozed |
2020-08-28 23:41:53 |
14
|
const struct opt OPTGET_INIT = { 1, 0, 1, 0, NULL, NULL, NULL, NULL }; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
15
|
|
40437ba |
Jamozed |
2020-08-28 23:41:53 |
16
|
static inline void permute(char **av, int i, int n); |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
17
|
|
40437ba |
Jamozed |
2020-08-28 23:41:53 |
18
|
int optget(struct opt *opt, char *av[], int flags) { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
19
|
if (flags & 1) { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
20
|
for (; cur && (cur[0] != '-' || cur[1] == 0); ++opt->ind, ++opt->nop); |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
21
|
if (!cur) { opt->ind -= opt->nop; opt->nop = 0; return -1; } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
22
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
23
|
else if (!cur || (cur[0] != '-' || cur[1] == 0)) { return -1; } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
24
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
25
|
int optind = opt->ind, optret; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
26
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
27
|
if (cur[1] == '-') { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
28
|
if (cur[2] == 0) { if (opt->nop) { |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
29
|
permute(av, opt->ind++, opt->nop); |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
30
|
opt->ind -= opt->nop; opt->nop = 0; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
31
|
} else { ++opt->ind; } return -1; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
32
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
33
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
34
|
int optend, lop; optret = '?'; opt->opt = 0; opt->lop = cur; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
35
|
if (!opt->lops) { goto nol; } |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
36
|
for (optend = 2; cur[optend] != '=' && cur[optend] != 0; ++optend); |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
37
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
38
|
for (lop = 0; opt->lops[lop].str; ++lop) { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
39
|
if (strncmp(&cur[2], opt->lops[lop].str, (size_t)optend - 2) == 0) { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
40
|
if (!opt->lops[lop].str[optend - 2]) { |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
41
|
optret = opt->opt = opt->lops[lop].val; break; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
42
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
43
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
44
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
45
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
46
|
if (opt->lops[lop].arg > ARG_NUL) { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
47
|
if (cur[optend]) { opt->arg = &cur[optend + 1]; } |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
48
|
else if (av[opt->ind + 1]) { opt->arg = av[++opt->ind]; } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
49
|
else { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
50
|
if (opt->lops[lop].arg == ARG_REQ) { optret = ':'; } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
51
|
opt->arg = NULL; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
52
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
53
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
54
|
else { opt->arg = NULL; } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
55
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
56
|
nol: opt->pos = 0; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
57
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
58
|
else { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
59
|
optret = opt->opt = cur[opt->pos++]; opt->lop = NULL; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
60
|
const char *optchr = strchr(opt->str, opt->opt); |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
61
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
62
|
if (!optchr) { optret = '?'; } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
63
|
else if (optchr[1] == ':') { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
64
|
if (cur[opt->pos]) { opt->arg = &cur[opt->pos]; } |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
65
|
else if (av[opt->ind + 1]) { opt->arg = av[++opt->ind]; } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
66
|
else { opt->arg = NULL; optret = ':'; } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
67
|
opt->pos = 0; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
68
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
69
|
else { opt->arg = NULL; } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
70
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
71
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
72
|
if (!opt->pos || !cur[opt->pos]) { |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
73
|
++opt->ind; opt->pos = 1; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
74
|
if (opt->nop) for (; optind < opt->ind; ++optind) { |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
75
|
permute(av, optind, opt->nop); |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
76
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
77
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
78
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
79
|
if (optret == '?' && opt->str[0] != ':') { |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
80
|
if (opt->opt) { warn("%c: invalid option", opt->opt); } |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
81
|
else if (opt->lop) { warn("%s: invalid option", opt->lop); } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
82
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
83
|
if (optret == ':' && opt->str[0] != ':') { |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
84
|
if (opt->opt) { warn("%c: option requires argument", opt->opt); } |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
85
|
else if (opt->lop) { warn("%s: option requires argument", opt->lop); } |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
86
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
87
|
|
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
88
|
return optret; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
89
|
} |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
90
|
|
40437ba |
Jamozed |
2020-08-28 23:41:53 |
91
|
static inline void permute(char **av, int i, int n) { |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
92
|
char *a = av[i]; memmove(&av[i - n + 1], &av[i - n], n * sizeof (av)); |
40437ba |
Jamozed |
2020-08-28 23:41:53 |
93
|
av[i - n] = a; return; |
1373e97 |
Jamozed |
2020-07-25 12:36:45 |
94
|
} |
|
|
|
95
|
|