20 #include <tool_config.h>
35 .desc =
"Notification testing tool",
36 .author =
"Elliot Haisley",
42 .brief =
"Notification testing options",
49 .brief =
"Print a backtrace",
50 .args =
CT_ARGS(kBacktraceArgs),
58 #define NOTIFY_OPTION_COUNT (sizeof(kNotifyOptions) / sizeof(cfg_choice_t))
64 .brief =
"Notification style",
71 .
name =
"zero_indexed",
72 .brief =
"Print zero indexed line numbers",
73 .args =
CT_ARGS(kZeroIndexedArgs),
84 .options = kNotifyOptions,
95 .test_backtrace = test_backtrace,
96 .notify_style = notify_style,
97 .zero_indexed = zero_indexed,
106 "module multi.lhs;\n"
108 "import multi.rhs,\n"
114 " if x < LIMIT then\n"
120 "module multi.rhs;\n"
122 "import multi.lhs,\n"
128 " if x < LIMIT then\n"
136 "import multi.lhs,\n"
139 "const LIMIT = 25;\n"
155 .brief =
"Test diagnostic at info level",
157 "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
158 "Sed non risus. Suspendisse lectus tortor, dignissim sit amet,\n"
159 "adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam.\n"
160 "Maecenas ligula massa, varius a, semper congue, euismod non, mi.\n"
161 "Proin porttitor, orci nec nonummy molestie, enim est eleifend mi,\n"
162 "non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa,\n"
163 "scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue.\n"
169 .brief =
"Undefined function name",
171 "A function name must be visible in the current scope\n"
172 "to be used in a call expression or statement.\n"
178 .brief =
"Unresolved import",
180 "An import statement must refer to a valid module.\n"
181 "The module must be visible in the current scope.\n"
187 .brief =
"Reserved name",
189 "A reserved name cannot be used as an identifier.\n"
190 "Reserved names are keywords and builtin names.\n"
196 msg_append(event, builtin,
"hello %s",
"world");
228 event_builder_t event =
msg_notify(logs, &kUndefinedFunctionName, node,
"function `%s` is undefined in the current context",
"lhs");
229 msg_note(event,
"did you mean `%s`?",
"rhs");
230 msg_append(event, node,
"function called here");
231 msg_append(event, node,
"function called here but with a different message");
232 msg_append(event, node2,
"function defined here");
259 msg_note(event,
"did you mean `%s`?",
"multi.rhs");
260 msg_note(event,
"did you mean `%s`?",
"multi.rhx");
261 msg_append(event, node,
"import statement here");
262 msg_append(event, node2,
"module declaration here");
277 msg_append(event, node,
"procedure declaration here");
278 msg_note(event,
"did you mean `%s`?",
"main");
281 static scan_t *scan_string(
const char *name,
const char *lang,
const char *source,
arena_t *arena)
284 return scan_io(lang, io, arena);
298 do_print_backtrace(config, arena);
302 return recurse(x - 1, config, arena);
309 do_print_backtrace(config, arena);
313 return recurse(x - 1, config, arena);
318 return rec3(x, config, arena);
325 return inner(y, config, arena);
328 return rec2(x - 1, y, config, arena);
339 do_print_backtrace(config, arena);
343 return recurse_middle(x - 1, config, arena);
350 do_print_backtrace(config, arena);
354 return recurse_tail(x - 1, config, arena);
361 do_print_backtrace(config, arena);
365 return recurse_head(x - 1, config, arena);
370 io_printf(io,
"\n=== backtrace ===\n\n");
372 const char *source_root = TOOL_ROOT;
374 io_printf(io,
"source root: %s\n\n", source_root);
384 .header = eHeadingGeneric,
385 .config = eBtZeroIndexedLines,
386 .project_source_path = source_root,
391 .header = eHeadingMicrosoft,
392 .config = eBtZeroIndexedLines,
393 .project_source_path = source_root,
399 rec2(200, 100, config1, arena);
400 rec2(5, 100, config2, arena);
402 recurse_head(25, config1, arena);
405 int main(
int argc,
const char **argv)
411 tool_t tool = make_config(arena);
449 .zero_indexed_lines = zero_indexed,
458 do_backtrace(con, arena);
CT_NODISCARD CT_SCAN_API scan_t * scan_io(const char *language, io_t *io, arena_t *arena)
create a scanner from an io source
int main(int argc, const char **argv)
CT_FORMAT_API const colour_pallete_t kColourDefault
a colour pallete that applies ANSI VT100 colours
CT_CONFIG_API cfg_field_t * config_enum(cfg_group_t *group, const cfg_info_t *info, cfg_enum_t cfg)
add a new choice field to a configuration group
CT_CONFIG_API cfg_field_t * config_bool(cfg_group_t *group, const cfg_info_t *info, bool initial)
add a new yes/no field to a configuration group
CT_PUREFN CT_CONFIG_API bool cfg_bool_value(const cfg_field_t *field)
get the current boolean value of a configuration field
CT_PUREFN CT_CONFIG_API size_t cfg_enum_value(const cfg_field_t *field)
get the current enum value of a configuration field
#define CT_ARG_LONG(name)
CT_CONFIG_API cfg_group_t * config_root(const cfg_info_t *info, arena_t *arena)
create a new configuration group
#define CT_ARG_SHORT(name)
#define CT_NEW_VERSION(major, minor, patch)
creates a new ctu_version_t from major, minor and patch
CT_MEMORY_API arena_t * get_global_arena(void)
get the global memory arena
CT_NODISCARD CT_IO_API io_t * io_string(const char *name, const char *string, arena_t *arena)
create an IO view of a string create a readonly IO view of a string
CT_IO_API os_error_t io_close(INOUT_NOTNULL io_t *io)
destroy an IO object
CT_IO_API io_t * io_stdout(void)
get the global stdout IO object
CT_IO_API size_t io_printf(io_t *io, STA_FORMAT_STRING const char *fmt,...)
printf to an io object
CT_NODISCARD CT_SCAN_API node_t * node_builtin(const char *name, arena_t *arena)
get the builtin node node used for drivers that declare builtin symbols
CT_NODISCARD CT_SCAN_API node_t * node_new(const scan_t *scan, where_t where)
create a new node on the heap
CT_NOTIFY_API event_builder_t msg_notify(INOUT_NOTNULL logger_t *logs, const diagnostic_t *diagnostic, const node_t *node, STA_FORMAT_STRING const char *fmt,...)
notify the logger of a new message
CT_NOTIFY_API void msg_append(event_builder_t builder, const node_t *node, STA_FORMAT_STRING const char *fmt,...)
append additional information to a message
CT_NODISCARD CT_NOTIFY_API logger_t * logger_new(arena_t *arena)
create a new logger
CT_NOTIFY_API void msg_note(event_builder_t builder, STA_FORMAT_STRING const char *fmt,...)
add a note to an existing message
CT_NODISCARD CT_NOTIFY_API typevec_t * logger_get_events(const logger_t *logs)
get the events from the logger
CT_SETUP_API setup_init_t setup_parse(int argc, const char **argv, setup_options_t setup)
parse the command line
CT_PUREFN CT_SETUP_API bool setup_should_exit(const setup_init_t *init)
accessor functions
CT_SETUP_API void setup_default(arena_t *arena)
initialise the runtime with default options
CT_SETUP_API setup_options_t setup_options(version_info_t info, cfg_group_t *root)
setup default options
CT_PUREFN CT_SETUP_API int setup_exit_code(const setup_init_t *init)
get the exit code
a backtrace report context
a choice in a set of options
STA_FIELD_STRING const char * text
the name of this choice
a choice from a set of options
information about a configuration field
STA_FIELD_STRING const char * name
the name of this field
severity_t severity
the severity of the diagnostic
an event builder handles adding additional information to an event
printing options for a stacktrace
print_options_t options
basic print options
arena_t * arena
temporary arena
a position in a source file
notification formatting options
print_options_t options
base print options
the result of parsing the command line
const colour_pallete_t * pallete
the chosen colour pallete
heading_style_t heading
the chosen heading style
default options shared by all tools
A vector with a fixed type size.
version information for a driver/interface/plugin
const char * license
the license of this component
a location inside a scanner locations are inclusive and 0-based
ctu_line_t first_line
the first line of the location
#define NOTIFY_OPTION_COUNT
void event_invalid_import(logger_t *logs, scan_t *scan, scan_t *scan_rhs)
int recurse(int x, fmt_backtrace_t config, arena_t *arena)
const char *const kSampleSourceMain
void event_missing_call(logger_t *logs, scan_t *scan_main, scan_t *scan_lhs, const node_t *builtin)
void event_invalid_function(logger_t *logs, scan_t *scan)
const char *const kSampleSourceLeft
void event_simple(logger_t *logs, const node_t *builtin)
const char *const kSampleSourceRight