#ifndef L2SU_COMMAND_H_INCLUDED #define L2SU_COMMAND_H_INCLUDED #include /* for CMD_ macros */ #include #include #include 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 */