NeoMutt  2023-05-17-56-ga67199
Teaching an old dog new tricks
DOXYGEN
debug.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <stdarg.h>
31#include <stdbool.h>
32#include <stdio.h>
33#include "mutt/lib.h"
34#include "gui/lib.h"
35#include "lib.h"
36
44int color_debug(enum LogLevel level, const char *format, ...)
45{
46 char buf[1024] = { 0 };
47
48 va_list ap;
49 va_start(ap, format);
50 int len = vsnprintf(buf, sizeof(buf), format, ap);
51 va_end(ap);
52
53 mutt_debug(level, buf);
54
55 return len;
56}
57
67const char *color_debug_log_color_attrs(int fg, int bg, int attrs)
68{
69 static char text[64];
70 int pos = 0;
71
72 if (attrs & A_BLINK)
73 pos += snprintf(text + pos, sizeof(text) - pos, "\033[5m");
74 if (attrs & A_BOLD)
75 pos += snprintf(text + pos, sizeof(text) - pos, "\033[1m");
76 if (attrs & A_NORMAL)
77 pos += snprintf(text + pos, sizeof(text) - pos, "\033[0m");
78 if (attrs & A_REVERSE)
79 pos += snprintf(text + pos, sizeof(text) - pos, "\033[7m");
80 if (attrs & A_STANDOUT)
81 pos += snprintf(text + pos, sizeof(text) - pos, "\033[1m");
82 if (attrs & A_UNDERLINE)
83 pos += snprintf(text + pos, sizeof(text) - pos, "\033[4m");
84
85 if (fg >= 0)
86 pos += snprintf(text + pos, sizeof(text) - pos, "\033[38;5;%dm", fg);
87 if (bg >= 0)
88 pos += snprintf(text + pos, sizeof(text) - pos, "\033[48;5;%dm", bg);
89
90 snprintf(text + pos, sizeof(text) - pos, "XXXXXX\033[0m");
91
92 return text;
93}
94
103const char *color_debug_log_color(int fg, int bg)
104{
105 static char text[64];
106 snprintf(text, sizeof(text), "\033[38;5;%dm\033[48;5;%dmXXXXXX\033[0m", fg, bg);
107 return text;
108}
109
118{
119 static char text[64];
120 struct Mapping attr_names[] = {
121 { "\033[5mBLI\033[0m", A_BLINK },
122 { "\033[1mBLD\033[0m", A_BOLD },
123 { "\033[0mNOR\033[0m", A_NORMAL },
124 { "\033[7mREV\033[0m", A_REVERSE },
125 { "\033[1mSTD\033[0m", A_STANDOUT },
126 { "\033[4mUND\033[0m", A_UNDERLINE },
127 { NULL, 0 },
128 };
129
130 int offset = 0;
131 text[0] = '\0';
132 for (int i = 0; attr_names[i].name; i++)
133 {
134 if (attrs & attr_names[i].value)
135 {
136 offset += snprintf(text + offset, sizeof(text) - offset, "%s ",
137 attr_names[i].name);
138 }
139 }
140 return text;
141}
142
150const char *color_debug_log_attrs_list(int attrs)
151{
152 static char text[64];
153
154 text[0] = '\0';
155 int pos = 0;
156 if (attrs & A_BLINK)
157 pos += snprintf(text + pos, sizeof(text) - pos, "blink ");
158 if (attrs & A_BOLD)
159 pos += snprintf(text + pos, sizeof(text) - pos, "bold ");
160 if (attrs & A_ITALIC)
161 pos += snprintf(text + pos, sizeof(text) - pos, "italic ");
162 if (attrs & A_NORMAL)
163 pos += snprintf(text + pos, sizeof(text) - pos, "normal ");
164 if (attrs & A_REVERSE)
165 pos += snprintf(text + pos, sizeof(text) - pos, "reverse ");
166 if (attrs & A_STANDOUT)
167 pos += snprintf(text + pos, sizeof(text) - pos, "standout ");
168 if (attrs & A_UNDERLINE)
169 pos += snprintf(text + pos, sizeof(text) - pos, "underline ");
170
171 return text;
172}
173
181const char *color_debug_log_name(char *buf, int buflen, int color)
182{
183 if (color < 0)
184 return "default";
185
186 if (color < 256)
187 snprintf(buf, buflen, "color%d", color);
188 else
189 snprintf(buf, buflen, "BAD:%d", color);
190
191 return buf;
192}
193
199void attr_color_dump(struct AttrColor *ac, const char *prefix)
200{
201 if (!ac)
202 return;
203
204 int index = ac->curses_color ? ac->curses_color->index : -1;
205
206 int fg = COLOR_DEFAULT;
207 int bg = COLOR_DEFAULT;
208 struct CursesColor *cc = ac->curses_color;
209 if (cc)
210 {
211 fg = cc->fg;
212 bg = cc->bg;
213 }
214 const char *color = color_debug_log_color(fg, bg);
215 const char *attrs = color_debug_log_attrs(ac->attrs);
216 color_debug(LL_DEBUG5, "%s| %5d | %s | 0x%08x | %s\n", NONULL(prefix), index,
217 color, ac->attrs, attrs);
218}
219
225void attr_color_list_dump(struct AttrColorList *acl, const char *title)
226{
227 if (!acl)
228 return;
229
230 int count = 0;
231 struct AttrColor *ac = NULL;
232 TAILQ_FOREACH(ac, acl, entries)
233 {
234 count++;
235 }
236
237 color_debug(LL_DEBUG5, "\033[1;32m%s:\033[0m (%d)\n", title, count);
238 if (count == 0)
239 return;
240
241 color_debug(LL_DEBUG5, " | Index | Colour | Attrs | Attrs\n");
242
243 TAILQ_FOREACH(ac, acl, entries)
244 {
245 attr_color_dump(ac, " ");
246 }
247}
248
254void curses_color_dump(struct CursesColor *cc, const char *prefix)
255{
256 if (!cc)
257 return;
258
259 const char *color = color_debug_log_color(cc->fg, cc->bg);
260 color_debug(LL_DEBUG5, "%s| %5d | %3d %3d | %s | %2d |\n", NONULL(prefix),
261 cc->index, cc->fg, cc->bg, color, cc->ref_count);
262}
263
268{
269 color_debug(LL_DEBUG5, "\033[1;32mCursesColors:\033[0m (%d)\n", NumCursesColors);
271 return;
272
273 color_debug(LL_DEBUG5, " | index | fg bg | colour | rc |\n");
274
275 struct CursesColor *cc = NULL;
276 TAILQ_FOREACH(cc, &CursesColors, entries)
277 {
278 curses_color_dump(cc, " ");
279 }
280}
281
288void quoted_color_dump(struct AttrColor *ac, int q_level, const char *prefix)
289{
290 if (!ac)
291 return;
292
293 int index = ac->curses_color ? ac->curses_color->index : -1;
294
295 int fg = COLOR_DEFAULT;
296 int bg = COLOR_DEFAULT;
297 struct CursesColor *cc = ac->curses_color;
298 if (cc)
299 {
300 fg = cc->fg;
301 bg = cc->bg;
302 }
303 const char *color = color_debug_log_color(fg, bg);
304 const char *attrs = color_debug_log_attrs(ac->attrs);
305 color_debug(LL_DEBUG5, "%s| quoted%d | %5d | %s | 0x%08x | %s\n", prefix,
306 q_level, index, color, ac->attrs, attrs);
307}
308
313{
314 color_debug(LL_DEBUG5, "\033[1;32mQuotedColors:\033[0m (%d)\n", NumQuotedColors);
315 color_debug(LL_DEBUG5, " | Name | Index | Colour | Attrs | Attrs\n");
316 for (size_t i = 0; i < COLOR_QUOTES_MAX; i++)
317 {
318 quoted_color_dump(&QuotedColors[i], i, " ");
319 }
320}
321
327void regex_color_dump(struct RegexColor *rcol, const char *prefix)
328{
329 if (!rcol)
330 return;
331
332 struct AttrColor *ac = &rcol->attr_color;
333 int index = ac->curses_color ? ac->curses_color->index : -1;
334
335 int fg = COLOR_DEFAULT;
336 int bg = COLOR_DEFAULT;
337 struct CursesColor *cc = ac->curses_color;
338 if (cc)
339 {
340 fg = cc->fg;
341 bg = cc->bg;
342 }
343 const char *color = color_debug_log_color(fg, bg);
344 const char *attrs = color_debug_log_attrs(ac->attrs);
345 color_debug(LL_DEBUG5, "%s| %5d | %s | 0x%08x | %-8s | %s\n", NONULL(prefix),
346 index, color, ac->attrs, attrs, rcol->pattern);
347}
348
354void regex_color_list_dump(const char *name, struct RegexColorList *rcl)
355{
356 if (!name || !rcl)
357 return;
358
359 int count = 0;
360 struct RegexColor *rcol = NULL;
361 STAILQ_FOREACH(rcol, rcl, entries)
362 {
363 count++;
364 }
365
366 color_debug(LL_DEBUG5, "\033[1;32mRegexColorList %s\033[0m (%d)\n", name, count);
367 if (count == 0)
368 return;
369
370 color_debug(LL_DEBUG5, " | Index | Colour | Attrs | Attrs | Pattern\n");
371 STAILQ_FOREACH(rcol, rcl, entries)
372 {
373 regex_color_dump(rcol, " ");
374 }
375}
376
381{
382 regex_color_list_dump("AttachList", &AttachList);
383 regex_color_list_dump("BodyList", &BodyList);
384 regex_color_list_dump("HeaderList", &HeaderList);
385 regex_color_list_dump("IndexAuthorList", &IndexAuthorList);
386 regex_color_list_dump("IndexCollapsedList", &IndexCollapsedList);
387 regex_color_list_dump("IndexDateList", &IndexDateList);
388 regex_color_list_dump("IndexFlagsList", &IndexFlagsList);
389 regex_color_list_dump("IndexLabelList", &IndexLabelList);
390 regex_color_list_dump("IndexList", &IndexList);
391 regex_color_list_dump("IndexNumberList", &IndexNumberList);
392 regex_color_list_dump("IndexSizeList", &IndexSizeList);
393 regex_color_list_dump("IndexSubjectList", &IndexSubjectList);
394 regex_color_list_dump("IndexTagList", &IndexTagList);
395 regex_color_list_dump("IndexTagsList", &IndexTagsList);
396 regex_color_list_dump("StatusList", &StatusList);
397}
398
404void simple_color_dump(enum ColorId cid, const char *prefix)
405{
406 struct AttrColor *ac = &SimpleColors[cid];
407 int index = ac->curses_color ? ac->curses_color->index : -1;
408 const char *name = NULL;
409 const char *compose = "";
410
411 name = mutt_map_get_name(cid, ColorFields);
412 if (!name)
413 {
415 if (name)
416 {
417 compose = "compose ";
418 }
419 }
420
421 int fg = COLOR_DEFAULT;
422 int bg = COLOR_DEFAULT;
423 struct CursesColor *cc = ac->curses_color;
424 if (cc)
425 {
426 fg = cc->fg;
427 bg = cc->bg;
428 }
429 const char *color_str = color_debug_log_color(fg, bg);
430 const char *attrs_str = color_debug_log_attrs(ac->attrs);
431 color_debug(LL_DEBUG5, "%s| %s%-17s | %5d | %s | 0x%08x | %s\n", prefix,
432 compose, name, index, color_str, ac->attrs, attrs_str);
433}
434
439void simple_colors_dump(bool force)
440{
441 color_debug(LL_DEBUG5, "\033[1;32mSimpleColors:\033[0m\n");
442 color_debug(LL_DEBUG5, " | Name | Index | Colour | Attrs | Attrs\n");
443 for (enum ColorId cid = MT_COLOR_NONE; cid < MT_COLOR_MAX; cid++)
444 {
445 struct AttrColor *ac = &SimpleColors[cid];
446 if (!force && !attr_color_is_set(ac))
447 continue;
448
449 simple_color_dump(cid, " ");
450 }
451}
452
457{
458 attr_color_list_dump(&MergedColors, "MergedColors");
459}
bool attr_color_is_set(struct AttrColor *ac)
Is the object coloured?
Definition: attr.c:160
struct RegexColorList IndexCollapsedList
List of colours applied to a collapsed thread in the index.
Definition: regex.c:52
struct RegexColorList IndexFlagsList
List of colours applied to the flags in the index.
Definition: regex.c:54
struct RegexColorList IndexAuthorList
List of colours applied to the author in the index.
Definition: regex.c:51
struct RegexColorList IndexSubjectList
List of colours applied to the subject in the index.
Definition: regex.c:59
struct RegexColorList IndexLabelList
List of colours applied to the label in the index.
Definition: regex.c:55
struct RegexColorList StatusList
List of colours applied to the status bar.
Definition: regex.c:62
struct RegexColorList IndexList
List of default colours applied to the index.
Definition: regex.c:56
struct RegexColorList IndexTagList
List of colours applied to tags in the index.
Definition: regex.c:60
struct RegexColorList BodyList
List of colours applied to the email body.
Definition: regex.c:49
struct RegexColorList IndexTagsList
List of colours applied to the tags in the index.
Definition: regex.c:61
struct RegexColorList HeaderList
List of colours applied to the email headers.
Definition: regex.c:50
struct RegexColorList AttachList
List of colours applied to the attachment headers.
Definition: regex.c:48
struct RegexColorList IndexDateList
List of colours applied to the date in the index.
Definition: regex.c:53
struct RegexColorList IndexNumberList
List of colours applied to the message number in the index.
Definition: regex.c:57
struct RegexColorList IndexSizeList
List of colours applied to the size in the index.
Definition: regex.c:58
struct AttrColor SimpleColors[MT_COLOR_MAX]
Array of Simple colours.
Definition: simple.c:37
const struct Mapping ComposeColorFields[]
Mapping of compose colour names to their IDs.
Definition: command.c:108
const struct Mapping ColorFields[]
Mapping of colour names to their IDs.
Definition: command.c:53
#define COLOR_DEFAULT
Definition: color.h:102
ColorId
List of all colored objects.
Definition: color.h:38
@ MT_COLOR_MAX
Definition: color.h:92
@ MT_COLOR_NONE
Definition: color.h:39
int NumCursesColors
Number of ncurses colours left to allocate.
Definition: curses.c:37
struct CursesColorList CursesColors
List of all Curses colours.
Definition: curses.c:36
void regex_colors_dump_all(void)
Dump all the Regex colours to the log.
Definition: debug.c:380
void regex_color_dump(struct RegexColor *rcol, const char *prefix)
Dump a Regex colour to the log.
Definition: debug.c:327
const char * color_debug_log_attrs(int attrs)
Get a string to represent some attributes in the log.
Definition: debug.c:117
void attr_color_list_dump(struct AttrColorList *acl, const char *title)
Dump all the Attr Colours to the log.
Definition: debug.c:225
int color_debug(enum LogLevel level, const char *format,...)
Write to the log file.
Definition: debug.c:44
const char * color_debug_log_color(int fg, int bg)
Get a colourful string to represent a colour in the log.
Definition: debug.c:103
const char * color_debug_log_attrs_list(int attrs)
Get a string to represent some attributes in the log.
Definition: debug.c:150
const char * color_debug_log_name(char *buf, int buflen, int color)
Get a string to represent a colour name.
Definition: debug.c:181
void quoted_color_list_dump(void)
Log all the Quoted colours.
Definition: debug.c:312
void curses_color_dump(struct CursesColor *cc, const char *prefix)
Log one Curses colour.
Definition: debug.c:254
void simple_colors_dump(bool force)
Dump all the Simple colours to the log.
Definition: debug.c:439
void simple_color_dump(enum ColorId cid, const char *prefix)
Dump a Simple colour to the log.
Definition: debug.c:404
const char * color_debug_log_color_attrs(int fg, int bg, int attrs)
Get a colourful string to represent a colour in the log.
Definition: debug.c:67
void attr_color_dump(struct AttrColor *ac, const char *prefix)
Dump an Attr Colour to the log.
Definition: debug.c:199
void quoted_color_dump(struct AttrColor *ac, int q_level, const char *prefix)
Log a Quoted colour.
Definition: debug.c:288
void merged_colors_dump(void)
Dump all the Merged colours to the log.
Definition: debug.c:456
void regex_color_list_dump(const char *name, struct RegexColorList *rcl)
Dump one Regex's colours to the log.
Definition: debug.c:354
void curses_colors_dump(void)
Log all the Curses colours.
Definition: debug.c:267
#define mutt_debug(LEVEL,...)
Definition: logging2.h:87
Convenience wrapper for the gui headers.
LogLevel
Names for the Logging Levels.
Definition: logging2.h:38
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
struct AttrColorList MergedColors
Array of user colours.
Definition: merged.c:41
Convenience wrapper for the library headers.
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define TAILQ_EMPTY(head)
Definition: queue.h:721
int NumQuotedColors
Number of colours for quoted email text.
Definition: quoted.c:38
struct AttrColor QuotedColors[COLOR_QUOTES_MAX]
Array of colours for quoted email text.
Definition: quoted.c:37
#define COLOR_QUOTES_MAX
Ten colours, quoted0..quoted9 (quoted and quoted0 are equivalent)
Definition: quoted.h:37
Key value store.
#define NONULL(x)
Definition: string2.h:37
A curses colour and its attributes.
Definition: attr.h:35
int attrs
Text attributes, e.g. A_BOLD.
Definition: attr.h:37
struct CursesColor * curses_color
Underlying Curses colour.
Definition: attr.h:36
Colour in the ncurses palette.
Definition: curses2.h:38
short index
Index number.
Definition: curses2.h:43
uint32_t fg
Foreground colour.
Definition: curses2.h:41
uint32_t bg
Background colour.
Definition: curses2.h:42
short ref_count
Number of users.
Definition: curses2.h:44
Mapping between user-readable string and a constant.
Definition: mapping.h:32
int value
Integer value.
Definition: mapping.h:34
const char * name
String value.
Definition: mapping.h:33
A regular expression and a color to highlight a line.
Definition: regex4.h:37
struct AttrColor attr_color
Colour and attributes to apply.
Definition: regex4.h:38
char * pattern
Pattern to match.
Definition: regex4.h:39