Line data Source code
1 : #include <stdlib.h> 2 : #include <string.h> 3 : #include "cache.h" 4 : #include "args.h" 5 : #include "parse.h" 6 : #include "util/ptr-array.h" 7 : #include "util/str-util.h" 8 : #include "util/xmalloc.h" 9 : 10 191 : CachedCommand *cached_command_new(const CommandRunner *runner, const char *cmd_str) 11 : { 12 191 : const size_t cmd_str_len = strlen(cmd_str); 13 191 : CachedCommand *cached = xmalloc(sizeof(*cached) + cmd_str_len + 1); 14 191 : memcpy(cached->cmd_str, cmd_str, cmd_str_len + 1); 15 : 16 191 : PointerArray array = PTR_ARRAY_INIT; 17 191 : if (parse_commands(runner, &array, cmd_str) != CMDERR_NONE) { 18 0 : goto nocache; 19 : } 20 : 21 191 : ptr_array_trim_nulls(&array); 22 191 : size_t n = array.count; 23 191 : if (n < 2 || ptr_array_idx(&array, NULL) != n - 1) { 24 : // Only single commands can be cached 25 2 : goto nocache; 26 : } 27 : 28 189 : const Command *cmd = runner->cmds->lookup(array.ptrs[0]); 29 189 : if (!cmd) { 30 : // Aliases or non-existent commands can't be cached 31 2 : goto nocache; 32 : } 33 : 34 187 : if (memchr(cmd_str, '$', cmd_str_len)) { 35 : // Commands containing variables can't be cached 36 1 : goto nocache; 37 : } 38 : 39 186 : free(ptr_array_remove_idx(&array, 0)); 40 186 : CommandArgs cmdargs = cmdargs_new((char**)array.ptrs); 41 186 : if (do_parse_args(cmd, &cmdargs) != ARGERR_NONE) { 42 3 : goto nocache; 43 : } 44 : 45 : // Command can be cached; cache takes ownership of args array 46 183 : cached->cmd = cmd; 47 183 : cached->a = cmdargs; 48 183 : return cached; 49 : 50 8 : nocache: 51 8 : ptr_array_free(&array); 52 8 : cached->cmd = NULL; 53 8 : return cached; 54 : } 55 : 56 375 : void cached_command_free(CachedCommand *cc) 57 : { 58 375 : if (!cc) { 59 : return; 60 : } 61 191 : if (cc->cmd) { 62 183 : free_string_array(cc->a.args); 63 : } 64 191 : free(cc); 65 : }