dte test coverage


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