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