1 /* 2 * Generation of interface headers. 3 * 4 * Copyright (C) 2019 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 #include <stdlib.h> 23 #include "client.h" 24 #include "common.h" 25 #include "config.h" 26 #include "declaration.h" 27 #include "includes.h" 28 #include "interface.h" 29 #include "server.h" 30 #include "structure.h" 31 #include "templates.h" 32 33 34 35 /* Write the definition of an interface to the given file for use by client or 36 server components. Client headers employ such definitions as do server 37 interface headers, whereas server wrapper headers employ other descriptions 38 of their operations. */ 39 40 void write_interface_definition(struct interface *iface, 41 enum component_role component, FILE *fp) 42 { 43 int cpp = (conf.language == CPP_LANGUAGE); 44 int client = (component == CLIENT_ROLE); 45 int input_items = get_max_input_items(iface->signatures); 46 char *class_name = get_interface_class_name(iface, component); 47 char *name = iface->name; 48 49 /* Emit include statements. */ 50 51 write_includes_separator(iface->includes, fp); 52 write_includes(iface->includes, fp); 53 54 /* Emit include for compound interface types. */ 55 56 if (conf.compound != NULL) 57 write_include(conf.compound, "_interface_types.h", fp); 58 59 /* Generate interface abstractions. */ 60 61 if (!cpp) 62 { 63 /* Define an object reference type for C. */ 64 65 if (!client) 66 { 67 fprintf(fp, ref_type_definition_prologue_c); 68 69 /* Provide a compound reference member for conversions. */ 70 71 if (conf.compound_name != NULL) 72 fprintf(fp, ref_type_definition_compound_member_c, conf.compound_name); 73 74 fprintf(fp, ref_type_definition_epilogue_c, L4_CAP_TYPE, name); 75 } 76 77 /* Define C client signatures representing the client functions. */ 78 79 else 80 write_signatures(iface->signatures, DECLARATION_ROLE, 81 fp, iface, write_client_signature); 82 } 83 84 /* Begin any namespace, defining the class or type. 85 C++ code employs an abstract server interface and a concrete client 86 interface class. 87 C code only employs a server interface which is instantiated for client 88 use elsewhere by employing the client functions. */ 89 90 if (cpp || !client) 91 { 92 if (cpp) 93 { 94 fprintf(fp, interface_prologue_cpp, class_name); 95 96 /* Inherit from the actual interface in the client. */ 97 98 if (client) 99 fprintf(fp, client_interface_prologue_cpp, name); 100 } 101 else 102 fputs(interface_prologue_c, fp); 103 104 /* Start the class or type body. */ 105 106 fputs(interface_body_begin, fp); 107 108 /* Define any state and initialisation details of a class. */ 109 110 if (cpp) 111 { 112 if (client) 113 fprintf(fp, client_interface_endpoint_declaration_cpp, L4_CAP_TYPE); 114 115 fputs(interface_signatures_prologue_cpp, fp); 116 117 /* Define a constructor. */ 118 119 if (client) 120 fprintf(fp, client_interface_constructor_cpp, class_name, L4_CAP_TYPE); 121 } 122 123 /* Emit signatures. */ 124 125 write_signatures(iface->signatures, MEMBER_DECLARATION_ROLE, 126 fp, iface, 127 client ? write_client_signature 128 : write_server_interface_signature); 129 130 /* Terminate the class or type body. */ 131 132 if (cpp) 133 fputs(interface_epilogue_cpp, fp); 134 else 135 fprintf(fp, interface_epilogue_c, name); 136 } 137 138 /* Define the maximum number of expected items for the interface. */ 139 140 if (!client) 141 fprintf(fp, expected_items_definition, name, input_items); 142 143 /* Define an object type for C and declare a client interface. */ 144 145 if (!cpp && !client) 146 fprintf(fp, object_type_definition_c, name, name, name); 147 148 if (!cpp && client) 149 fprintf(fp, client_interface_declaration_c, name, name); 150 151 /* Emit opcodes and message access structures with the generic server 152 interface, these being common to both client and server. */ 153 154 if (!client) 155 { 156 write_opcode_definition(iface, fp); 157 write_structures(iface->signatures, fp, iface); 158 } 159 160 /* Emit a conversion macro for compound interface dispatch. */ 161 162 if (!cpp && !client) 163 fprintf(fp, compound_interface_conversion, name, name, name, name); 164 165 free(class_name); 166 }