1 /* 2 * Template output. 3 * 4 * Copyright (C) 2019, 2020, 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #pragma once 23 24 /* Filename definitions. */ 25 26 #define client_filename_c "%s/%s_client.c" 27 #define client_filename_cpp "%s/%s_client.cc" 28 #define client_header_filename "%s/%s_client.h" 29 #define interface_filename "%s/%s_interface.h" 30 #define server_filename_c "%s/%s_server.c" 31 #define server_filename_cpp "%s/%s_server.cc" 32 #define server_header_filename "%s/%s_server.h" 33 34 35 36 /* Client templates. */ 37 38 #define client_prologue \ 39 "#include \"%s_client.h\"\n" \ 40 "#include <ipc/message.h>\n" 41 42 #define client_function_body_prologue \ 43 " ipc_message_t msg;\n" \ 44 " long err;\n" 45 46 #define client_function_body_endpoint_conversion_c \ 47 " %s _endp = _self.cap;\n" 48 49 #define client_function_body_call \ 50 "\n ipc_message_request(&msg, %s, %s);\n\n" \ 51 " err = l4_error(msg.tag);\n" \ 52 " if (err)\n" \ 53 " return err;\n" 54 55 #define client_function_body_call_oneway \ 56 "\n ipc_message_send(&msg, %s, %s);\n\n" \ 57 " err = l4_error(msg.tag);\n" \ 58 " if (err)\n" \ 59 " return err;\n" 60 61 #define client_function_body_epilogue \ 62 "\n ipc_message_free(&msg);\n" \ 63 " return L4_EOK;\n" 64 65 /* Client interface definitions for C++. */ 66 67 #define client_interface_prologue_cpp \ 68 " : public %s" 69 70 #define client_interface_endpoint_declaration_cpp \ 71 "protected:\n" \ 72 " %s _endp;\n\n" 73 74 #define client_interface_constructor_cpp \ 75 "\n %s(%s endp) : _endp(endp) { }\n" 76 77 /* Client interface definitions for C. */ 78 79 #define client_interface_declaration_c \ 80 "\nextern iface_%s client_iface_%s;\n" 81 82 #define client_interface_prologue_empty_c \ 83 "\niface_%s client_iface_%s;" 84 85 #define client_interface_prologue_c \ 86 "\niface_%s client_iface_%s = {" 87 88 #define client_interface_member_c \ 89 "\n .%s = %s," 90 91 #define client_interface_epilogue_c \ 92 "\n};\n" 93 94 95 96 /* Compound interface definitions. */ 97 98 #define compound_interface_include \ 99 "#include \"%s_interface.h\"\n" 100 101 #define compound_ref_type_definition_prologue_c \ 102 "\ntypedef struct {\n" \ 103 " union {\n" \ 104 " %s cap;\n" \ 105 " void *ptr;\n" \ 106 " };\n" 107 108 #define compound_ref_type_definition_member_c \ 109 " ref_%s as_%s;\n" 110 111 #define compound_ref_type_definition_epilogue_c \ 112 "} ref_%s;\n" 113 114 #define compound_interface_conversion_c \ 115 "\n#define convert_to_%s(_self) (&((%s) {.iface=_self->iface->to_%s, .ref=_self->ref.as_%s}))\n" 116 117 #define compound_interface_conversion_cpp \ 118 "\n#define convert_to_%s(_self) (_self)\n" 119 120 121 122 /* Dispatch functions. */ 123 124 #define dispatch_function_signature \ 125 "\nvoid dispatch_%s(ipc_message_t *msg, %s *_self)" 126 127 #define dispatch_function_prologue \ 128 " long err;\n\n" 129 130 #define dispatch_function_test_protocol \ 131 " if (l4_msgtag_label(msg->tag) != %s)\n" \ 132 " {\n" \ 133 " ipc_message_send_error(msg, -L4_EBADPROTO);\n" \ 134 " return;\n" \ 135 " }\n" 136 137 #define dispatch_function_label_dispatcher \ 138 " switch (l4_msgtag_label(msg->tag))\n" \ 139 " {\n" 140 141 #define dispatch_function_word_dispatcher \ 142 " switch (ipc_message_get_word(msg, 0))\n" \ 143 " {\n" 144 145 /* Dispatch templates. */ 146 147 #define dispatch_function_case_prologue \ 148 " case %s:\n" 149 150 #define dispatch_function_case_epilogue \ 151 " break;\n\n" 152 153 #define dispatch_function_interface_case \ 154 " case %s:\n" \ 155 " dispatch_%s(msg, %s);\n" \ 156 " break;\n\n" 157 158 #define dispatch_function_wrapper_case \ 159 " case %s:\n" \ 160 " ipc_message_send_error(msg, %s_%s(msg, %s));\n" \ 161 " break;\n\n" 162 163 #define dispatch_function_oneway_wrapper_case \ 164 " case %s:\n" \ 165 " err = %s_%s(msg, %s);\n" \ 166 " (void) err;\n" \ 167 " break;\n\n" 168 169 #define dispatch_function_reply_wrapper_case \ 170 " case %s:\n" \ 171 " err = %s_%s(msg, %s);\n" \ 172 " ipc_message_send_error(msg, err != IPC_MESSAGE_SENT ? err : (long) L4_EOK);\n" \ 173 " if (err != IPC_MESSAGE_SENT)\n" \ 174 " ipc_message_reply(msg);\n" \ 175 " break;\n\n" 176 177 #define dispatch_function_default_case \ 178 " default:\n" \ 179 " ipc_message_send_error(msg, -L4_EBADPROTO);\n" \ 180 " ipc_message_reply(msg);\n" \ 181 " break;\n" 182 183 #define dispatch_function_dispatcher_epilogue \ 184 " }\n" 185 186 187 188 /* Message handling functions. */ 189 190 #define handle_function_signature \ 191 "\nvoid handle_%s(ipc_message_t *msg, %s *_self)" 192 193 #define handle_function \ 194 " ipc_message_open(msg);\n" \ 195 " dispatch_%s(msg, _self);\n" \ 196 " ipc_message_discard(msg);\n" 197 198 199 200 /* General header templates. */ 201 202 #define header_prologue \ 203 "#ifndef __%s__%s__\n" \ 204 "#define __%s__%s__\n\n" \ 205 "#include <l4/sys/err.h>\n" \ 206 "#include <l4/sys/types.h>\n" 207 208 #define header_epilogue \ 209 "#endif\n" 210 211 212 213 /* Server templates. */ 214 215 #define server_header_prologue \ 216 "#ifndef __SERVER__%s__\n" \ 217 "#define __SERVER__%s__\n\n" \ 218 "#include <ipc/message.h>\n" \ 219 "#include <ipc/server.h>\n" 220 221 #define server_prologue \ 222 "#include \"%s_server.h\"\n" 223 224 #define server_config_instance_declaration \ 225 "\nextern ipc_server_default_config_type config_%s;\n" 226 227 #define server_config_instance \ 228 "\nipc_server_default_config_type config_%s = {\n" \ 229 " %s_expected_items, (ipc_server_handler_type) handle_%s};\n" 230 231 /* Server wrapper function templates. */ 232 233 #define server_function_signature \ 234 "\nlong %s_%s(ipc_message_t *msg, %s *_self)" 235 236 #define server_function_body_prologue \ 237 " long err;\n" 238 239 #define server_function_body_unused_message \ 240 "\n (void) msg;\n" 241 242 #define server_function_body_call \ 243 " if (err)\n" \ 244 " return err;\n" 245 246 #define server_function_body_epilogue \ 247 "\n return L4_EOK;\n" 248 249 #define server_completion_function_signature_prologue \ 250 "\nlong complete_%s(l4_cap_idx_t _endp" 251 252 #define server_completion_optional_function_signature_prologue \ 253 "\nlong complete_%s(" 254 255 #define server_completion_function_body_prologue \ 256 " ipc_message_t msg;\n" 257 258 #define server_completion_function_body_epilogue \ 259 "\n ipc_message_send(&msg, %s, %s);\n\n" \ 260 " return l4_error(msg.tag);\n" 261 262 #define server_completion_optional_function_body_epilogue \ 263 "\n ipc_message_reply(&msg);\n\n" \ 264 " return l4_error(msg.tag);\n" 265 266 #define server_initiation_function_body_epilogue \ 267 "\n ipc_message_prepare(msg);\n\n" \ 268 " return L4_EOK;\n" 269 270 271 272 /* Interface class definitions. */ 273 274 #define interface_prologue_cpp \ 275 "\n#ifdef __cplusplus\n" \ 276 "\nclass %s" 277 278 #define interface_prologue_base_cpp \ 279 "%spublic %s" 280 281 #define interface_prologue_c \ 282 "\ntypedef struct" \ 283 284 #define interface_body_begin \ 285 "\n{\n" 286 287 #define interface_body_base_c \ 288 " iface_%s *to_%s;\n" 289 290 #define interface_signatures_prologue_cpp \ 291 "public:" 292 293 #define interface_epilogue_cpp \ 294 "};\n\n" \ 295 "#endif /* __cplusplus */\n" 296 297 #define interface_epilogue_c \ 298 "\n} iface_%s;\n" 299 300 #define interface_function_signature_prologue \ 301 "\n%slong %s(" 302 303 #define interface_struct_member_function_signature_prologue \ 304 " long (*%s)(" 305 306 #define interface_unimplemented_method_prologue_cpp \ 307 "\n {" 308 309 #define interface_unimplemented_method_epilogue_cpp \ 310 " return -L4_EBADPROTO; }\n" 311 312 #define interface_unused_parameter \ 313 " (void) %s;" 314 315 /* Reference and object type definitions for interfaces. */ 316 317 #define ref_type_definition_c \ 318 "\ntypedef union { %s cap; void *ptr; } ref_%s;\n" 319 320 #define object_type_definition_c \ 321 "\ntypedef struct\n" \ 322 "{\n" \ 323 " ref_%s ref;\n" \ 324 " iface_%s *iface;\n" \ 325 "\n} %s;\n" 326 327 #define expected_items_definition \ 328 "\n#define %s_expected_items %d\n" 329 330 331 332 /* Opcode definitions. */ 333 334 #define opcode_enumeration_prologue \ 335 "\nenum opcodes_%s\n{\n" 336 337 #define opcode_identifier \ 338 " opcode_%s_%s" 339 340 #define opcode_enumeration_epilogue \ 341 "};\n" 342 343 /* Message structure definitions. */ 344 345 #define structure_prologue \ 346 "\nstruct %s_words_%s\n{\n" 347 348 #define structure_opcode_member \ 349 " %s _op;\n" 350 351 #define structure_epilogue \ 352 "};\n" 353 354 /* Message access templates. */ 355 356 #define message_accessor_declaration \ 357 " struct %s_words_%s *%s_words;\n" 358 359 #define message_accessor_initialisation \ 360 "\n %s_words = (struct %s_words_%s *)" 361 362 #define message_accessor_reading_initialiser \ 363 " ipc_message_get_word_address(%smsg, 0);\n" 364 365 #define message_accessor_writing_initialiser \ 366 " ipc_message_reserve_words(%smsg, sizeof(struct %s_words_%s));\n" 367 368 369 370 /* Tokens. */ 371 372 #define BEGIN_FUNCTION "\n{\n" 373 #define END_FUNCTION "}\n" 374 375 #define COMPLETE_MEMBER ";\n" 376 #define INDENT_MEMBER " " 377 378 #define COMPLETE_SIGNATURE ";\n" 379 #define END_SIGNATURE "\n" 380 381 382 383 /* Texts. */ 384 385 #define help_text \ 386 "Usage: %s [ <options> ] <filename> ...\n\n" \ 387 "Generate source code for the interfaces in the supplied files.\n\n" \ 388 "The following options are supported:\n\n" \ 389 "--all or -a Produce all kinds of output for a given language.\n\n" \ 390 "--client or -c Generate client code.\n\n" \ 391 "--dir or -d Create output in the indicated directory.\n\n" \ 392 "--files or -f Only show processed filenames, produce no files.\n\n" \ 393 "--headers or -h Produce header files.\n\n" \ 394 "--help or -? Show this message.\n\n" \ 395 "--interfaces or -i Produce interface header files.\n\n" \ 396 "--language or -l Generate code in the indicated language.\n\n" \ 397 "--recursive or -R Also generate code for any base interfaces.\n\n" \ 398 "--routines or -r Produce program routines.\n\n" \ 399 "--server or -s Generate server code.\n\n" \ 400 "--verbose or -v Show verbose output reporting the processed interfaces.\n\n" \ 401 "--version or -V Show version information.\n\n"