-
-
Notifications
You must be signed in to change notification settings - Fork 571
Expand file tree
/
Copy pathrz_cmd.h
More file actions
629 lines (588 loc) · 23.7 KB
/
Copy pathrz_cmd.h
File metadata and controls
629 lines (588 loc) · 23.7 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
#ifndef RZ_CMD_H
#define RZ_CMD_H
#include <rz_types.h>
#include <rz_util.h>
#include <rz_bind.h>
#ifdef __cplusplus
extern "C" {
#endif
// RZ_LIB_VERSION_HEADER (rz_cmd);
/**
* Value returned by a command handler.
*/
typedef enum rz_cmd_status_t {
RZ_CMD_STATUS_OK = 0, ///< command handler exited in the right way
RZ_CMD_STATUS_WRONG_ARGS, ///< command handler could not handle the arguments passed to it
RZ_CMD_STATUS_ERROR, ///< command handler had issues while running (e.g. allocation error, etc.)
RZ_CMD_STATUS_INVALID, ///< command could not be executed (e.g. shell level error, bad expression, etc.)
RZ_CMD_STATUS_NONEXISTINGCMD, ///< command does not exist
RZ_CMD_STATUS_EXIT, ///< command handler asks to exit the prompt loop
} RzCmdStatus;
/**
* Type of argument a command handler can have. This is used for visualization
* in help messages and for autocompletion as well.
*/
typedef enum rz_cmd_arg_type_t {
RZ_CMD_ARG_TYPE_FAKE, ///< This is not considered a real argument, just used to show something in the help. Name of arg is shown as-is and it is not counted.
RZ_CMD_ARG_TYPE_NUM, ///< Argument is a number
RZ_CMD_ARG_TYPE_RZNUM, ///< Argument that can be interpreted by RzNum (numbers, flags, operations, etc.)
RZ_CMD_ARG_TYPE_STRING, ///< Argument that can be an arbitrary string
RZ_CMD_ARG_TYPE_RAW, ///< Like RZ_CMD_ARG_TYPE_STRING, but unescaping and quote unwrapping is not done
RZ_CMD_ARG_TYPE_ENV, ///< Argument can be the name of an existing rizin variable
RZ_CMD_ARG_TYPE_CHOICES, ///< Argument can be one of the provided choices
RZ_CMD_ARG_TYPE_FCN, ///< Argument can be the name of an existing function
RZ_CMD_ARG_TYPE_FILE, ///< Argument is a filename
RZ_CMD_ARG_TYPE_OPTION, ///< Argument is an option, prefixed with `-`. It is present or not. No argument.
RZ_CMD_ARG_TYPE_CMD, ///< Argument is an rizin command
RZ_CMD_ARG_TYPE_MACRO, ///< Argument is the name of a pre-defined macro
RZ_CMD_ARG_TYPE_EVAL_KEY, ///< Argument is the name of a evaluable variable (e.g. `et` command)
RZ_CMD_ARG_TYPE_EVAL_FULL, ///< Argument is the name+(optional)value of a evaluable variable (e.g. `e` command)
RZ_CMD_ARG_TYPE_FCN_VAR, ///< Argument is the name of a function variable/argument
RZ_CMD_ARG_TYPE_FLAG, ///< Argument is a rizin flag
RZ_CMD_ARG_TYPE_ENUM_TYPE, ///< Argument is a C enum type name
RZ_CMD_ARG_TYPE_STRUCT_TYPE, ///< Argument is a C struct type name
RZ_CMD_ARG_TYPE_UNION_TYPE, ///< Argument is a C union type name
RZ_CMD_ARG_TYPE_ALIAS_TYPE, ///< Argument is a C typedef (alias) name
RZ_CMD_ARG_TYPE_CLASS_TYPE, ///< Argument is a C++/etc class name
RZ_CMD_ARG_TYPE_ANY_TYPE, ///< Argument is the any of the C or C++ type name
RZ_CMD_ARG_TYPE_GLOBAL_VAR, ///< Argument is a user defined global variable
RZ_CMD_ARG_TYPE_REG_FILTER, ///< Argument is a register name, size, type or "all"
RZ_CMD_ARG_TYPE_REG_TYPE, ///< Argument is a register type/arena like "gpr"
RZ_CMD_ARG_TYPE_FOLDER, ///< Argument is a directory or path
RZ_CMD_ARG_TYPE_PF_FORMAT_NAME, ///< Argument is the name of a `pf` named format (registered via `pfn`)
RZ_CMD_ARG_TYPE_PF_FORMAT_PATH, ///< Argument is a `pf` named format name optionally followed by `.<field>` (for `pf.` and `pfw`)
RZ_CMD_ARG_TYPE_PF_FDF_FILE, ///< Argument is the name of a Format Definition File (.fdf), looked up in the FDF search dirs
} RzCmdArgType;
/**
* Argument can contain spaces when it is the last of a command and it would
* be considered as a single argument by the command handler.
*/
#define RZ_CMD_ARG_FLAG_LAST (1 << 0)
/**
* Argument is an array of elements. It must be the last in the list of
* arguments of a command.
*/
#define RZ_CMD_ARG_FLAG_ARRAY (1 << 1)
/**
* Argument is an option, prefixed with `-`. It is present or not.
*/
#define RZ_CMD_ARG_FLAG_OPTION (1 << 2)
typedef enum rz_cmd_escape_t {
RZ_CMD_ESCAPE_ONE_ARG, ///< The string should be escaped so that it appears as one single argument
RZ_CMD_ESCAPE_MULTI_ARG, ///< The string should be escaped so that it appears as one or multiple arguments
RZ_CMD_ESCAPE_PF_ARG, ///< The string should be escaped so that it appears as one or multiple `pf` arguments
RZ_CMD_ESCAPE_DOUBLE_QUOTED_ARG, ///< The string should be escaped so that it can be wrapped in "...."
RZ_CMD_ESCAPE_SINGLE_QUOTED_ARG, ///< The string should be escaped so that it can be wrapped in '....'
} RzCmdEscape;
/**
* \brief Enum to describe the way data are printed
*/
typedef enum {
RZ_OUTPUT_MODE_STANDARD = 1 << 0,
RZ_OUTPUT_MODE_JSON = 1 << 1,
RZ_OUTPUT_MODE_QUIET = 1 << 2,
RZ_OUTPUT_MODE_SDB = 1 << 3,
RZ_OUTPUT_MODE_LONG = 1 << 4,
RZ_OUTPUT_MODE_LONG_JSON = 1 << 5,
RZ_OUTPUT_MODE_TABLE = 1 << 6,
RZ_OUTPUT_MODE_QUIETEST = 1 << 7,
RZ_OUTPUT_MODE_GRAPH = 1 << 8,
RZ_OUTPUT_MODE_STR_BUF = 1 << 9,
} RzOutputMode;
RZ_OWN RZ_OUT typedef char *(*pipe_fn)(const char *, int *);
/**
* \brief List of fallback pipe handlers for specific commands.
*
* Each entry maps a command name to the internal implementation used
* when no external binary is available in the system PATH.
*/
typedef struct pipe_fallbacks {
const char *command;
pipe_fn fallback_fn;
} PipeFallbacks;
/**
* \brief Represent the output state of a command handler.
*
* This structure is passed to commands of type \p RZ_CMD_DESC_TYPE_ARGV_STATE .
*/
typedef struct rz_cmd_state_output_t {
/**
* Output mode expected from the command handler
*/
RzOutputMode mode;
/**
* mode-specific data. Handlers are called with these data already
* initialized as necessary, based on the requested mode, and they do not
* need to be freed by the handler.
*/
union {
PJ *pj;
RzTable *t;
RzStrBuf *sbuf;
} d;
} RzCmdStateOutput;
typedef int (*RzCmdCb)(void *user, const char *input);
typedef RzCmdStatus (*RzCmdArgvCb)(RzCore *core, int argc, const char **argv);
typedef RzCmdStatus (*RzCmdArgvModesCb)(RzCore *core, int argc, const char **argv, RzOutputMode mode);
typedef RzCmdStatus (*RzCmdArgvStateCb)(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
typedef RzCmdStatus (*RzCmdMacroCb)(RzCore *core, int argc, const char **argv, int macro);
typedef int (*RzCmdNullCb)(void *user);
/**
* argc/argv data created from parsing the input command string.
*/
typedef struct rz_cmd_parsed_args_t {
int argc;
char **argv;
bool has_space_after_cmd;
char *extra; ///< Extra data that is neither a command name nor an argument (e.g. command modifiers/specifiers, table queries, etc.)
} RzCmdParsedArgs;
typedef struct rz_cmd_macro_t {
char *name;
char **args;
size_t nargs;
char *code;
} RzCmdMacro;
typedef struct rz_cmd_item_t {
char cmd[64];
RzCmdCb callback;
} RzCmdItem;
typedef struct rz_cmd_alias_t {
int count;
char **keys;
char **values;
int *remote;
} RzCmdAlias;
/**
* \brief A detailed entry that can be used to show additional info about a command entry.
*
* It can contain whatever relevant information (e.g. examples, specific uses of
* a command, variables, etc.).
*
* Displayed as:
* | <text><arg_str> # <comment>
*/
typedef struct rz_cmd_desc_detail_entry_t {
/**
* Main text of the detailed entry
*/
const char *text;
/**
* Short explanation of the entry, shown with the comment color
*/
const char *comment;
/**
* Text to show in a different color, after `text`, usually used to show
* arguments for examples.
*
* Optional.
*/
const char *arg_str;
} RzCmdDescDetailEntry;
/**
* A detail section used to better describe a command.
*/
typedef struct rz_cmd_desc_detail_t {
/**
* Name of the section, displayed at the beginning of the section.
*/
const char *name;
/**
* NULL-terminated array of entries, displayed one per line.
*/
const RzCmdDescDetailEntry *entries;
} RzCmdDescDetail;
/**
* Callback used to dynamically generate the details sections in the help of a command.
* NOTE: The array of RzCmdDescDetail returned will be freed, so all fields
* within need to be dynamically allocated even if they are marked as `const`.
*/
typedef RZ_OWN RzCmdDescDetail *(*RzCmdDescDetailCb)(RzCore *core, int argc, const char **argv);
/**
* Callback used to dynamically generate the choices of an argument with type \p RZ_CMD_ARG_TYPE_CHOICES
*/
typedef RZ_OWN char **(*RzCmdArgChoiceCb)(RzCore *core);
/**
* A description of an argument of a RzCmdDesc.
*/
typedef struct rz_cmd_desc_arg_t {
/**
* The name of the argument, shown also in its help.
*/
const char *name;
/**
* True if the argument is optional. If argument X is optional, then all
* arguments after X can only be specified if X was provided as well and
* they don't need to be set as optional.
*
* Example:
* CMDNAME <mandatory-arg0> [<optional-arg1> <optional-arg2> [<optional-arg3> [optional-arg4]]]
* <mandatory-arg0> has optional=false
* <optional-arg1> has optional=true
* <optional-arg2> has optional=false (it can be specified only if arg1
* was specified as well, so it doesn't need to be optional)
* <optional-arg3> has optional=true
* <optional-arg4> has optional=true
* Given the above:
* - `CMDNAME a0` is a valid command
* - `CMDNAME a0 a1 a2` is a valid command
* - `CMDNAME a0 a1` is not a valid command, because if a1 is specified, also a2 has to be
* - `CMDNAME a0 a1 a2 a3` is a valid command
* - `CMDNAME a0 a1 a2 a3 a4` is a valid command
*/
bool optional;
/**
* True if no space should be displayed before this argument in the help. By default it is
* false and a space is displayed before this argument.
*/
bool no_space;
/**
* Type of the argument.
*/
RzCmdArgType type;
/**
* Flag of the argument, used to modify the behaviour of this argument. See RZ_CMD_ARG_FLAG_ values.
*/
int flags;
/**
* Default value for the argument, if it is not specified. This field
* shall be used only when \p optional is true.
*/
const char *default_value;
/**
* Additional data which is type specific.
*/
union {
/**
* Data associated with an argument of \p type RZ_CMD_ARG_TYPE_CHOICES.
*/
struct {
/**
* Predefined list of possible values.
*/
const char **choices;
/**
* Callback used to generate a list of possible values.
* When this is specified, \p choices is ignored.
*/
RzCmdArgChoiceCb choices_cb;
} choices;
};
} RzCmdDescArg;
/**
* Define how the command looks like in the help.
*/
typedef struct rz_cmd_desc_help_t {
/**
* Short-sentence explaining what the command does.
* This is shown, for example, when the list of sub-commands is printed
* and each sub-command has a very short description on the right,
* explaining what it does.
*/
const char *summary;
/**
* Long description of what the command does. It can be as long as you
* want and it should explain well how the command behaves. This is
* shown, for example, when `??` is appended on a command. In that case,
* the short summary is extended with this longer description.
*
* Optional.
*/
const char *description;
/**
* String used to identify the arguments. This usually comes together
* with the summary.
* TODO: explain how to differentiate between required and optional arguments
*/
const char *args_str;
/**
* String that overrides the name+args_str usually used to describe the
* command.
*
* Optional.
*/
const char *usage;
/**
* String to use as sub-commands suggestions instead of the
* auto-generated one (e.g. [abcd] or [?] that you can see near command
* names when doing `w?`). If not provided, the options will be
* auto-generated.
*
* Optional.
*/
const char *options;
/**
* When true, the subcommands are automatically sorted alphabetically. By
* default subcommands are shown in the order provided by the developer.
*
* Optional.
*/
bool sort_subcommands;
/**
* NULL-terminated array of details sections used to better explain how
* to use the command. This is shown together with the long description.
*
* Optional.
*/
const RzCmdDescDetail *details;
/**
* Function that returns an array of details sections used to better explain
* how to use the command. This is shown together with the long description
* and can be used in addition or in alternative of \p details , when the
* output needs to be generated dynamically.
*
* Optional.
*/
RzCmdDescDetailCb details_cb;
/**
* Description of the arguments accepted by this command.
*/
const RzCmdDescArg *args;
} RzCmdDescHelp;
typedef enum rz_cmd_desc_type_t {
/**
* For handlers that accept argc/argv. It cannot have children. Use
* RZ_CMD_DESC_TYPE_GROUP if you need a command that can be both
* executed and has sub-commands.
*/
RZ_CMD_DESC_TYPE_ARGV = 0,
/**
* For cmd descriptors that are parent of other sub-commands, even if
* they may also have a sub-command with the same name. For example,
* `wc` is both the parent of `wci`, `wc*`, etc. but there is also `wc`
* as a sub-command.
*/
RZ_CMD_DESC_TYPE_GROUP,
/**
* For cmd descriptors that are just used to group together related
* sub-commands. Do not use this if the command can be used by itself or
* if it's necessary to show its help. Because this descriptor is not
* stored in the hashtable and cannot be retrieved except by listing the
* children of its parent. Most of the time you want RZ_CMD_DESC_TYPE_GROUP.
*/
RZ_CMD_DESC_TYPE_INNER,
/**
* For entries that shall be shown in the help tree but that are not
* commands on their own. `|?`, `@?`, `>?` are example of this. It is
* useful to provide help entries for them in the tree, but there are no
* command handlers for these. The RzCmdDescDetail in the help can be
* used to show fake children of this descriptor.
*/
RZ_CMD_DESC_TYPE_FAKE,
/**
* For handlers that accept argc/argv and that provides multiple output
* modes (e.g. rizin commands, quiet output, json, long). It cannot have
* children. Use RZ_CMD_DESC_TYPE_GROUP if you need a command that can
* be both executed and has sub-commands.
*/
RZ_CMD_DESC_TYPE_ARGV_MODES,
/**
* For handlers that accept argc/argv and that provides multiple output
* modes (e.g. rizin commands, quiet output, json, long). It cannot have
* children. Use RZ_CMD_DESC_TYPE_GROUP if you need a command that can
* be both executed and has sub-commands.
*
* Differently from \p RZ_CMD_DESC_TYPE_ARGV_MODES, these handlers receive
* an output structure with the mode and data already initialized (e.g. PJ,
* RzTable, etc.) and the handler just has to fill the data in those
* structure, while RzCmd will allocate, free and print the data within.
*/
RZ_CMD_DESC_TYPE_ARGV_STATE,
} RzCmdDescType;
/**
* Command Descriptor structure. It represents a command that can be executed
* by the user on the shell or a part of the command help (e.g. groups of
* commands). Anything that appears under `?` has an associated command
* descriptor.
*/
typedef struct rz_cmd_desc_t {
/**
* Type of the command descriptor. There are several types of commands:
* groups, fake and inner have no handlers; argv, mode and state can
* have handlers and get arguments via int argc, char **argv.
*/
RzCmdDescType type;
/**
* Base name of the command. This is used to retrieve the \p RzCmdDesc when
* a user executes a command. It can match multiple user-called commands.
* For example a command that accepts STANDARD and JSON \p modes is called
* for both `<name>` and `<name>j`.
*/
char *name;
/**
* Parent of this command descriptor.
*
* Commands are organized in a tree, with the root being shown when doing
* `?`. This relationship is used when showing commands helps.
*/
struct rz_cmd_desc_t *parent;
/**
* Number of children command descriptors of this node.
*/
int n_children;
/**
* Vector of childrens command descriptors.
*/
RzPVector /*<RzCmdDesc *>*/ children;
/**
* Reference to the help structure of this command descriptor.
*/
const RzCmdDescHelp *help;
/**
* Type-specific fields.
*/
union {
struct {
RzCmdArgvCb cb;
int min_argc;
int max_argc;
} argv_data;
struct {
struct rz_cmd_desc_t *exec_cd;
} group_data;
struct {
RzCmdArgvModesCb cb;
int modes; ///< A combination of RzOutputMode values
RzOutputMode default_mode; ///< Make one of the modes the default one, used even when the special suffix is not specified.
int min_argc;
int max_argc;
} argv_modes_data;
struct {
RzCmdArgvStateCb cb;
int modes; ///< A combination of RzOutputMode values
RzOutputMode default_mode; ///< Make one of the modes the default one, used even when the special suffix is not specified.
int min_argc;
int max_argc;
} argv_state_data;
} d;
} RzCmdDesc;
typedef struct rz_cmd_t {
RzCore *core;
RzCmdNullCb nullcallback;
RzCmdItem *cmds[UT8_MAX];
RzCmdAlias aliases;
HtSP *macros; ///< Map of macros (char *)name -> RzCmdMacro
void *language; // used to store TSLanguage *
HtUP *ts_symbols_ht;
RzCmdDesc *root_cmd_desc;
HtSP *ht_cmds;
/**
* True if a rz_cons_instance exists. When used from RzCore this is
* commonly true. However, it can be used in tests to avoid access to
* non-initialized RzCons.
*/
bool has_cons;
/**
* True when you want to add multiple commands in batch. This is an
* optimization mainly for groups that require sorted sub-commands, so
* instead of sorting on each addition we just sort one time at the end.
* False by default.
*/
bool batch;
} RzCmd;
// TODO: remove this once transitioned to RzCmdDesc
typedef struct rz_cmd_descriptor_t {
const char *cmd;
const char **help_msg;
const char **help_detail;
const char **help_detail2;
struct rz_cmd_descriptor_t *sub[127];
} RzCmdDescriptor;
typedef bool (*RzCmdForeachNameCb)(RzCmd *cmd, const RzCmdDesc *desc, void *user);
typedef bool (*RzCmdForeachMacroCb)(RzCmd *cmd, const RzCmdMacro *macro, void *user);
#ifdef RZ_API
RZ_API RzCmd *rz_cmd_new(RzCore *core, bool has_cons);
RZ_API RzCmd *rz_cmd_free(RzCmd *cmd);
RZ_API void rz_cmd_batch_start(RzCmd *cmd);
RZ_API void rz_cmd_batch_end(RzCmd *cmd);
RZ_API int rz_cmd_add(RzCmd *cmd, const char *command, RzCmdCb callback);
RZ_API int rz_cmd_call(RzCmd *cmd, const char *command);
RZ_API RzCmdStatus rz_cmd_call_parsed_args(RzCmd *cmd, RzCmdParsedArgs *args);
RZ_API RzCmdDesc *rz_cmd_get_root(RzCmd *cmd);
RZ_API RzCmdDesc *rz_cmd_get_desc(RzCmd *cmd, const char *cmd_identifier);
RZ_API RzCmdDesc *rz_cmd_get_desc_best(RzCmd *cmd, const char *cmd_identifier);
RZ_API RZ_OWN char *rz_cmd_get_help(RZ_BORROW RzCmd *cmd, RZ_BORROW RzCmdParsedArgs *args, bool use_color, int gutter_size);
RZ_API bool rz_cmd_get_help_json(RzCmd *cmd, const RzCmdDesc *cd, PJ *j);
RZ_API bool rz_cmd_get_help_strbuf(RzCmd *cmd, const RzCmdDesc *cd, bool use_color, RzStrBuf *sb, int gutter_size);
static inline RzCmdStatus rz_cmd_int2status(int v) {
if (v == -2) {
return RZ_CMD_STATUS_EXIT;
} else if (v < 0) {
return RZ_CMD_STATUS_ERROR;
} else {
return RZ_CMD_STATUS_OK;
}
}
static inline int rz_cmd_status2int(RzCmdStatus s) {
switch (s) {
case RZ_CMD_STATUS_OK:
return 0;
case RZ_CMD_STATUS_ERROR:
case RZ_CMD_STATUS_WRONG_ARGS:
case RZ_CMD_STATUS_INVALID:
case RZ_CMD_STATUS_NONEXISTINGCMD:
return -1;
case RZ_CMD_STATUS_EXIT:
default:
return -2;
}
}
/* RzCmdDescriptor */
RZ_API RzCmdDesc *rz_cmd_desc_argv_new(RzCmd *cmd, RzCmdDesc *parent, const char *name, RzCmdArgvCb cb, const RzCmdDescHelp *help);
RZ_API RzCmdDesc *rz_cmd_desc_argv_modes_new(RzCmd *cmd, RzCmdDesc *parent, const char *name, int modes, RzCmdArgvModesCb cb, const RzCmdDescHelp *help);
RZ_API RzCmdDesc *rz_cmd_desc_argv_state_new(RzCmd *cmd, RzCmdDesc *parent, const char *name, int modes, RzCmdArgvStateCb cb, const RzCmdDescHelp *help);
RZ_API RzCmdDesc *rz_cmd_desc_inner_new(RzCmd *cmd, RzCmdDesc *parent, const char *name, const RzCmdDescHelp *help);
RZ_API RzCmdDesc *rz_cmd_desc_group_new(RzCmd *cmd, RzCmdDesc *parent, const char *name, RzCmdArgvCb cb, const RzCmdDescHelp *help, const RzCmdDescHelp *group_help);
RZ_API RzCmdDesc *rz_cmd_desc_group_modes_new(RzCmd *cmd, RzCmdDesc *parent, const char *name, int modes, RzCmdArgvModesCb cb, const RzCmdDescHelp *help, const RzCmdDescHelp *group_help);
RZ_API RzCmdDesc *rz_cmd_desc_group_state_new(RzCmd *cmd, RzCmdDesc *parent, const char *name, int modes, RzCmdArgvStateCb cb, const RzCmdDescHelp *help, const RzCmdDescHelp *group_help);
RZ_API RzCmdDesc *rz_cmd_desc_fake_new(RzCmd *cmd, RzCmdDesc *parent, const char *name, const RzCmdDescHelp *help);
RZ_API RzCmdDesc *rz_cmd_desc_parent(RzCmdDesc *cd);
RZ_API RzCmdDesc *rz_cmd_desc_get_exec(RzCmdDesc *cd);
RZ_API bool rz_cmd_desc_set_default_mode(RzCmdDesc *cd, RzOutputMode mode);
RZ_API bool rz_cmd_desc_has_handler(const RzCmdDesc *cd);
RZ_API bool rz_cmd_desc_remove(RzCmd *cmd, RzCmdDesc *cd);
RZ_API void rz_cmd_foreach_cmdname(RzCmd *cmd, RzCmdDesc *begin, RzCmdForeachNameCb cb, void *user);
RZ_API const RzCmdDescArg *rz_cmd_desc_get_arg(const RzCmdDesc *cd, size_t i);
#define rz_cmd_desc_children_foreach(root, it_cd) rz_pvector_foreach (&root->children, it_cd)
#define rz_cmd_desc_children_foreach_idx(root, it_cd, idx) rz_pvector_enumerate (&root->children, it_cd, idx)
RZ_API void rz_cmd_desc_details_free(RzCmdDescDetail *details);
/* RzCmdParsedArgs */
RZ_API RzCmdParsedArgs *rz_cmd_parsed_args_new(const char *cmd, int n_args, char **args);
RZ_API RzCmdParsedArgs *rz_cmd_parsed_args_newcmd(const char *cmd);
RZ_API RzCmdParsedArgs *rz_cmd_parsed_args_newargs(int n_args, char **args);
RZ_API void rz_cmd_parsed_args_free(RzCmdParsedArgs *args);
RZ_API bool rz_cmd_parsed_args_setargs(RzCmdParsedArgs *arg, int n_args, char **args);
RZ_API bool rz_cmd_parsed_args_addarg(RzCmdParsedArgs *a, const char *arg);
RZ_API bool rz_cmd_parsed_args_setcmd(RzCmdParsedArgs *arg, const char *cmd);
RZ_API char *rz_cmd_parsed_args_argstr(RzCmdParsedArgs *arg);
RZ_API char *rz_cmd_parsed_args_execstr(RzCmdParsedArgs *arg);
RZ_API const char *rz_cmd_parsed_args_cmd(RzCmdParsedArgs *arg);
RZ_API char *rz_cmd_escape_arg(const char *arg, RzCmdEscape escape);
RZ_API char *rz_cmd_unescape_arg(const char *arg, RzCmdEscape escape);
RZ_API void rz_cmd_state_output_array_start(RzCmdStateOutput *state);
RZ_API void rz_cmd_state_output_array_end(RzCmdStateOutput *state);
RZ_API void rz_cmd_state_output_set_columnsf(RzCmdStateOutput *state, const char *fmt, ...);
RZ_API void rz_cmd_state_output_set_color_selector(RzCmdStateOutput *state, RzTableColorSelector color_cb, void *user);
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode, RZ_NULLABLE const RzCore *core);
RZ_API void rz_cmd_state_output_fini(RZ_NONNULL RzCmdStateOutput *state);
RZ_API void rz_cmd_state_output_free(RZ_NONNULL RzCmdStateOutput *state);
RZ_API void rz_cmd_state_output_print(RZ_NONNULL RzCmdStateOutput *state);
#define rz_cmd_parsed_args_foreach_arg(args, i, arg) for ((i) = 1; (i) < (args->argc) && ((arg) = (args)->argv[i]); (i)++)
/* rz_cmd_macro */
RZ_API bool rz_cmd_macro_add(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name, const char **args, RZ_NONNULL const char *code);
RZ_API bool rz_cmd_macro_update(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name, const char **args, RZ_NONNULL const char *code);
RZ_API bool rz_cmd_macro_rm(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name);
RZ_API const RzCmdMacro *rz_cmd_macro_get(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name);
RZ_API RZ_OWN RzList /*<RzCmdMacro *>*/ *rz_cmd_macro_list(RZ_NONNULL RzCmd *cmd);
RZ_API RzCmdStatus rz_cmd_macro_call(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name, RZ_NONNULL const char **argv);
RZ_API RzCmdStatus rz_cmd_macro_call_multiple(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name, RZ_NONNULL const char **argv);
RZ_API void rz_cmd_macro_foreach(RZ_NONNULL RzCmd *cmd, RzCmdForeachMacroCb cb, void *user);
RZ_API bool rz_cmd_alias_del(RzCmd *cmd, const char *k);
RZ_API char **rz_cmd_alias_keys(RzCmd *cmd, int *sz);
RZ_API int rz_cmd_alias_set(RzCmd *cmd, const char *k, const char *v, int remote);
RZ_API char *rz_cmd_alias_get(RzCmd *cmd, const char *k, int remote);
RZ_API void rz_cmd_alias_free(RzCmd *cmd);
#ifdef __cplusplus
}
#endif
#endif
#endif