OBFI

Brainfuck Interpreter
git clone http://git.omkov.net/OBFI
Log | Tree | Refs | README | LICENCE | Download

OBFI/src/util/optget.c (93 lines, 2.5 KiB) -rw-r--r-- file download

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