LCOV - code coverage report
Current view: top level - src/command - cache.c Hit Total Coverage
Test: dte Lines: 31 32 96.9 %
Date: 2023-03-25 22:04:15

          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             : }

Generated by: LCOV version 1.14