| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef COMMAND_RUN_H | ||
| 2 | #define COMMAND_RUN_H | ||
| 3 | |||
| 4 | #include <stdbool.h> | ||
| 5 | #include <stddef.h> | ||
| 6 | #include <stdint.h> | ||
| 7 | #include <string.h> | ||
| 8 | #include "error.h" | ||
| 9 | #include "util/macros.h" | ||
| 10 | #include "util/string-view.h" | ||
| 11 | |||
| 12 | typedef uint_least64_t CommandFlagSet; | ||
| 13 | |||
| 14 | typedef struct { | ||
| 15 | char **args; // Positional args, with flag args moved to the front | ||
| 16 | size_t nr_args; // Number of args (not including flag args) | ||
| 17 | CommandFlagSet flag_set; // Bitset of used flags | ||
| 18 | char flags[14]; // Flags in parsed order | ||
| 19 | uint8_t nr_flags; // Number of parsed flags | ||
| 20 | uint8_t nr_flag_args; // Number of flag args | ||
| 21 | } CommandArgs; | ||
| 22 | |||
| 23 | // A set of flags associated with a Command that define how it may be | ||
| 24 | // used in certain contexts (completely unrelated to CommandArgs::flags | ||
| 25 | // or Command::flags, despite the terminology being somewhat ambiguous) | ||
| 26 | typedef enum { | ||
| 27 | CMDOPT_ALLOW_IN_RC = 1 << 0, // Allow command in rc files | ||
| 28 | CMDOPT_NO_FLAGS_AFTER_ARGS = 1 << 1, // Stop parsing flags after first positional arg | ||
| 29 | } CommandOptions; | ||
| 30 | |||
| 31 | struct EditorState; | ||
| 32 | |||
| 33 | typedef bool (*CommandFunc)(struct EditorState *e, const CommandArgs *args); | ||
| 34 | |||
| 35 | typedef struct { | ||
| 36 | const char name[15]; | ||
| 37 | const char flags[14]; | ||
| 38 | uint8_t cmdopts; // CommandOptions | ||
| 39 | uint8_t min_args; | ||
| 40 | uint8_t max_args; // 0xFF here means "no limit" (effectively SIZE_MAX) | ||
| 41 | CommandFunc cmd; | ||
| 42 | } Command; | ||
| 43 | |||
| 44 | typedef struct { | ||
| 45 | const Command* (*lookup)(const char *name); | ||
| 46 | void (*macro_record)(struct EditorState *e, const Command *cmd, char **args); | ||
| 47 | } CommandSet; | ||
| 48 | |||
| 49 | typedef enum { | ||
| 50 | CMDRUNNER_ALLOW_RECORDING = 1u << 0, | ||
| 51 | CMDRUNNER_EXPAND_TILDE_SLASH = 1u << 1, | ||
| 52 | CMDRUNNER_STOP_AT_FIRST_ERROR = 1u << 2, | ||
| 53 | } CommandRunnerFlags; | ||
| 54 | |||
| 55 | typedef struct { | ||
| 56 | const CommandSet *cmds; | ||
| 57 | const char* (*lookup_alias)(const struct EditorState *e, const char *name); | ||
| 58 | char* (*expand_variable)(const struct EditorState *e, const char *name); | ||
| 59 | const StringView *home_dir; // Used by parse_command_arg(); for expanding ~/ | ||
| 60 | struct EditorState *e; // Passed to the above function pointers | ||
| 61 | ErrorBuffer *ebuf; // Used by parse_args(), handle_command(), exec_config() | ||
| 62 | unsigned int recursion_count; // Used by run_commands(); to limit alias recursion | ||
| 63 | CommandRunnerFlags flags; | ||
| 64 | } CommandRunner; | ||
| 65 | |||
| 66 | 52564 | static inline int command_cmp(const void *key, const void *elem) | |
| 67 | { | ||
| 68 | 52564 | const char *name = key; | |
| 69 | 52564 | const Command *cmd = elem; | |
| 70 | 52564 | return strcmp(name, cmd->name); | |
| 71 | } | ||
| 72 | |||
| 73 | 8939 | static inline bool command_func_call ( | |
| 74 | struct EditorState *e, | ||
| 75 | ErrorBuffer *ebuf, | ||
| 76 | const Command *cmd, | ||
| 77 | const CommandArgs *args | ||
| 78 | ) { | ||
| 79 | 8939 | const char *saved_cmd_name = ebuf->command_name; | |
| 80 | 8939 | ebuf->command_name = cmd->name; | |
| 81 | 8939 | bool r = cmd->cmd(e, args); | |
| 82 | 8939 | ebuf->command_name = saved_cmd_name; | |
| 83 | 8939 | return r; | |
| 84 | } | ||
| 85 | |||
| 86 | bool handle_command(CommandRunner *runner, const char *cmd) NONNULL_ARGS; | ||
| 87 | |||
| 88 | #endif | ||
| 89 |