Cthulhu  0.2.10
Cthulhu compiler collection
main.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-only
2 
19 
20 #include "config/config.h"
21 #include "core/macros.h"
22 #include "core/version_def.h"
23 #include "format/config.h"
24 #include "format/notify2.h"
25 #include "io/console.h"
26 #include "io/io.h"
27 #include "memory/memory.h"
28 #include "meta.h"
29 #include "notify/notify.h"
30 #include "os/os.h"
31 #include "setup/setup.h"
32 #include "std/vector.h"
33 #include "json/json.h"
34 
35 static const version_info_t kToolVersion = {
36  .license = "LGPLv3",
37  .author = "Elliot Haisley",
38  .desc = "Meta code generation tool",
39  .version = CT_NEW_VERSION(0, 0, 1),
40 };
41 
42 typedef struct tool_t
43 {
45 
48 
50 } tool_t;
51 
52 static const cfg_info_t kRootInfo = {
53  .name = "meta",
54  .brief = "meta code generation tool",
55 };
56 
57 static const cfg_arg_t kHeaderOutputArgs[] = { CT_ARG_LONG("header") };
58 
59 static const cfg_info_t kHeaderOutputInfo = {
60  .name = "header",
61  .brief = "output header file",
62  .args = CT_ARGS(kHeaderOutputArgs),
63 };
64 
65 static const cfg_arg_t kSourceOutputArgs[] = { CT_ARG_LONG("source") };
66 
67 static const cfg_info_t kSourceOutputInfo = {
68  .name = "source",
69  .brief = "output source file",
70  .args = CT_ARGS(kSourceOutputArgs),
71 };
72 
73 static tool_t make_tool(void)
74 {
75  arena_t *arena = get_global_arena();
76 
77  cfg_group_t *root = config_root(&kRootInfo, arena);
78  setup_options_t options = setup_options(kToolVersion, root);
79 
80  cfg_field_t *header = config_string(root, &kHeaderOutputInfo, NULL);
81  cfg_field_t *source = config_string(root, &kSourceOutputInfo, NULL);
82 
83  tool_t tool = {
84  .root = root,
85  .header_output = header,
86  .source_output = source,
87  .options = options,
88  };
89 
90  return tool;
91 }
92 
93 static void print_errors(io_t *io, setup_init_t setup, logger_t *logger, arena_t *arena)
94 {
95  print_notify_t config = {
96  .options = {
97  .arena = arena,
98  .io = io,
99  .pallete = setup.pallete,
100  },
101  .heading = setup.heading,
102  .style = eNotifyFull,
103  .zero_indexed_lines = false,
104  };
105 
106  print_notify_many(config, logger_get_events(logger));
107 }
108 
109 int main(int argc, const char **argv)
110 {
111  setup_default(NULL);
112  arena_t *arena = get_global_arena();
113  tool_t tool = make_tool();
114 
115  setup_init_t init = setup_parse(argc, argv, tool.options);
116  if (setup_should_exit(&init))
117  return setup_exit_code(&init);
118 
119  size_t len = vector_len(init.posargs);
120  if (len != 1)
121  return setup_exit_help(tool.options, &init);
122 
123  const char *input = vector_get(init.posargs, 0);
124 
125  io_t *err = io_stderr();
126  io_t *con = io_stdout();
127 
128  io_t *io = io_file(input, eOsAccessRead, arena);
129  os_error_t error = io_error(io);
130  if (error != eOsSuccess)
131  {
132  io_printf(err, "failed to open file %s: %s\n", input, os_error_string(error, arena));
133  return CT_EXIT_ERROR;
134  }
135 
136  logger_t *logger = logger_new(arena);
137 
138  json_parse_t parse = json_parse(io, logger, arena);
139  if (parse.root == NULL)
140  {
141  print_errors(err, init, logger, arena);
142  return CT_EXIT_ERROR;
143  }
144 
145  meta_info_t *info = meta_info_parse(parse.root, parse.scanner, logger, arena);
146  if (info == NULL)
147  {
148  print_errors(err, init, logger, arena);
149  return CT_EXIT_ERROR;
150  }
151 
152  text_view_t prefix = info->prefix;
153  io_printf(con, "prefix: %.*s\n", (int)prefix.length, prefix.text);
154 
155  size_t nodes = typevec_len(info->nodes);
156  for (size_t i = 0; i < nodes; i++)
157  {
158  meta_ast_t *ast = typevec_offset(info->nodes, i);
159  text_view_t ast_name = ast->name;
160  io_printf(con, "node: %.*s\n", (int)ast_name.length, ast_name.text);
161 
162  size_t fields = typevec_len(ast->fields);
163  for (size_t j = 0; j < fields; j++)
164  {
165  meta_field_t *field = typevec_offset(ast->fields, j);
166  text_view_t field_name = field->name;
167  io_printf(con, "field: %.*s\n", (int)field_name.length, field_name.text);
168  }
169  }
170 }
tool_t make_tool(version_info_t version, arena_t *arena)
Definition: cmd.c:121
CT_NODISCARD STA_RET_STRING CT_OS_API char * os_error_string(os_error_t error, arena_t *arena)
convert an os error code to a string
Definition: os.c:56
int main(int argc, const char **argv)
Definition: main.c:168
CT_CONFIG_API cfg_field_t * config_string(cfg_group_t *group, const cfg_info_t *info, const char *initial)
add a new string field to a configuration group
Definition: config.c:138
#define CT_ARGS(it)
Definition: config.h:57
#define CT_ARG_LONG(name)
Definition: config.h:55
CT_CONFIG_API cfg_group_t * config_root(const cfg_info_t *info, arena_t *arena)
create a new configuration group
Definition: config.c:97
#define CT_NEW_VERSION(major, minor, patch)
creates a new ctu_version_t from major, minor and patch
Definition: version_def.h:20
#define CT_EXIT_ERROR
the user has made an error
Definition: macros.h:92
CT_FORMAT_API void print_notify_many(print_notify_t config, const typevec_t *events)
format many events for printing
Definition: notify.c:111
@ eNotifyFull
print a more full event includes source text if as well as the location and message
Definition: notify2.h:31
CT_MEMORY_API arena_t * get_global_arena(void)
get the global memory arena
Definition: memory.c:16
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 io_t * io_stderr(void)
get the global stderr IO object
Definition: console.c:65
CT_IO_API io_t * io_stdout(void)
get the global stdout IO object
Definition: console.c:60
CT_IO_API size_t io_printf(io_t *io, STA_FORMAT_STRING const char *fmt,...)
printf to an io object
CT_JSON_API json_parse_t json_parse(io_t *io, logger_t *logger, arena_t *arena)
parse an io into a json value parse the contents of an io object into a json value
Definition: json.c:43
CT_NODISCARD CT_NOTIFY_API logger_t * logger_new(arena_t *arena)
create a new logger
Definition: notify.c:21
CT_NODISCARD CT_NOTIFY_API typevec_t * logger_get_events(const logger_t *logs)
get the events from the logger
Definition: notify.c:36
CT_SETUP_API setup_init_t setup_parse(int argc, const char **argv, setup_options_t setup)
parse the command line
Definition: setup.c:366
CT_SETUP_API int setup_exit_help(setup_options_t setup, const setup_init_t *init)
print the help message and exit
Definition: setup.c:450
CT_PUREFN CT_SETUP_API bool setup_should_exit(const setup_init_t *init)
accessor functions
Definition: setup.c:434
CT_SETUP_API void setup_default(arena_t *arena)
initialise the runtime with default options
Definition: setup.c:188
CT_SETUP_API setup_options_t setup_options(version_info_t info, cfg_group_t *root)
setup default options
Definition: setup.c:215
CT_PUREFN CT_SETUP_API int setup_exit_code(const setup_init_t *init)
get the exit code
Definition: setup.c:442
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_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_PUREFN CT_STD_API void * vector_get(const vector_t *vector, size_t index)
get a value from a vector
Definition: vector.c:134
CT_NODISCARD CT_PUREFN CT_STD_API size_t vector_len(const vector_t *vector)
get the length of a vector
Definition: vector.c:152
meta_info_t * meta_info_parse(json_t *json, scan_t *scan, logger_t *logger, arena_t *arena)
Definition: meta.c:99
@ eOsSuccess
Definition: posix.h:24
an allocator object
Definition: arena.h:86
information about a configuration field
Definition: config.h:69
STA_FIELD_STRING const char * name
the name of this field
Definition: config.h:71
arena_t * arena
temporary arena
Definition: format.h:37
io object implementation
Definition: impl.h:122
json_t * root
Definition: json.h:85
scan_t * scanner
Definition: json.h:84
a logging sink
Definition: notify.c:14
text_view_t name
Definition: meta.h:44
typevec_t * fields
Definition: meta.h:46
text_view_t name
Definition: meta.h:38
text_view_t prefix
Definition: meta.h:30
typevec_t * nodes
Definition: meta.h:33
notification formatting options
Definition: notify2.h:38
print_options_t options
base print options
Definition: notify2.h:40
the result of parsing the command line
Definition: setup.h:69
const colour_pallete_t * pallete
the chosen colour pallete
Definition: setup.h:82
vector_t * posargs
the parsed position arguments
Definition: setup.h:79
heading_style_t heading
the chosen heading style
Definition: setup.h:85
default options shared by all tools
Definition: setup.h:31
a non-owning view of text
Definition: text.h:24
size_t length
the number of characters in the text
Definition: text.h:30
Definition: cmd.h:14
cfg_field_t * header_output
Definition: main.c:46
cfg_field_t * source_output
Definition: main.c:47
setup_options_t options
Definition: cmd.h:31
cfg_group_t * root
Definition: main.c:44
version information for a driver/interface/plugin
Definition: version_def.h:48
const char * license
the license of this component
Definition: version_def.h:49