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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#ifndef L2SU_COMMAND_H_INCLUDED
#define L2SU_COMMAND_H_INCLUDED
#include <stddef.h>
/* for CMD_ macros */
#include <stdlib.h>
#include <string.h>
#include <errno.h>
enum {
CMD_NODE_TYPE_NULL,
CMD_NODE_TYPE_LITERAL,
CMD_NODE_TYPE_ARGUMENT,
CMD_NODE_FLAG_EXEC = 0x100
};
enum {
CMD_INIT_SUCCESS,
CMD_INIT_ERROR
};
enum {
CMD_RESULT_SUCCESS,
CMD_RESULT_FAIL
};
enum {
CMD_VALIDATE_PASS, /* yep this argument is correct */
CMD_VALIDATE_FAIL_SKIP, /* this argument is NOT correct */
CMD_VALIDATE_FAIL_ERROR /* this argument IS the correct argument, but it is invalid (stop searching siblings) */
};
enum {
CMD_PARSE_SUCCESS, /* parse successful */
CMD_PARSE_ESYNTAX, /* invalid command syntax */
CMD_PARSE_EUSAGE /* function was called with NULL arguments */
};
#define CMD_FATAL_(_op) do { \
_op; \
exit(EXIT_FAILURE); \
} while (0)
#define CMD_MSG(_l, _s, ...) fprintf(stderr, _l ": " _s "\n", __VA_ARGS__)
#define CMD_MSG0(_l, _s) fputs(_l ": " _s "\n", stderr);
#define CMD_FATAL(_s, ...) CMD_FATAL_(CMD_MSG("fatal", _s, __VA_ARGS__))
#define CMD_FATAL0(_s) CMD_FATAL_(CMD_MSG0("fatal", _s))
#define CMD_ERROR(_s, ...) CMD_MSG("error", _s, __VA_ARGS__)
#define CMD_ERROR0(_s) CMD_MSG0("error", _s)
#define CMD_WARN(_s, ...) CMD_MSG("warn", _s, __VA_ARGS__)
#define CMD_WARN0(_s) CMD_MSG0("warn", _s)
#define CMD_MSG_UNKNOWN_ARGUMENT "Unknown argument '%s'."
#define CMD_MSG_REQ_ARG_UNSPECIFIED "Required argument '%s' not specified."
#define CMD_MSG_INVALID_UUID "Invalid UUID '%s'."
#define CMD_MSG_ALLOCATION_FAILED "Allocation failed."
struct l2_command_node;
struct l2_context_node {
struct l2_context_node *next;
struct l2_command_node *node;
char *value; /* for argument command nodes */
};
typedef unsigned (l2_cmd_proc_t)(struct l2_context_node * /* ctx */, char ** /* args */);
typedef unsigned (l2_cmd_validate_proc_t)(const char * /* arg */);
struct l2_command_node {
unsigned type;
const char *name;
union {
/* for literal nodes */
const char **aliases;
/* for argument nodes */
l2_cmd_validate_proc_t *validate_proc; /* a validate_proc of NULL is assumed to always return CMD_VALIDATE_PASS */
} extra;
l2_cmd_proc_t *cmd_proc;
struct l2_command_node *children;
};
extern struct l2_command_node l2_cmd_root;
/* unsigned l2_cmd_init(void); */
struct l2_parseinfo {
char **argv;
l2_cmd_proc_t *proc;
struct l2_context_node *ctx;
};
unsigned l2_cmd_parse_command(char **argv, struct l2_parseinfo *parseinfo);
void l2_cmd_free_ctx(struct l2_context_node *ctx);
/* DESCRIPTION:
* This function is for unpacking a bunch of arguments from a parsed command into
* string variables.
*
* HOW TO USE:
* Pass your command context followed by your arguments (const char *name, char **pvalue).
* Prefix the name with "#" if it is optional.
*
* This function will exit if a required value was not present.
*
* Example: l2_cmd_collect_args(ctx, 2, "name", &name, "#location", &path);
*/
void l2_cmd_collect_args(struct l2_context_node *ctx, unsigned argc, ...);
#endif /* include guard */
|