Cthulhu  0.2.10
Cthulhu compiler collection
common_extra.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-only
2 
3 #include "common_extra.h"
4 
5 #include "base/util.h"
6 #include "core/macros.h"
7 #include "io/io.h"
8 #include "memory/memory.h"
9 
10 #include "base/panic.h"
11 #include "scan/node.h"
12 #include "std/map.h"
13 #include "std/set.h"
14 #include "std/str.h"
15 #include "arena/arena.h"
16 
17 #include "std/typed/vector.h"
18 #include "std/vector.h"
19 
20 #include <ctype.h>
21 
22 #define COLOUR_UNKNOWN eColourMagenta
23 #define COLOUR_SORRY eColourMagenta
24 #define COLOUR_INTERNAL eColourCyan
25 #define COLOUR_FATAL eColourRed
26 #define COLOUR_WARN eColourYellow
27 #define COLOUR_INFO eColourGreen
28 #define COLOUR_DEBUG eColourGreen
29 
30 severity_t get_severity(const diagnostic_t *diag, bool override_fatal)
31 {
32  severity_t severity = diag->severity;
33  if (override_fatal && severity == eSeverityWarn) return eSeverityFatal;
34 
35  return severity;
36 }
37 
38 const char *get_severity_name(severity_t severity)
39 {
40  switch (severity)
41  {
42  case eSeveritySorry: return "sorry";
43  case eSeverityInternal: return "internal";
44  case eSeverityFatal: return "error";
45  case eSeverityWarn: return "warning";
46  case eSeverityInfo: return "info";
47  case eSeverityDebug: return "debug";
48  default: return "unknown";
49  }
50 }
51 
53 {
54  switch (severity)
55  {
56  case eSeveritySorry: return COLOUR_SORRY;
57  case eSeverityInternal: return COLOUR_INTERNAL;
58  case eSeverityFatal: return COLOUR_FATAL;
59  case eSeverityWarn: return COLOUR_WARN;
60  case eSeverityInfo:
61  case eSeverityDebug: return COLOUR_INFO;
62  default: return COLOUR_UNKNOWN;
63  }
64 }
65 
66 // assumes all segments are in the same file
67 static int segment_cmp(const void *lhs, const void *rhs)
68 {
69  const segment_t *seg_lhs = lhs;
70  const segment_t *seg_rhs = rhs;
71 
72  const scan_t *scan_lhs = node_get_scan(&seg_lhs->node);
73  const scan_t *scan_rhs = node_get_scan(&seg_rhs->node);
74 
75  CTASSERTF(scan_lhs == scan_rhs, "segments must be in the same scan (%s and %s)",
76  scan_path(scan_lhs), scan_path(scan_rhs));
77 
78  where_t where_lhs = node_get_location(&seg_lhs->node);
79  where_t where_rhs = node_get_location(&seg_rhs->node);
80 
81  if (where_lhs.first_line < where_rhs.first_line) return -1;
82  if (where_lhs.first_line > where_rhs.first_line) return 1;
83 
84  if (where_lhs.first_column < where_rhs.first_column) return -1;
85  if (where_lhs.first_column > where_rhs.first_column) return 1;
86 
87  return 0;
88 }
89 
90 void segments_sort(typevec_t *segments)
91 {
92  typevec_sort(segments, segment_cmp);
93 }
94 
95 typevec_t *all_segments_in_scan(const typevec_t *segments, const node_t *node, arena_t *arena)
96 {
97  CTASSERT(segments != NULL);
98  CTASSERT(node != NULL);
99 
100  const scan_t *scan = node_get_scan(node);
101 
102  size_t len = typevec_len(segments);
103  typevec_t *result = typevec_new(sizeof(segment_t), len, arena);
104 
105  for (size_t i = 0; i < len; i++)
106  {
107  segment_t *segment = typevec_offset(segments, i);
108  CTASSERT(segment != NULL);
109 
110  const scan_t *other = node_get_scan(&segment->node);
111  if (other != scan) continue;
112 
113  typevec_push(result, segment);
114  }
115 
116  segments_sort(result);
117 
118  return result;
119 }
120 
121 size_t get_line_number(file_config_t config, const node_t *node)
122 {
123  where_t where = node_get_location(node);
124  if (config.zeroth_line) return where.first_line;
125 
126  return where.first_line + 1;
127 }
128 
129 bool node_has_line(const node_t *node)
130 {
131  return !node_is_builtin(node);
132 }
133 
134 typedef struct cache_map_t
135 {
138 } cache_map_t;
139 
140 typedef struct lineinfo_t
141 {
142  size_t offset;
143  size_t length;
144 } lineinfo_t;
145 
146 typedef struct text_cache_t
147 {
149 
152 
154 
156 } text_cache_t;
157 
158 // load the start and length of each line in the file
159 static void load_lineinfo(text_cache_t *text)
160 {
161  size_t offset = 0;
162 
163  const char *start = text->source.text;
164  const char *end = start + text->source.length;
165 
166  while (start < end)
167  {
168  size_t i = str_find(start, "\n");
169  const char *next = (i == SIZE_MAX) ? end : start + i;
170 
171  lineinfo_t info = {
172  .offset = offset,
173  .length = next - start,
174  };
175 
176  typevec_push(text->line_info, &info);
177 
178  offset += info.length + 1;
179  start = next + 1;
180  }
181 }
182 
183 static text_cache_t *text_cache_new(io_t *io, text_view_t source, size_t len, arena_t *arena)
184 {
185  text_cache_t *cache = ARENA_MALLOC(sizeof(text_cache_t), "text_cache", NULL, arena);
186  cache->arena = arena;
187  cache->io = io;
188  cache->source = source;
189  cache->line_info = typevec_new(sizeof(lineinfo_t), len, arena);
190  cache->cached_lines = map_optimal(len, kTypeInfoString, arena);
191 
192  return cache;
193 }
194 
195 static text_view_t get_io_view(io_t *io)
196 {
197  if (io_error(io) != 0)
198  {
199  return text_view_from("");
200  }
201 
202  const void *memory = io_map(io, eOsProtectRead);
203  size_t size = io_size(io);
204 
205  CTASSERTF(memory != NULL, "io_map(%s) failed", io_name(io));
206 
207  return text_view_make(memory, size);
208 }
209 
210 static text_cache_t *text_cache_io(io_t *io, arena_t *arena)
211 {
212  CTASSERT(io != NULL);
213 
214  text_view_t view = get_io_view(io);
215 
216  text_cache_t *cache = text_cache_new(io, view, 32, arena);
217 
218  if (io_error(io) == 0) load_lineinfo(cache);
219 
220  return cache;
221 }
222 
223 static text_cache_t *text_cache_scan(const scan_t *scan, arena_t *arena)
224 {
225  CTASSERT(scan != NULL);
226 
227  text_view_t view = scan_source(scan);
228 
229  text_cache_t *cache = text_cache_new(NULL, view, 32, arena);
230 
231  load_lineinfo(cache);
232 
233  return cache;
234 }
235 
236 static void text_cache_delete(text_cache_t *cache)
237 {
238  CTASSERT(cache != NULL);
239 
240  if (cache->io != NULL) io_close(cache->io);
241  arena_free(cache, sizeof(text_cache_t), cache->arena);
242 }
243 
244 static bool cache_is_valid(text_cache_t *cache)
245 {
246  CTASSERT(cache != NULL);
247 
248  return cache->io == NULL || io_error(cache->io) == 0;
249 }
250 
252 {
253  CTASSERT(arena != NULL);
254 
255  cache_map_t *data = ARENA_MALLOC(sizeof(cache_map_t), "cache_map", NULL, arena);
256  data->arena = arena;
257  data->map = map_optimal(size, kTypeInfoString, arena);
258 
259  return data;
260 }
261 
263 {
264  CTASSERT(map != NULL);
265 
266  map_iter_t iter = map_iter(map->map);
267  const char *key = NULL;
268  text_cache_t *cache = NULL;
269  while (CTU_MAP_NEXT(&iter, &key, &cache))
270  {
271  text_cache_delete(cache);
272  }
273 }
274 
276 {
277  CTASSERT(map != NULL);
278  CTASSERT(path != NULL);
279 
280  // TODO: is using the name stable?
281  text_cache_t *cache = map_get(map->map, path);
282  if (cache != NULL && cache_is_valid(cache)) return cache;
283 
284  io_t *io = io_file(path, eOsAccessRead, map->arena);
285  text_cache_t *text = text_cache_io(io, map->arena);
286 
287  // always insert the cache, even if it is invalid.
288  // this way we avoid trying to open the file again
289  map_set(map->map, path, text);
290  if (cache_is_valid(text)) return text;
291 
292  return NULL;
293 }
294 
296 {
297  CTASSERT(map != NULL);
298  CTASSERT(scan != NULL);
299 
300  text_cache_t *cache = map_get(map->map, scan);
301  if (cache != NULL && cache_is_valid(cache)) return cache;
302 
303  // scan caches will never be invalid, so we can just insert them
304  text_cache_t *text = text_cache_scan(scan, map->arena);
305  map_set(map->map, scan, text);
306 
307  return text;
308 }
309 
311 {
312  CTASSERT(cache != NULL);
313 
314  bool has_line = typevec_len(cache->line_info) > line;
315 
316  if (!has_line)
317  {
318  // line is out of bounds. why?
319  return text_view_make("", 0);
320  }
321 
322  lineinfo_t *info = typevec_offset(cache->line_info, line);
323 
324  return text_view_make(cache->source.text + info->offset, info->length);
325 }
326 
328 {
329  CTASSERT(cache != NULL);
330 
331  return typevec_len(cache->line_info);
332 }
333 
334 static const char *const kHexChars = "0123456789abcdef";
335 
336 static bool get_escaped_char(char *buf, char c)
337 {
338  if (isprint(c))
339  {
340  buf[0] = c;
341  buf[1] = '\0';
342  return false;
343  }
344 
345  // print 2 byte hex value, we need to do this manually rather than using snprintf
346  // because snprintf is too slow and for some ungodly reason this is a hot path
347  buf[0] = '\\';
348  buf[1] = kHexChars[c >> 4];
349  buf[2] = kHexChars[c & 0xf];
350  buf[3] = '\0';
351 
352  return true;
353 }
354 
355 text_t cache_escape_line(text_cache_t *cache, size_t line, const colour_pallete_t *colours,
356  size_t column_limit)
357 {
358  CTASSERT(colours != NULL);
359 
360  text_t *cached = map_get(cache->cached_lines, (void *)(uintptr_t)(line + 1));
361  if (cached != NULL) return *cached;
362 
363  text_view_t view = cache_get_line(cache, line);
364 
365  typevec_t *result = typevec_new(sizeof(char), view.length * 2, cache->arena);
366 
367  // we use a temporary buffer to format into because this is a hot path
368  // when reporting very long lines, snprintf is too slow
369 
370  // 8 characters is enough for any 1 byte hex value
371  char buffer[8] = "";
372  bool in_colour = false;
373  size_t used = column_limit;
374  for (size_t i = 0; i < view.length; i++)
375  {
376  char c = view.text[i];
377  bool is_notprint = get_escaped_char(buffer, c);
378  if (is_notprint && !in_colour)
379  {
380  const char *colour = colour_get(colours, COLOUR_UNKNOWN);
381  typevec_append(result, colour, ctu_strlen(colour));
382  in_colour = true;
383  }
384  else if (!is_notprint && in_colour)
385  {
386  const char *reset = colour_reset(colours);
387  typevec_append(result, reset, ctu_strlen(reset));
388  in_colour = false;
389  }
390 
391  typevec_append(result, buffer, ctu_strlen(buffer));
392 
393  if (0 >= --used)
394  {
395  break;
396  }
397  }
398 
399  text_t *ptr = ARENA_MALLOC(sizeof(text_t), "text", NULL, cache->arena);
400  ptr->text = typevec_data(result);
401  ptr->length = typevec_len(result);
402 
403  map_set(cache->cached_lines, (void *)(uintptr_t)(line + 1), ptr);
404 
405  return *ptr;
406 }
407 
408 static bool set_has_option(set_t *set, const diagnostic_t *diag)
409 {
410  if (set == NULL) return false;
411 
412  return set_contains(set, diag);
413 }
414 
415 STA_DECL
416 int text_report(typevec_t *events, report_config_t config, const char *title)
417 {
418  CTASSERT(events != NULL);
419  CTASSERT(title != NULL);
420 
421  arena_t *arena = get_global_arena();
422  size_t error_budget = config.max_errors == 0 ? 20 : config.max_errors;
423  size_t warn_budget = config.max_warnings == 0 ? 20 : config.max_warnings;
424 
425  cache_map_t *cache = cache_map_new(32, arena);
426 
428  text_config_t text = config.text_config;
429 
430  text.cache = cache;
431 
432  size_t len = typevec_len(events);
433  void (*fn)(text_config_t, const event_t *) = fmt == eTextComplex ? text_report_rich
435 
436  int result = CT_EXIT_OK;
437  size_t warning_count = 0;
438  size_t error_count = 0;
439  size_t bug_count = 0;
440 
441 
442  for (size_t i = 0; i < len; i++)
443  {
444  event_t *event = typevec_offset(events, i);
445  const diagnostic_t *diag = event->diagnostic;
446  if (set_has_option(config.ignore_warnings, diag))
447  {
448  continue;
449  }
450 
451  switch (diag->severity)
452  {
453  case eSeverityWarn:
454  warn_budget -= 1;
455  if (warn_budget == 0) continue;
456  break;
457 
458  case eSeverityFatal:
459  error_budget -= 1;
460  if (error_budget == 0) continue;
461  break;
462 
463  default: break;
464  }
465 
466  text.config.override_fatal = set_has_option(config.error_warnings, diag);
467 
468  fn(text, event);
469 
470  switch (diag->severity)
471  {
472  case eSeverityFatal:
473  result = CT_MAX(result, CT_EXIT_ERROR);
474  error_count += 1;
475  break;
476  case eSeverityInternal:
477  case eSeveritySorry:
478  result = CT_MAX(result, CT_EXIT_INTERNAL);
479  bug_count += 1;
480  break;
481  case eSeverityWarn:
482  warning_count += 1;
483  /* fallthrough */
484  default: break;
485  }
486  }
487 
488  io_t *io = text.io;
489 
490  format_context_t ctx = {
491  .arena = arena,
492  .pallete = text.colours,
493  };
494 
495  if (result != CT_EXIT_OK)
496  {
497  io_printf(io, "compilation failed during stage: %s\n", title);
498  vector_t *parts = vector_new(3, arena);
499  if (error_count > 0)
500  {
501  char *colour_err = colour_format(ctx, COLOUR_FATAL, "%zu errors", error_count);
502  vector_push(&parts, colour_err);
503  }
504 
505  if (warning_count > 0)
506  {
507  char *colour_warn = colour_format(ctx, COLOUR_WARN, "%zu warnings", warning_count);
508  vector_push(&parts, colour_warn);
509  }
510 
511  if (bug_count > 0)
512  {
513  char *colour_bug = colour_format(ctx, COLOUR_INTERNAL, "%zu bugs", bug_count);
514  vector_push(&parts, colour_bug);
515  }
516 
517  char *msg = str_join(", ", parts, arena);
518  io_printf(io, " %s\n", msg);
519  }
520  else if (warning_count > 0)
521  {
522  io_printf(io, "compilation succeeded with warnings during stage: %s\n", title);
523  char *colour_warn = colour_format(ctx, COLOUR_WARN, "%zu warnings", warning_count);
524  io_printf(io, " %s\n", colour_warn);
525  }
526 
527  return result;
528 }
529 
530 char *fmt_node_location(source_config_t config, const node_t *node)
531 {
532  const scan_t *scan = node_get_scan(node);
533  const char *path = scan_is_builtin(scan) ? NULL : scan_path(scan);
534  where_t where = node_get_location(node);
535 
536  return fmt_source_location(config, path, where);
537 }
STA_DECL char * colour_format(format_context_t context, colour_t idx, const char *fmt,...)
Definition: colour.c:65
CT_NODISCARD CT_PUREFN CT_SCAN_API const char * scan_path(const scan_t *scan)
get the path of a scanner
Definition: scan.c:56
CT_NODISCARD CT_PUREFN CT_SCAN_API text_view_t scan_source(const scan_t *scan)
get a text span of the scanners contents
Definition: scan.c:96
CT_NODISCARD size_t size
Definition: scan.h:128
CT_NODISCARD CT_PUREFN CT_SCAN_API bool scan_is_builtin(const scan_t *scan)
check if a scanner is the builtin scanner
Definition: scan.c:41
STA_DECL int text_report(typevec_t *events, report_config_t config, const char *title)
Definition: common_extra.c:416
colour_t get_severity_colour(severity_t severity)
Definition: common_extra.c:52
text_cache_t * cache_emplace_file(cache_map_t *map, const char *path)
Definition: common_extra.c:275
#define COLOUR_FATAL
Definition: common_extra.c:25
#define COLOUR_WARN
Definition: common_extra.c:26
#define COLOUR_SORRY
Definition: common_extra.c:23
#define COLOUR_UNKNOWN
Definition: common_extra.c:22
bool node_has_line(const node_t *node)
Definition: common_extra.c:129
void cache_map_delete(cache_map_t *map)
Definition: common_extra.c:262
const char * get_severity_name(severity_t severity)
Definition: common_extra.c:38
#define COLOUR_INFO
Definition: common_extra.c:27
void segments_sort(typevec_t *segments)
Definition: common_extra.c:90
typevec_t * all_segments_in_scan(const typevec_t *segments, const node_t *node, arena_t *arena)
Definition: common_extra.c:95
text_cache_t * cache_emplace_scan(cache_map_t *map, const scan_t *scan)
Definition: common_extra.c:295
size_t get_line_number(file_config_t config, const node_t *node)
Definition: common_extra.c:121
size_t cache_count_lines(text_cache_t *cache)
Definition: common_extra.c:327
severity_t get_severity(const diagnostic_t *diag, bool override_fatal)
Definition: common_extra.c:30
char * fmt_node_location(source_config_t config, const node_t *node)
Definition: common_extra.c:530
#define COLOUR_INTERNAL
Definition: common_extra.c:24
text_t cache_escape_line(text_cache_t *cache, size_t line, const colour_pallete_t *colours, size_t column_limit)
Definition: common_extra.c:355
text_view_t cache_get_line(text_cache_t *cache, size_t line)
Definition: common_extra.c:310
cache_map_t * cache_map_new(size_t size, arena_t *arena)
Definition: common_extra.c:251
#define STA_DECL
sal2 annotation on function implementations to copy annotations from the declaration
CT_NODISCARD CT_PUREFN CT_BASE_API size_t ctu_strlen(const char *str)
get the length of a string not including the null terminator equivalent to strlen but with safety che...
Definition: util.c:87
CT_CONSTFN CT_BASE_API text_view_t text_view_make(STA_READS(length) const char *text, size_t length)
create a new non-owning text array text must be at least length bytes long
CT_PUREFN CT_BASE_API text_view_t text_view_from(const char *text)
create a new non-owning text array this is a shortcut for
Definition: util.c:191
colour_t
a colour code
Definition: colour.h:23
STA_RET_STRING CT_PUREFN CT_FORMAT_API const char * colour_get(const colour_pallete_t *colours, colour_t idx)
get a colours string form from a pallete
Definition: colour.c:39
STA_RET_STRING CT_PUREFN CT_FORMAT_API const char * colour_reset(const colour_pallete_t *colours)
get a reset string from a pallete
Definition: colour.c:48
#define CT_EXIT_OK
no user errors or internal errors
Definition: macros.h:91
#define CT_EXIT_INTERNAL
internal compiler errors have occurred
Definition: macros.h:94
#define CT_EXIT_ERROR
the user has made an error
Definition: macros.h:92
CT_MEMORY_API arena_t * get_global_arena(void)
get the global memory arena
Definition: memory.c:16
CT_NODISCARD CT_STD_API map_t * map_optimal(size_t size, hash_info_t info, arena_t *arena)
create a new map with an optimal size
Definition: optimal.c:85
#define CTU_MAP_NEXT(iter, key, value)
get the next key-value pair from a map iterator
Definition: map.h:250
CT_NODISCARD CT_PUREFN CT_STD_API map_iter_t map_iter(const map_t *map)
create a new map iterator
Definition: map.c:456
CT_STD_API void map_set(map_t *map, const void *key, void *value)
set a key-value pair in a map
Definition: map.c:294
CT_NODISCARD CT_PUREFN CT_STD_API void * map_get(const map_t *map, const void *key)
get a value from a map
Definition: map.c:324
CT_NODISCARD CT_PUREFN CT_STD_API bool set_contains(const set_t *set, const void *key)
check if a set contains a key
Definition: set.c:118
CT_NODISCARD CT_IO_API io_t * io_file(const char *path, os_access_t mode, arena_t *arena)
create an IO object from a file
Definition: file.c:125
CT_NODISCARD CT_IO_API os_error_t io_error(const io_t *io)
get the last error from the io object
Definition: io.c:144
CT_IO_API os_error_t io_close(INOUT_NOTNULL io_t *io)
destroy an IO object
CT_NODISCARD CT_IO_API size_t io_size(io_t *io)
get the total size of an io objects contents
Definition: io.c:94
CT_IO_API size_t io_printf(io_t *io, STA_FORMAT_STRING const char *fmt,...)
printf to an io object
CT_NODISCARD CT_IO_API const char * io_name(const io_t *io)
get the name of an io object
Definition: io.c:112
CT_NODISCARD CT_IO_API void * io_map(io_t *io, os_protect_t protect)
map an io object into memory maps an io objects entire contents into memory.
Definition: io.c:120
CT_NODISCARD CT_PUREFN CT_SCAN_API const scan_t * node_get_scan(const node_t *node)
get the associated source file of a node
Definition: node.c:57
CT_NODISCARD CT_PUREFN CT_SCAN_API bool node_is_builtin(const node_t *node)
check if a node is the builtin node
Definition: node.c:23
CT_NODISCARD CT_PUREFN CT_SCAN_API where_t node_get_location(const node_t *node)
get the location of a node inside its source file
Definition: node.c:65
#define CT_MAX(L, R)
Definition: macros.h:34
#define ARENA_MALLOC(size, name, parent, arena)
allocate memory from a custom allocator
Definition: arena.h:392
CT_ARENA_API void arena_free(STA_RELEASE void *ptr, size_t size, arena_t *arena)
release memory from a custom allocator
severity_t
the default severity of a diagnostic
Definition: diagnostic.h:18
#define CTASSERT(expr)
assert a condition, prints the condition as a message
Definition: panic.h:130
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
Definition: panic.h:116
CT_PUREFN CT_STD_API size_t str_find(const char *str, const char *sub)
find the first instance of a substring in a string
Definition: str.c:896
CT_NODISCARD CT_STD_API char * str_join(const char *sep, const vector_t *parts, arena_t *arena)
join strings
Definition: str.c:274
CT_NODISCARD STA_FORMAT_STRING const char * fmt
Definition: str.h:68
CT_STD_API const hash_info_t kTypeInfoString
type information for a c style string
Definition: typeinfo.c:35
CT_STD_API void typevec_sort(typevec_t *vec, int(*cmp)(const void *, const void *))
sort a vector
Definition: vector.c:206
CT_STD_API void * typevec_push(typevec_t *vec, const void *src)
push a value onto the vector
Definition: vector.c:156
CT_NODISCARD CT_PUREFN CT_STD_API size_t typevec_len(const typevec_t *vec)
get the length of a vector
Definition: vector.c:120
CT_NODISCARD CT_PUREFN CT_STD_API void * typevec_data(const typevec_t *vec)
get a pointer to the underlying data
Definition: vector.c:199
CT_STD_API void typevec_append(typevec_t *vec, const void *src, size_t len)
append multiple values onto the vector
Definition: vector.c:169
CT_NODISCARD CT_STD_API typevec_t * typevec_new(size_t width, size_t len, arena_t *arena)
create a new typed vector on the heap
Definition: vector.c:77
CT_NODISCARD CT_PUREFN CT_STD_API void * typevec_offset(const typevec_t *vec, size_t index)
get a pointer to the value at the given index
Definition: vector.c:191
CT_NODISCARD CT_STD_API vector_t * vector_new(size_t size, arena_t *arena)
create a new vector with an initial capacity
Definition: vector.c:63
CT_STD_API void vector_push(vector_t **vector, void *value)
push a value onto the end of a vector
Definition: vector.c:108
an allocator object
Definition: arena.h:86
arena_t * arena
Definition: common_extra.c:136
map_t * map
Definition: common_extra.c:137
a colour pallete
Definition: colour.h:39
a diagnostic
Definition: diagnostic.h:27
severity_t severity
the severity of the diagnostic
Definition: diagnostic.h:29
an event handle TODO: make this and segment_t opaque
Definition: notify.h:36
the configuration for a file
Definition: notify.h:49
bool override_fatal
if true all warnings are treated as fatal
Definition: notify.h:58
bool zeroth_line
the zeroth line of a file is the first line
Definition: notify.h:51
a formatting context when using colours
Definition: colour.h:46
arena_t * arena
Definition: colour.h:47
io object implementation
Definition: impl.h:122
size_t offset
Definition: common_extra.c:142
size_t length
Definition: common_extra.c:143
a map iterator handle
Definition: map.h:183
an unordered hash map
Definition: map.h:38
a position in a source file
Definition: node.h:23
size_t max_errors
Definition: notify.h:86
size_t max_warnings
Definition: notify.h:87
text_config_t text_config
Definition: notify.h:93
set_t * ignore_warnings
Definition: notify.h:89
set_t * error_warnings
Definition: notify.h:90
text_format_t report_format
Definition: notify.h:92
a source file scanner
Definition: scan.h:24
a segment inside an event
Definition: notify.h:57
node_t node
the related node
Definition: notify.h:59
an unordered hash set
Definition: set.c:19
text_view_t source
Definition: common_extra.c:151
arena_t * arena
Definition: common_extra.c:148
typevec_t * line_info
Definition: common_extra.c:153
map_t * cached_lines
Definition: common_extra.c:155
io_t * io
Definition: notify.h:81
const colour_pallete_t * colours
Definition: notify.h:78
file_config_t config
Definition: notify.h:75
cache_map_t * cache
a shared cache between all reports, set to NULL to disable caching
Definition: notify.h:72
a range of text
Definition: text.h:14
size_t length
the number of characters in the text
Definition: text.h:19
a non-owning view of text
Definition: text.h:24
size_t length
the number of characters in the text
Definition: text.h:30
A vector with a fixed type size.
Definition: vector.h:24
a generic vector of pointers
Definition: vector.c:16
a location inside a scanner locations are inclusive and 0-based
Definition: where.h:23
ctu_column_t first_column
the first column of the location
Definition: where.h:31
ctu_line_t first_line
the first line of the location
Definition: where.h:25
text_format_t
Definition: notify.h:62
@ eTextComplex
complex text reporting
Definition: notify.h:64
CT_FORMAT_API void text_report_simple(text_config_t config, const event_t *event)
Definition: text_simple.c:162
CT_FORMAT_API void text_report_rich(text_config_t config, const event_t *event)
Definition: text_rich.c:528
char * fmt_source_location(source_config_t config, const char *path, where_t where)
Definition: common.c:124