dte test coverage


Directory: ./
File: src/command/cache.c
Date: 2024-12-21 16:03:22
Exec Total Coverage
Lines: 39 39 100.0%
Functions: 2 2 100.0%
Branches: 16 16 100.0%

Line Branch Exec Source
1 #include <stdlib.h>
2 #include <string.h>
3 #include "cache.h"
4 #include "args.h"
5 #include "parse.h"
6 #include "util/log.h"
7 #include "util/ptr-array.h"
8 #include "util/str-array.h"
9 #include "util/xmalloc.h"
10
11 // Takes a command string and returns a struct containing the resolved
12 // Command and pre-parsed arguments, or a NULL Command if uncacheable.
13 // In both cases, CachedCommand::cmd_str is filled with a copy of the
14 // original string. This caching is done to allow handle_binding() to
15 // avoid repeated parsing/allocation each time a key binding is used.
16 1189 CachedCommand *cached_command_new(const CommandRunner *runner, const char *cmd_str)
17 {
18 1189 const size_t cmd_str_len = strlen(cmd_str);
19 1189 CachedCommand *cached = xmalloc(sizeof(*cached) + cmd_str_len + 1);
20 1189 memcpy(cached->cmd_str, cmd_str, cmd_str_len + 1);
21
22 1189 const char *reason;
23 1189 PointerArray array = PTR_ARRAY_INIT;
24
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1186 times.
1189 if (parse_commands(runner, &array, cmd_str) != CMDERR_NONE) {
25 3 reason = "parsing failed";
26 3 goto nocache;
27 }
28
29 1186 ptr_array_trim_nulls(&array);
30 1186 size_t n = array.count;
31
4/4
✓ Branch 0 taken 1185 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1184 times.
1186 if (n < 2 || ptr_array_xindex(&array, NULL) != n - 1) {
32 2 reason = "multiple commands";
33 2 goto nocache;
34 }
35
36 1184 const Command *cmd = runner->cmds->lookup(array.ptrs[0]);
37
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1177 times.
1184 if (!cmd) {
38 // Aliases and non-existent commands can't be cached, because the
39 // command they expand to could later be invalidated by cmd_alias().
40 7 reason = "contains aliases";
41 7 goto nocache;
42 }
43
44 // TODO: Make this condition more precise
45
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1176 times.
1177 if (memchr(cmd_str, '$', cmd_str_len)) {
46 1 reason = "may contain variables";
47 1 goto nocache;
48 }
49
50 1176 free(ptr_array_remove_index(&array, 0));
51 1176 CommandArgs cmdargs = cmdargs_new((char**)array.ptrs);
52
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1173 times.
1176 if (do_parse_args(cmd, &cmdargs) != ARGERR_NONE) {
53 3 reason = "argument parsing failed";
54 3 goto nocache;
55 }
56
57 // Command can be cached; cache takes ownership of args array
58 1173 cached->cmd = cmd;
59 1173 cached->a = cmdargs;
60 1173 return cached;
61
62 16 nocache:
63 16 LOG_TRACE("skipping command cache (%s): %s", reason, cmd_str);
64 16 ptr_array_free(&array);
65 16 cached->cmd = NULL;
66 16 return cached;
67 }
68
69 2368 void cached_command_free(CachedCommand *cc)
70 {
71
2/2
✓ Branch 0 taken 1189 times.
✓ Branch 1 taken 1179 times.
2368 if (!cc) {
72 return;
73 }
74
2/2
✓ Branch 0 taken 1173 times.
✓ Branch 1 taken 16 times.
1189 if (cc->cmd) {
75 1173 free_string_array(cc->a.args);
76 }
77 1189 free(cc);
78 }
79