Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <errno.h> | ||
2 | #include <stdarg.h> | ||
3 | #include <stdio.h> | ||
4 | #include <string.h> | ||
5 | #include "error.h" | ||
6 | #include "command/run.h" | ||
7 | #include "util/log.h" | ||
8 | #include "util/xstdio.h" | ||
9 | |||
10 | VPRINTF(2) | ||
11 | 146 | static void error_msgv(ErrorBuffer *eb, const char *format, va_list ap) | |
12 | { | ||
13 | 146 | const size_t size = sizeof(eb->buf); | |
14 | 146 | const char *cmd = eb->command_name; | |
15 | 146 | const char *file = eb->config_filename; | |
16 | 146 | unsigned int line = eb->config_line; | |
17 | 146 | int pos = 0; | |
18 | |||
19 |
1/2✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 146 times.
|
146 | if (file && cmd) { |
20 | ✗ | pos = snprintf(eb->buf, size, "%s:%u: %s: ", file, line, cmd); | |
21 |
2/2✓ Branch 0 (4→5) taken 2 times.
✓ Branch 1 (4→6) taken 144 times.
|
146 | } else if (file) { |
22 | 2 | pos = snprintf(eb->buf, size, "%s:%u: ", file, line); | |
23 |
2/2✓ Branch 0 (6→7) taken 134 times.
✓ Branch 1 (6→11) taken 10 times.
|
144 | } else if (cmd) { |
24 | 134 | pos = snprintf(eb->buf, size, "%s: ", cmd); | |
25 | } | ||
26 | |||
27 |
1/2✗ Branch 0 (8→9) not taken.
✓ Branch 1 (8→11) taken 136 times.
|
136 | if (unlikely(pos < 0)) { |
28 | // Note: POSIX snprintf(3) *does* set errno on failure (unlike ISO C) | ||
29 | ✗ | LOG_ERRNO("snprintf"); | |
30 | ✗ | pos = 0; | |
31 | } | ||
32 | |||
33 |
1/2✓ Branch 0 (11→12) taken 146 times.
✗ Branch 1 (11→13) not taken.
|
146 | if (likely(pos < (size - 3))) { |
34 | 146 | vsnprintf(eb->buf + pos, size - pos, format, ap); | |
35 | } else { | ||
36 | ✗ | LOG_WARNING("no buffer space left for error message"); | |
37 | } | ||
38 | |||
39 |
2/2✓ Branch 0 (14→15) taken 4 times.
✓ Branch 1 (14→17) taken 142 times.
|
146 | if (eb->print_to_stderr) { |
40 | 4 | xfputs(eb->buf, stderr); | |
41 | 4 | xfputc('\n', stderr); | |
42 | } | ||
43 | |||
44 | 146 | eb->is_error = true; | |
45 | 146 | eb->nr_errors++; | |
46 | 146 | LOG_INFO("%s", eb->buf); | |
47 | 146 | } | |
48 | |||
49 | 128 | bool error_msg(ErrorBuffer *eb, const char *format, ...) | |
50 | { | ||
51 | 128 | va_list ap; | |
52 | 128 | va_start(ap, format); | |
53 | 128 | error_msgv(eb, format, ap); | |
54 | 128 | va_end(ap); | |
55 | 128 | return false; // To allow tail-calling from command handlers | |
56 | } | ||
57 | |||
58 | 18 | bool error_msg_for_cmd(ErrorBuffer *eb, const char *cmd, const char *format, ...) | |
59 | { | ||
60 | 18 | const char *saved_cmd = eb->command_name; | |
61 | 18 | eb->command_name = cmd; | |
62 | |||
63 | 18 | va_list ap; | |
64 | 18 | va_start(ap, format); | |
65 | 18 | error_msgv(eb, format, ap); | |
66 | 18 | va_end(ap); | |
67 | |||
68 | 18 | eb->command_name = saved_cmd; | |
69 | 18 | return false; | |
70 | } | ||
71 | |||
72 | 1 | bool error_msg_errno(ErrorBuffer *eb, const char *prefix) | |
73 | { | ||
74 | 1 | return error_msg(eb, "%s: %s", prefix, strerror(errno)); | |
75 | } | ||
76 | |||
77 | 14 | bool info_msg(ErrorBuffer *eb, const char *format, ...) | |
78 | { | ||
79 | 14 | va_list ap; | |
80 | 14 | va_start(ap, format); | |
81 | 14 | vsnprintf(eb->buf, sizeof(eb->buf), format, ap); | |
82 | 14 | va_end(ap); | |
83 | 14 | eb->is_error = false; | |
84 | 14 | return true; // To allow tail-calling from command handlers | |
85 | } | ||
86 | |||
87 | 131 | void clear_error(ErrorBuffer *eb) | |
88 | { | ||
89 | 131 | eb->buf[0] = '\0'; | |
90 | 131 | } | |
91 |