~lattis/muon

ref: 1c1ab113103e1a2ebcb7edf3a47f826428f8e124 muon/include/opts.h -rw-r--r-- 1.5 KiB
1c1ab113Stone Tickle extract string.split() 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef MUON_OPTS_H
#define MUON_OPTS_H

#include <stdio.h>

#include "lang/workspace.h"

/* OPTSTART should be pretty self-explanatory.  You just pass it the optstring
 * that you would pass to getopt().  "h" is added to this optstring for you.
 *
 * OPTEND is a little bit more involved, the first 4 arguments are used to
 * construct the help message, while the 5th argument should be the number of
 * required operands for this subcommand, or -1 which disables the check.
 */
#define OPTSTART(optstring) \
	signed char opt; \
	optind = 1; \
	while ((opt = getopt(argc - argi, &argv[argi], optstring "h")) != -1) { \
		switch (opt) {
#define OPTEND(usage_pre, usage_post, usage_opts, commands, operands) \
case 'h': \
	print_usage(stdout, commands, usage_pre, usage_opts, usage_post); \
	exit(0); \
	break; \
default: \
	print_usage(stderr, commands, usage_pre, usage_opts, usage_post); \
	return false; \
} \
} \
	if (!check_operands(argc, (argi + optind), operands)) { \
	print_usage(stderr, commands, usage_pre, usage_opts, usage_post); \
	return false; \
	} \
	argi += optind;

typedef bool (*cmd_func)(uint32_t argc, uint32_t argi, char *const[]);

struct command {
	const char *name;
	cmd_func cmd;
	const char *desc;
};

void print_usage(FILE *f, const struct command *commands,
	const char *pre, const char *opts, const char *post);
bool find_cmd(const struct command *commands, cmd_func *ret,
	uint32_t argc, uint32_t argi, char *const argv[], bool optional);
bool check_operands(uint32_t argc, uint32_t argi, int32_t expected);
#endif