1.1 --- a/Makefile Sat Nov 09 00:44:59 2019 +0100
1.2 +++ b/Makefile Sat Nov 09 01:18:22 2019 +0100
1.3 @@ -1,6 +1,6 @@
1.4 # Original sources and final program.
1.5
1.6 -SOURCES = main.c common.c dispatch.c message.c program.c summary.c
1.7 +SOURCES = main.c client.c common.c declaration.c dispatch.c message.c program.c server.c structure.c summary.c
1.8 PROGRAM = idl
1.9
1.10 # Generated files from flex and bison.
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/client.c Sat Nov 09 01:18:22 2019 +0100
2.3 @@ -0,0 +1,167 @@
2.4 +/*
2.5 + * Client code generation.
2.6 + *
2.7 + * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
2.8 + *
2.9 + * This program is free software; you can redistribute it and/or
2.10 + * modify it under the terms of the GNU General Public License as
2.11 + * published by the Free Software Foundation; either version 2 of
2.12 + * the License, or (at your option) any later version.
2.13 + *
2.14 + * This program is distributed in the hope that it will be useful,
2.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.17 + * GNU General Public License for more details.
2.18 + *
2.19 + * You should have received a copy of the GNU General Public License
2.20 + * along with this program; if not, write to the Free Software
2.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
2.22 + * Boston, MA 02110-1301, USA
2.23 + */
2.24 +
2.25 +#include <stdlib.h>
2.26 +#include "client.h"
2.27 +#include "common.h"
2.28 +#include "declaration.h"
2.29 +#include "message.h"
2.30 +#include "templates.h"
2.31 +
2.32 +
2.33 +
2.34 +static void write_signature_end(FILE *fp)
2.35 +{
2.36 + fputs(";\n", fp);
2.37 +}
2.38 +
2.39 +/* Generate operation signature details for client use. */
2.40 +
2.41 +static void _write_client_signature(struct signature *sig, FILE *fp, struct interface *iface)
2.42 +{
2.43 + char *opname = get_operation_name(iface, sig);
2.44 +
2.45 + /* NOTE: Qualifier discarded for now. */
2.46 + /* Introduce an initial parameter for the endpoint. */
2.47 +
2.48 + fprintf(fp, "\nlong %s(%s _endp", opname, L4_CAP_TYPE);
2.49 + write_parameter_separator(sig->parameters, fp);
2.50 + write_parameters(sig->parameters, fp, SIGNATURE_ROLE);
2.51 + fputs(")", fp);
2.52 +
2.53 + free(opname);
2.54 +}
2.55 +
2.56 +/* Generate each operation signature or "function prototype" for client use. */
2.57 +
2.58 +void write_client_signature(struct signature *sig, FILE *fp, struct interface *iface)
2.59 +{
2.60 + _write_client_signature(sig, fp, iface);
2.61 + write_signature_end(fp);
2.62 +}
2.63 +
2.64 +/* Generate function source code for each operation signature. */
2.65 +
2.66 +void write_client_function(struct signature *sig, FILE *fp, struct interface *iface)
2.67 +{
2.68 + _write_client_signature(sig, fp, iface);
2.69 + fputs("\n{\n", fp);
2.70 + write_client_function_body(sig->parameters, fp, iface, sig);
2.71 + fputs("}\n", fp);
2.72 +}
2.73 +
2.74 +/* Generate a function body corresponding to an operation for client use. */
2.75 +
2.76 +void write_client_function_body(struct parameter *param, FILE *fp,
2.77 + struct interface *iface, struct signature *sig)
2.78 +{
2.79 + int input_words, input_items, output_words, output_items;
2.80 +
2.81 + /* With a protocol attribute, the opcode is the attribute value. Otherwise,
2.82 + it is the operation code. */
2.83 +
2.84 + char *opname = get_operation_name(iface, sig),
2.85 + *protocol = get_protocol(iface->attributes),
2.86 + *opcode = get_opcode_identifier(protocol, opname);
2.87 +
2.88 + /* Generate the prologue. */
2.89 +
2.90 + fputs(client_function_body_prologue, fp);
2.91 +
2.92 + /* Count the number of input words, items and output words. */
2.93 +
2.94 + count_parameters(param, &input_words, &input_items, &output_words, &output_items);
2.95 +
2.96 + /* Adjust the input words where a protocol is used as the opcode. */
2.97 +
2.98 + if (protocol != NULL)
2.99 + input_words++;
2.100 +
2.101 + /* Generate types parameterised with the qualified operation name. */
2.102 +
2.103 + write_accessor_declaration(input_words, output_words, opname, fp);
2.104 +
2.105 + /* Initialise the message. */
2.106 +
2.107 + fprintf(fp, "\n ipc_message_new(&msg);\n");
2.108 +
2.109 + /* Generate expected output item requirements. */
2.110 +
2.111 + if (output_items)
2.112 + fprintf(fp, " err = ipc_message_expect(&msg, %d);\n"
2.113 + " if (err)\n"
2.114 + " return err;\n", output_items);
2.115 +
2.116 + /* Populate input parameters in the message. Dereference function parameters
2.117 + acting as "inout" parameters. */
2.118 +
2.119 + if (input_words)
2.120 + {
2.121 + /* Reserve space for the words before any items, obtaining a pointer to the
2.122 + words. */
2.123 +
2.124 + write_accessor_initialisation(IN_PARAMETER, CLIENT_ROLE, opname, fp);
2.125 +
2.126 + if (protocol != NULL)
2.127 + fprintf(fp, " in_words->_op = %s;\n", opname);
2.128 +
2.129 + write_message_access(param, CLIENT_ROLE, IN_PARAMETER, WORD_CLASS, fp);
2.130 + }
2.131 +
2.132 + /* Do the same for items. */
2.133 +
2.134 + if (input_items)
2.135 + {
2.136 + fputs("\n", fp);
2.137 + write_message_access(param, CLIENT_ROLE, IN_PARAMETER, ITEM_CLASS, fp);
2.138 + }
2.139 +
2.140 + /* Send the request. */
2.141 +
2.142 + fprintf(fp, client_function_body_call, opcode);
2.143 +
2.144 + /* Retrieve output parameters from the message. */
2.145 +
2.146 + if (output_words)
2.147 + {
2.148 + write_accessor_initialisation(OUT_PARAMETER, CLIENT_ROLE, opname, fp);
2.149 + write_message_access(param, CLIENT_ROLE, OUT_PARAMETER, WORD_CLASS, fp);
2.150 + }
2.151 +
2.152 + /* Do the same for items. */
2.153 +
2.154 + if (output_items)
2.155 + {
2.156 + fputs("\n", fp);
2.157 + write_message_access(param, CLIENT_ROLE, OUT_PARAMETER, ITEM_CLASS, fp);
2.158 + }
2.159 +
2.160 + /* Return success. */
2.161 +
2.162 + fprintf(fp, "\n return L4_EOK;\n");
2.163 +
2.164 + /* Free allocated strings. */
2.165 +
2.166 + free(opname);
2.167 +
2.168 + if (protocol == NULL)
2.169 + free(opcode);
2.170 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/client.h Sat Nov 09 01:18:22 2019 +0100
3.3 @@ -0,0 +1,40 @@
3.4 +/*
3.5 + * Client code generation.
3.6 + *
3.7 + * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
3.8 + *
3.9 + * This program is free software; you can redistribute it and/or
3.10 + * modify it under the terms of the GNU General Public License as
3.11 + * published by the Free Software Foundation; either version 2 of
3.12 + * the License, or (at your option) any later version.
3.13 + *
3.14 + * This program is distributed in the hope that it will be useful,
3.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.17 + * GNU General Public License for more details.
3.18 + *
3.19 + * You should have received a copy of the GNU General Public License
3.20 + * along with this program; if not, write to the Free Software
3.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
3.22 + * Boston, MA 02110-1301, USA
3.23 + */
3.24 +
3.25 +#pragma once
3.26 +
3.27 +#include <stdio.h>
3.28 +#include "types.h"
3.29 +
3.30 +void write_client_signature(struct signature *sig, FILE *fp, struct interface *iface);
3.31 +
3.32 +void write_client_function(struct signature *sig, FILE *fp, struct interface *iface);
3.33 +
3.34 +void write_client_function_body(struct parameter *param, FILE *fp,
3.35 + struct interface *iface, struct signature *sig);
3.36 +
3.37 +void write_server_function(struct signature *sig, FILE *fp, struct interface *iface);
3.38 +
3.39 +void write_server_function_body(struct parameter *param, FILE *fp,
3.40 + struct interface *iface, struct signature *sig);
3.41 +
3.42 +void write_server_function_call(struct parameter *param, FILE *fp,
3.43 + struct interface *iface, struct signature *sig);
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/declaration.c Sat Nov 09 01:18:22 2019 +0100
4.3 @@ -0,0 +1,98 @@
4.4 +/*
4.5 + * Generation of declaration elements such as parameters and members.
4.6 + *
4.7 + * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
4.8 + *
4.9 + * This program is free software; you can redistribute it and/or
4.10 + * modify it under the terms of the GNU General Public License as
4.11 + * published by the Free Software Foundation; either version 2 of
4.12 + * the License, or (at your option) any later version.
4.13 + *
4.14 + * This program is distributed in the hope that it will be useful,
4.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.17 + * GNU General Public License for more details.
4.18 + *
4.19 + * You should have received a copy of the GNU General Public License
4.20 + * along with this program; if not, write to the Free Software
4.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
4.22 + * Boston, MA 02110-1301, USA
4.23 + */
4.24 +
4.25 +#include "declaration.h"
4.26 +
4.27 +/* Generate parameters in each function signature. */
4.28 +
4.29 +void write_parameters(struct parameter *param, FILE *fp, enum parameter_role role)
4.30 +{
4.31 + if (param == NULL)
4.32 + return;
4.33 +
4.34 + write_parameter(param, fp, role);
4.35 + write_parameter_separator(param->tail, fp);
4.36 + write_parameters(param->tail, fp, role);
4.37 +}
4.38 +
4.39 +/* Generate a parameter in a signature. */
4.40 +
4.41 +void write_parameter(struct parameter *param, FILE *fp, enum parameter_role role)
4.42 +{
4.43 + struct identifier *ident = param->identifiers;
4.44 + char *type;
4.45 + int first = 1;
4.46 +
4.47 + while (ident != NULL)
4.48 + {
4.49 + if (first)
4.50 + first = 0;
4.51 + else
4.52 + fputs(" ", fp);
4.53 +
4.54 + /* Emit type identifiers. */
4.55 +
4.56 + if (ident->tail != NULL)
4.57 + fputs(ident->identifier, fp);
4.58 +
4.59 + /* Emit the parameter name. */
4.60 +
4.61 + else
4.62 + {
4.63 + /* Items must have their type identifiers restored. */
4.64 +
4.65 + if (param->cls & ITEM_CLASS)
4.66 + {
4.67 + type = param->cls == FPAGE_ITEM ? L4_FPAGE_TYPE : L4_CAP_TYPE;
4.68 + fputs(type, fp);
4.69 + fputs(" ", fp);
4.70 + }
4.71 +
4.72 + fprintf(fp, "%s%s", (role == SIGNATURE_ROLE) && (param->specifier & OUT_PARAMETER) ? "*" : "",
4.73 + ident->identifier);
4.74 + }
4.75 +
4.76 + ident = ident->tail;
4.77 + }
4.78 +}
4.79 +
4.80 +void write_parameter_separator(struct parameter *param, FILE *fp)
4.81 +{
4.82 + if (param != NULL)
4.83 + fputs(", ", fp);
4.84 +}
4.85 +
4.86 +/* Write structure members for word data structures or variable declarations for
4.87 + parameters. */
4.88 +
4.89 +void write_declarations(struct parameter *param, enum specifier direction,
4.90 + enum parameter_class cls, FILE *fp)
4.91 +{
4.92 + for (; param != NULL; param = param->tail)
4.93 + {
4.94 + if ((param->specifier & direction) && (param->cls & cls))
4.95 + {
4.96 + fputs(" ", fp);
4.97 + write_parameter(param, fp, STRUCTURE_ROLE);
4.98 + fputs(";\n", fp);
4.99 + }
4.100 + }
4.101 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/declaration.h Sat Nov 09 01:18:22 2019 +0100
5.3 @@ -0,0 +1,36 @@
5.4 +/*
5.5 + * Generation of declaration elements such as parameters and members.
5.6 + *
5.7 + * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
5.8 + *
5.9 + * This program is free software; you can redistribute it and/or
5.10 + * modify it under the terms of the GNU General Public License as
5.11 + * published by the Free Software Foundation; either version 2 of
5.12 + * the License, or (at your option) any later version.
5.13 + *
5.14 + * This program is distributed in the hope that it will be useful,
5.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.17 + * GNU General Public License for more details.
5.18 + *
5.19 + * You should have received a copy of the GNU General Public License
5.20 + * along with this program; if not, write to the Free Software
5.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
5.22 + * Boston, MA 02110-1301, USA
5.23 + */
5.24 +
5.25 +#pragma once
5.26 +
5.27 +#include <stdio.h>
5.28 +#include "types.h"
5.29 +
5.30 +/* Parameter lists. */
5.31 +
5.32 +void write_parameters(struct parameter *param, FILE *fp, enum parameter_role role);
5.33 +void write_parameter(struct parameter *param, FILE *fp, enum parameter_role role);
5.34 +void write_parameter_separator(struct parameter *param, FILE *fp);
5.35 +
5.36 +/* Structure member and variable declaration/initialisation. */
5.37 +
5.38 +void write_declarations(struct parameter *param, enum specifier direction,
5.39 + enum parameter_class cls, FILE *fp);
6.1 --- a/dispatch.c Sat Nov 09 00:44:59 2019 +0100
6.2 +++ b/dispatch.c Sat Nov 09 01:18:22 2019 +0100
6.3 @@ -1,5 +1,5 @@
6.4 /*
6.5 - * Client code generation: dispatch functions.
6.6 + * Generation of server dispatch functions.
6.7 *
6.8 * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
6.9 *
7.1 --- a/dispatch.h Sat Nov 09 00:44:59 2019 +0100
7.2 +++ b/dispatch.h Sat Nov 09 01:18:22 2019 +0100
7.3 @@ -1,5 +1,5 @@
7.4 /*
7.5 - * Client code generation: dispatch functions.
7.6 + * Generation of server dispatch functions.
7.7 *
7.8 * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
7.9 *
8.1 --- a/message.c Sat Nov 09 00:44:59 2019 +0100
8.2 +++ b/message.c Sat Nov 09 01:18:22 2019 +0100
8.3 @@ -1,5 +1,5 @@
8.4 /*
8.5 - * Client code generation: message structure access.
8.6 + * Generation of message structure access operations.
8.7 *
8.8 * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
8.9 *
9.1 --- a/message.h Sat Nov 09 00:44:59 2019 +0100
9.2 +++ b/message.h Sat Nov 09 01:18:22 2019 +0100
9.3 @@ -1,5 +1,5 @@
9.4 /*
9.5 - * Client code generation: message structure access.
9.6 + * Generation of message structure access operations.
9.7 *
9.8 * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
9.9 *
10.1 --- a/program.c Sat Nov 09 00:44:59 2019 +0100
10.2 +++ b/program.c Sat Nov 09 01:18:22 2019 +0100
10.3 @@ -1,5 +1,5 @@
10.4 /*
10.5 - * Client code generation.
10.6 + * Code generation from interface descriptions.
10.7 *
10.8 * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
10.9 *
10.10 @@ -20,10 +20,14 @@
10.11 */
10.12
10.13 #include <stdlib.h>
10.14 +#include "client.h"
10.15 #include "common.h"
10.16 +#include "declaration.h"
10.17 #include "dispatch.h"
10.18 #include "message.h"
10.19 #include "program.h"
10.20 +#include "server.h"
10.21 +#include "structure.h"
10.22 #include "summary.h"
10.23 #include "templates.h"
10.24
10.25 @@ -117,12 +121,6 @@
10.26 fputs("\n", fp);
10.27 }
10.28
10.29 -static void write_parameter_separator(struct parameter *param, FILE *fp)
10.30 -{
10.31 - if (param != NULL)
10.32 - fputs(", ", fp);
10.33 -}
10.34 -
10.35 static void write_signature_end(FILE *fp)
10.36 {
10.37 fputs(";\n", fp);
10.38 @@ -553,9 +551,7 @@
10.39
10.40 /* Emit opcodes. */
10.41
10.42 - fprintf(common_fp, "\nenum opcodes_%s\n{\n", iface->name);
10.43 - write_opcodes(iface->signatures, common_fp, iface->name);
10.44 - fputs("};\n", common_fp);
10.45 + write_opcode_definition(iface, common_fp);
10.46
10.47 /* Emit message access structures. */
10.48
10.49 @@ -577,28 +573,6 @@
10.50 fprintf(fp, "#include %s\n", inc->filename);
10.51 }
10.52
10.53 -/* Generate an enumeration of operator codes. */
10.54 -
10.55 -void write_opcodes(struct signature *sig, FILE *fp, const char *name)
10.56 -{
10.57 - char *opcode;
10.58 -
10.59 - if (sig == NULL)
10.60 - return;
10.61 -
10.62 - fprintf(fp, " opcode_%s_%s", name, sig->operation);
10.63 -
10.64 - /* Obtain any explicit opcode from the signature attributes. */
10.65 -
10.66 - opcode = get_opcode(sig->attributes);
10.67 - if (opcode != NULL)
10.68 - fprintf(fp, " = %s", opcode);
10.69 -
10.70 - fputs(",\n", fp);
10.71 -
10.72 - write_opcodes(sig->tail, fp, name);
10.73 -}
10.74 -
10.75 /* Generate signatures. */
10.76
10.77 void write_signatures(struct signature *sig, FILE *fp, struct interface *iface,
10.78 @@ -611,83 +585,6 @@
10.79 write_signatures(sig->tail, fp, iface, write_signature);
10.80 }
10.81
10.82 -/* Generate operation signature details for client use. */
10.83 -
10.84 -static void _write_client_signature(struct signature *sig, FILE *fp, struct interface *iface)
10.85 -{
10.86 - char *opname = get_operation_name(iface, sig);
10.87 -
10.88 - /* NOTE: Qualifier discarded for now. */
10.89 - /* Introduce an initial parameter for the endpoint. */
10.90 -
10.91 - fprintf(fp, "\nlong %s(%s _endp", opname, L4_CAP_TYPE);
10.92 - write_parameter_separator(sig->parameters, fp);
10.93 - write_parameters(sig->parameters, fp, SIGNATURE_ROLE);
10.94 - fputs(")", fp);
10.95 -
10.96 - free(opname);
10.97 -}
10.98 -
10.99 -/* Generate each operation signature or "function prototype" for client use. */
10.100 -
10.101 -void write_client_signature(struct signature *sig, FILE *fp, struct interface *iface)
10.102 -{
10.103 - _write_client_signature(sig, fp, iface);
10.104 - write_signature_end(fp);
10.105 -}
10.106 -
10.107 -/* Generate operation wrapper function details used by the server. */
10.108 -
10.109 -void _write_server_signature(struct signature *sig, FILE *fp, struct interface *iface)
10.110 -{
10.111 - /* NOTE: Qualifier discarded for now. */
10.112 -
10.113 - char *opname = get_operation_name(iface, sig),
10.114 - *type = (output_language == CPP_LANGUAGE) ? iface->name : "void";
10.115 -
10.116 - fprintf(fp, "\nlong wrap_%s(ipc_message_t *msg, %s *_self)", opname, type);
10.117 -
10.118 - free(opname);
10.119 -}
10.120 -
10.121 -/* Generate each signature for a wrapper function used by the server. */
10.122 -
10.123 -void write_server_signature(struct signature *sig, FILE *fp, struct interface *iface)
10.124 -{
10.125 - _write_server_signature(sig, fp, iface);
10.126 - write_signature_end(fp);
10.127 -}
10.128 -
10.129 -/* Generate each operation signature or "function prototype" for server use. */
10.130 -
10.131 -void write_server_interface_signature(struct signature *sig, FILE *fp, struct interface *iface)
10.132 -{
10.133 - char *opname = get_interface_operation_name(iface, sig, output_language);
10.134 -
10.135 - /* NOTE: Qualifier discarded for now. */
10.136 -
10.137 - int have_init_param = (output_language == C_LANGUAGE);
10.138 -
10.139 - /* Indent and provide a qualifier for C++ class declarations. */
10.140 -
10.141 - char *type = (output_language == CPP_LANGUAGE) ? iface->name : "void",
10.142 - *qualifier = (output_language == CPP_LANGUAGE) ? " virtual " : "",
10.143 - *value_qualifier = (output_language == CPP_LANGUAGE) ? " = 0" : "",
10.144 - *init_param = have_init_param ? "void *_self" : "";
10.145 -
10.146 - /* Introduce an initial parameter for the component state. */
10.147 -
10.148 - fprintf(fp, "\n%slong %s(%s", qualifier, opname, init_param);
10.149 -
10.150 - if (have_init_param)
10.151 - write_parameter_separator(sig->parameters, fp);
10.152 - write_parameters(sig->parameters, fp, SIGNATURE_ROLE);
10.153 -
10.154 - fprintf(fp, ")%s;\n", value_qualifier);
10.155 -
10.156 - free(opname);
10.157 -}
10.158 -
10.159 /* Generate functions corresponding to the signatures. */
10.160
10.161 void write_functions(struct signature *sig, FILE *fp, struct interface *iface,
10.162 @@ -699,347 +596,3 @@
10.163 write_function(sig, fp, iface);
10.164 write_functions(sig->tail, fp, iface, write_function);
10.165 }
10.166 -
10.167 -/* Generate function source code for each operation signature. */
10.168 -
10.169 -void write_client_function(struct signature *sig, FILE *fp, struct interface *iface)
10.170 -{
10.171 - _write_client_signature(sig, fp, iface);
10.172 - fputs("\n{\n", fp);
10.173 - write_client_function_body(sig->parameters, fp, iface, sig);
10.174 - fputs("}\n", fp);
10.175 -}
10.176 -
10.177 -/* Generate function source code for each operation, with the generated function
10.178 - unpacking a message, calling the actual operation and repacking the
10.179 - results. */
10.180 -
10.181 -void write_server_function(struct signature *sig, FILE *fp, struct interface *iface)
10.182 -{
10.183 - char *type = (output_language == CPP_LANGUAGE) ? iface->name : "void";
10.184 -
10.185 - _write_server_signature(sig, fp, iface);
10.186 - fputs("\n{\n", fp);
10.187 - write_server_function_body(sig->parameters, fp, iface, sig);
10.188 - fputs("}\n", fp);
10.189 -}
10.190 -
10.191 -/* Generate a function body corresponding to an operation for client use. */
10.192 -
10.193 -void write_client_function_body(struct parameter *param, FILE *fp,
10.194 - struct interface *iface, struct signature *sig)
10.195 -{
10.196 - int input_words, input_items, output_words, output_items;
10.197 -
10.198 - /* With a protocol attribute, the opcode is the attribute value. Otherwise,
10.199 - it is the operation code. */
10.200 -
10.201 - char *opname = get_operation_name(iface, sig),
10.202 - *protocol = get_protocol(iface->attributes),
10.203 - *opcode = get_opcode_identifier(protocol, opname);
10.204 -
10.205 - /* Generate the prologue. */
10.206 -
10.207 - fputs(client_function_body_prologue, fp);
10.208 -
10.209 - /* Count the number of input words, items and output words. */
10.210 -
10.211 - count_parameters(param, &input_words, &input_items, &output_words, &output_items);
10.212 -
10.213 - /* Adjust the input words where a protocol is used as the opcode. */
10.214 -
10.215 - if (protocol != NULL)
10.216 - input_words++;
10.217 -
10.218 - /* Generate types parameterised with the qualified operation name. */
10.219 -
10.220 - write_accessor_declaration(input_words, output_words, opname, fp);
10.221 -
10.222 - /* Initialise the message. */
10.223 -
10.224 - fprintf(fp, "\n ipc_message_new(&msg);\n");
10.225 -
10.226 - /* Generate expected output item requirements. */
10.227 -
10.228 - if (output_items)
10.229 - fprintf(fp, " err = ipc_message_expect(&msg, %d);\n"
10.230 - " if (err)\n"
10.231 - " return err;\n", output_items);
10.232 -
10.233 - /* Populate input parameters in the message. Dereference function parameters
10.234 - acting as "inout" parameters. */
10.235 -
10.236 - if (input_words)
10.237 - {
10.238 - /* Reserve space for the words before any items, obtaining a pointer to the
10.239 - words. */
10.240 -
10.241 - write_accessor_initialisation(IN_PARAMETER, CLIENT_ROLE, opname, fp);
10.242 -
10.243 - if (protocol != NULL)
10.244 - fprintf(fp, " in_words->_op = %s;\n", opname);
10.245 -
10.246 - write_message_access(param, CLIENT_ROLE, IN_PARAMETER, WORD_CLASS, fp);
10.247 - }
10.248 -
10.249 - /* Do the same for items. */
10.250 -
10.251 - if (input_items)
10.252 - {
10.253 - fputs("\n", fp);
10.254 - write_message_access(param, CLIENT_ROLE, IN_PARAMETER, ITEM_CLASS, fp);
10.255 - }
10.256 -
10.257 - /* Send the request. */
10.258 -
10.259 - fprintf(fp, client_function_body_call, opcode);
10.260 -
10.261 - /* Retrieve output parameters from the message. */
10.262 -
10.263 - if (output_words)
10.264 - {
10.265 - write_accessor_initialisation(OUT_PARAMETER, CLIENT_ROLE, opname, fp);
10.266 - write_message_access(param, CLIENT_ROLE, OUT_PARAMETER, WORD_CLASS, fp);
10.267 - }
10.268 -
10.269 - /* Do the same for items. */
10.270 -
10.271 - if (output_items)
10.272 - {
10.273 - fputs("\n", fp);
10.274 - write_message_access(param, CLIENT_ROLE, OUT_PARAMETER, ITEM_CLASS, fp);
10.275 - }
10.276 -
10.277 - /* Return success. */
10.278 -
10.279 - fprintf(fp, "\n return L4_EOK;\n");
10.280 -
10.281 - /* Free allocated strings. */
10.282 -
10.283 - free(opname);
10.284 -
10.285 - if (protocol == NULL)
10.286 - free(opcode);
10.287 -}
10.288 -
10.289 -/* Generate a function body corresponding to an operation for server use. */
10.290 -
10.291 -void write_server_function_body(struct parameter *param, FILE *fp,
10.292 - struct interface *iface, struct signature *sig)
10.293 -{
10.294 - int input_words, input_items, output_words, output_items;
10.295 - char *opname = get_operation_name(iface, sig);
10.296 -
10.297 - /* Generate the prologue. */
10.298 -
10.299 - fputs(server_function_body_prologue, fp);
10.300 -
10.301 - /* Count the number of input words, items and output words. */
10.302 -
10.303 - count_parameters(param, &input_words, &input_items, &output_words, &output_items);
10.304 -
10.305 - /* Generate variable declarations. */
10.306 -
10.307 - write_declarations(param, ANY_PARAMETER, ANY_CLASS, fp);
10.308 -
10.309 - /* Generate types parameterised with the qualified operation name. */
10.310 -
10.311 - write_accessor_declaration(input_words, output_words, opname, fp);
10.312 -
10.313 - /* Unpack each word and item from the message into variables. */
10.314 -
10.315 - if (input_words)
10.316 - {
10.317 - write_accessor_initialisation(IN_PARAMETER, SERVER_ROLE, opname, fp);
10.318 - write_message_access(param, SERVER_ROLE, IN_PARAMETER, WORD_CLASS, fp);
10.319 - }
10.320 -
10.321 - if (input_items)
10.322 - {
10.323 - fputs("\n", fp);
10.324 - write_message_access(param, SERVER_ROLE, IN_PARAMETER, ITEM_CLASS, fp);
10.325 - }
10.326 -
10.327 - /* Invoke the actual operation using the variables. */
10.328 -
10.329 - write_server_function_call(param, fp, iface, sig);
10.330 -
10.331 - /* Pack the outputs into the message and perform any other housekeeping. */
10.332 -
10.333 - if (output_words)
10.334 - {
10.335 - write_accessor_initialisation(OUT_PARAMETER, SERVER_ROLE, opname, fp);
10.336 - write_message_access(param, SERVER_ROLE, OUT_PARAMETER, WORD_CLASS, fp);
10.337 - }
10.338 -
10.339 - if (output_items)
10.340 - {
10.341 - fputs("\n", fp);
10.342 - write_message_access(param, SERVER_ROLE, OUT_PARAMETER, ITEM_CLASS, fp);
10.343 - }
10.344 -
10.345 - /* Return success. */
10.346 -
10.347 - fprintf(fp, "\n return L4_EOK;\n");
10.348 -
10.349 - /* Free allocated strings. */
10.350 -
10.351 - free(opname);
10.352 -}
10.353 -
10.354 -/* Generate an invocation of the actual server operation. */
10.355 -
10.356 -void write_server_function_call(struct parameter *param, FILE *fp,
10.357 - struct interface *iface, struct signature *sig)
10.358 -{
10.359 - char *name, *addr,
10.360 - *opname = get_interface_operation_name(iface, sig, output_language);
10.361 -
10.362 - fputs("\n err = ", fp);
10.363 -
10.364 - /* Access a method when emitting C++. */
10.365 -
10.366 - if (output_language == CPP_LANGUAGE)
10.367 - fprintf(fp, "_self->%s(", opname);
10.368 -
10.369 - /* Employ a function otherwise. */
10.370 -
10.371 - else
10.372 - {
10.373 - fprintf(fp, "%s(_self", opname);
10.374 - write_parameter_separator(param, fp);
10.375 - }
10.376 -
10.377 - /* Generate the parameter list, employing addresses for output parameters. */
10.378 -
10.379 - for (; param != NULL; param = param->tail)
10.380 - {
10.381 - addr = param->specifier & OUT_PARAMETER ? "&" : "";
10.382 - name = get_parameter_name(param->identifiers);
10.383 - fprintf(fp, "%s%s", addr, name);
10.384 - write_parameter_separator(param->tail, fp);
10.385 - }
10.386 -
10.387 - fputs(");\n", fp);
10.388 -
10.389 - /* Emit post-invocation details. */
10.390 -
10.391 - fputs(server_function_body_call, fp);
10.392 -
10.393 - /* Free allocated strings. */
10.394 -
10.395 - free(opname);
10.396 -}
10.397 -
10.398 -/* Generate structures for messages corresponding to the signatures. */
10.399 -
10.400 -void write_structures(struct signature *sig, FILE *fp, struct interface *iface)
10.401 -{
10.402 - if (sig == NULL)
10.403 - return;
10.404 -
10.405 - write_structure(sig, fp, iface);
10.406 - write_structures(sig->tail, fp, iface);
10.407 -}
10.408 -
10.409 -/* Generate message structures for a signature. */
10.410 -
10.411 -void write_structure(struct signature *sig, FILE *fp, struct interface *iface)
10.412 -{
10.413 - struct parameter *param = sig->parameters;
10.414 - char *opname = get_operation_name(iface, sig),
10.415 - *protocol = get_protocol(iface->attributes);
10.416 - int input_words, input_items, output_words, output_items;
10.417 -
10.418 - count_parameters(param, &input_words, &input_items, &output_words, &output_items);
10.419 -
10.420 - if (input_words)
10.421 - {
10.422 - fprintf(fp, "\nstruct in_words_%s\n{\n", opname);
10.423 - if (protocol != NULL)
10.424 - fprintf(fp, " %s _op;\n", L4_WORD_TYPE);
10.425 - write_declarations(param, IN_PARAMETER, WORD_CLASS, fp);
10.426 - fprintf(fp, "};\n");
10.427 - }
10.428 -
10.429 - if (output_words)
10.430 - {
10.431 - fprintf(fp, "\nstruct out_words_%s\n{\n", opname);
10.432 - write_declarations(param, OUT_PARAMETER, WORD_CLASS, fp);
10.433 - fprintf(fp, "};\n");
10.434 - }
10.435 -
10.436 - /* Free allocated strings. */
10.437 -
10.438 - free(opname);
10.439 -}
10.440 -
10.441 -/* Generate parameters in each function signature. */
10.442 -
10.443 -void write_parameters(struct parameter *param, FILE *fp, enum parameter_role role)
10.444 -{
10.445 - if (param == NULL)
10.446 - return;
10.447 -
10.448 - write_parameter(param, fp, role);
10.449 - write_parameter_separator(param->tail, fp);
10.450 - write_parameters(param->tail, fp, role);
10.451 -}
10.452 -
10.453 -/* Generate a parameter in a signature. */
10.454 -
10.455 -void write_parameter(struct parameter *param, FILE *fp, enum parameter_role role)
10.456 -{
10.457 - struct identifier *ident = param->identifiers;
10.458 - char *type;
10.459 - int first = 1;
10.460 -
10.461 - while (ident != NULL)
10.462 - {
10.463 - if (first)
10.464 - first = 0;
10.465 - else
10.466 - fputs(" ", fp);
10.467 -
10.468 - /* Emit type identifiers. */
10.469 -
10.470 - if (ident->tail != NULL)
10.471 - fputs(ident->identifier, fp);
10.472 -
10.473 - /* Emit the parameter name. */
10.474 -
10.475 - else
10.476 - {
10.477 - /* Items must have their type identifiers restored. */
10.478 -
10.479 - if (param->cls & ITEM_CLASS)
10.480 - {
10.481 - type = param->cls == FPAGE_ITEM ? L4_FPAGE_TYPE : L4_CAP_TYPE;
10.482 - fputs(type, fp);
10.483 - fputs(" ", fp);
10.484 - }
10.485 -
10.486 - fprintf(fp, "%s%s", (role == SIGNATURE_ROLE) && (param->specifier & OUT_PARAMETER) ? "*" : "",
10.487 - ident->identifier);
10.488 - }
10.489 -
10.490 - ident = ident->tail;
10.491 - }
10.492 -}
10.493 -
10.494 -/* Write structure members for word data structures or variable declarations for
10.495 - parameters. */
10.496 -
10.497 -void write_declarations(struct parameter *param, enum specifier direction,
10.498 - enum parameter_class cls, FILE *fp)
10.499 -{
10.500 - for (; param != NULL; param = param->tail)
10.501 - {
10.502 - if ((param->specifier & direction) && (param->cls & cls))
10.503 - {
10.504 - fputs(" ", fp);
10.505 - write_parameter(param, fp, STRUCTURE_ROLE);
10.506 - fputs(";\n", fp);
10.507 - }
10.508 - }
10.509 -}
11.1 --- a/program.h Sat Nov 09 00:44:59 2019 +0100
11.2 +++ b/program.h Sat Nov 09 01:18:22 2019 +0100
11.3 @@ -24,26 +24,6 @@
11.4 #include <stdio.h>
11.5 #include "types.h"
11.6
11.7 -/* General capability type. */
11.8 -
11.9 -#define L4_CAP_TYPE "l4_cap_idx_t"
11.10 -
11.11 -/* A flexpage type that can hold extra information (such as the "hot spot"). */
11.12 -
11.13 -#define L4_FPAGE_TYPE "l4_snd_fpage_t"
11.14 -
11.15 -/* General word type. */
11.16 -
11.17 -#define L4_WORD_TYPE "l4_umword_t"
11.18 -
11.19 -/* Output role of a parameter. */
11.20 -
11.21 -enum parameter_role
11.22 -{
11.23 - SIGNATURE_ROLE,
11.24 - STRUCTURE_ROLE,
11.25 -};
11.26 -
11.27 /* Component-level processing. */
11.28
11.29 void begin_compound_output(void);
11.30 @@ -68,45 +48,7 @@
11.31 void write_signatures(struct signature *sig, FILE *fp, struct interface *iface,
11.32 void (*write_signature)(struct signature *, FILE *, struct interface *));
11.33
11.34 -void write_client_signature(struct signature *sig, FILE *fp, struct interface *iface);
11.35 -void write_server_signature(struct signature *sig, FILE *fp, struct interface *iface);
11.36 -void write_server_interface_signature(struct signature *sig, FILE *fp, struct interface *iface);
11.37 -
11.38 /* Function details. */
11.39
11.40 void write_functions(struct signature *sig, FILE *fp, struct interface *iface,
11.41 void (*write_function)(struct signature *, FILE *, struct interface *));
11.42 -
11.43 -/* Function definitions. */
11.44 -
11.45 -void write_client_function(struct signature *sig, FILE *fp, struct interface *iface);
11.46 -
11.47 -void write_client_function_body(struct parameter *param, FILE *fp,
11.48 - struct interface *iface, struct signature *sig);
11.49 -
11.50 -void write_server_function(struct signature *sig, FILE *fp, struct interface *iface);
11.51 -
11.52 -void write_server_function_body(struct parameter *param, FILE *fp,
11.53 - struct interface *iface, struct signature *sig);
11.54 -
11.55 -void write_server_function_call(struct parameter *param, FILE *fp,
11.56 - struct interface *iface, struct signature *sig);
11.57 -
11.58 -/* Message access structures. */
11.59 -
11.60 -void write_structures(struct signature *sig, FILE *fp, struct interface *iface);
11.61 -void write_structure(struct signature *sig, FILE *fp, struct interface *iface);
11.62 -
11.63 -/* Parameter lists. */
11.64 -
11.65 -void write_parameters(struct parameter *param, FILE *fp, enum parameter_role role);
11.66 -void write_parameter(struct parameter *param, FILE *fp, enum parameter_role role);
11.67 -
11.68 -/* Operation codes. */
11.69 -
11.70 -void write_opcodes(struct signature *sig, FILE *fp, const char *name);
11.71 -
11.72 -/* Structure member and variable declaration/initialisation. */
11.73 -
11.74 -void write_declarations(struct parameter *param, enum specifier direction,
11.75 - enum parameter_class cls, FILE *fp);
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/server.c Sat Nov 09 01:18:22 2019 +0100
12.3 @@ -0,0 +1,215 @@
12.4 +/*
12.5 + * Server code generation.
12.6 + *
12.7 + * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
12.8 + *
12.9 + * This program is free software; you can redistribute it and/or
12.10 + * modify it under the terms of the GNU General Public License as
12.11 + * published by the Free Software Foundation; either version 2 of
12.12 + * the License, or (at your option) any later version.
12.13 + *
12.14 + * This program is distributed in the hope that it will be useful,
12.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.17 + * GNU General Public License for more details.
12.18 + *
12.19 + * You should have received a copy of the GNU General Public License
12.20 + * along with this program; if not, write to the Free Software
12.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
12.22 + * Boston, MA 02110-1301, USA
12.23 + */
12.24 +
12.25 +#include <stdlib.h>
12.26 +#include "common.h"
12.27 +#include "declaration.h"
12.28 +#include "message.h"
12.29 +#include "server.h"
12.30 +#include "templates.h"
12.31 +
12.32 +
12.33 +
12.34 +/* Output language, set in the main program. */
12.35 +
12.36 +extern enum language output_language;
12.37 +
12.38 +
12.39 +
12.40 +static void write_signature_end(FILE *fp)
12.41 +{
12.42 + fputs(";\n", fp);
12.43 +}
12.44 +
12.45 +/* Generate operation wrapper function details used by the server. */
12.46 +
12.47 +void _write_server_signature(struct signature *sig, FILE *fp, struct interface *iface)
12.48 +{
12.49 + /* NOTE: Qualifier discarded for now. */
12.50 +
12.51 + char *opname = get_operation_name(iface, sig),
12.52 + *type = (output_language == CPP_LANGUAGE) ? iface->name : "void";
12.53 +
12.54 + fprintf(fp, "\nlong wrap_%s(ipc_message_t *msg, %s *_self)", opname, type);
12.55 +
12.56 + free(opname);
12.57 +}
12.58 +
12.59 +/* Generate each signature for a wrapper function used by the server. */
12.60 +
12.61 +void write_server_signature(struct signature *sig, FILE *fp, struct interface *iface)
12.62 +{
12.63 + _write_server_signature(sig, fp, iface);
12.64 + write_signature_end(fp);
12.65 +}
12.66 +
12.67 +/* Generate each operation signature or "function prototype" for server use. */
12.68 +
12.69 +void write_server_interface_signature(struct signature *sig, FILE *fp, struct interface *iface)
12.70 +{
12.71 + char *opname = get_interface_operation_name(iface, sig, output_language);
12.72 +
12.73 + /* NOTE: Qualifier discarded for now. */
12.74 +
12.75 + int have_init_param = (output_language == C_LANGUAGE);
12.76 +
12.77 + /* Indent and provide a qualifier for C++ class declarations. */
12.78 +
12.79 + char *type = (output_language == CPP_LANGUAGE) ? iface->name : "void",
12.80 + *qualifier = (output_language == CPP_LANGUAGE) ? " virtual " : "",
12.81 + *value_qualifier = (output_language == CPP_LANGUAGE) ? " = 0" : "",
12.82 + *init_param = have_init_param ? "void *_self" : "";
12.83 +
12.84 + /* Introduce an initial parameter for the component state. */
12.85 +
12.86 + fprintf(fp, "\n%slong %s(%s", qualifier, opname, init_param);
12.87 +
12.88 + if (have_init_param)
12.89 + write_parameter_separator(sig->parameters, fp);
12.90 + write_parameters(sig->parameters, fp, SIGNATURE_ROLE);
12.91 +
12.92 + fprintf(fp, ")%s;\n", value_qualifier);
12.93 +
12.94 + free(opname);
12.95 +}
12.96 +
12.97 +/* Generate function source code for each operation, with the generated function
12.98 + unpacking a message, calling the actual operation and repacking the
12.99 + results. */
12.100 +
12.101 +void write_server_function(struct signature *sig, FILE *fp, struct interface *iface)
12.102 +{
12.103 + char *type = (output_language == CPP_LANGUAGE) ? iface->name : "void";
12.104 +
12.105 + _write_server_signature(sig, fp, iface);
12.106 + fputs("\n{\n", fp);
12.107 + write_server_function_body(sig->parameters, fp, iface, sig);
12.108 + fputs("}\n", fp);
12.109 +}
12.110 +
12.111 +/* Generate a function body corresponding to an operation for server use. */
12.112 +
12.113 +void write_server_function_body(struct parameter *param, FILE *fp,
12.114 + struct interface *iface, struct signature *sig)
12.115 +{
12.116 + int input_words, input_items, output_words, output_items;
12.117 + char *opname = get_operation_name(iface, sig);
12.118 +
12.119 + /* Generate the prologue. */
12.120 +
12.121 + fputs(server_function_body_prologue, fp);
12.122 +
12.123 + /* Count the number of input words, items and output words. */
12.124 +
12.125 + count_parameters(param, &input_words, &input_items, &output_words, &output_items);
12.126 +
12.127 + /* Generate variable declarations. */
12.128 +
12.129 + write_declarations(param, ANY_PARAMETER, ANY_CLASS, fp);
12.130 +
12.131 + /* Generate types parameterised with the qualified operation name. */
12.132 +
12.133 + write_accessor_declaration(input_words, output_words, opname, fp);
12.134 +
12.135 + /* Unpack each word and item from the message into variables. */
12.136 +
12.137 + if (input_words)
12.138 + {
12.139 + write_accessor_initialisation(IN_PARAMETER, SERVER_ROLE, opname, fp);
12.140 + write_message_access(param, SERVER_ROLE, IN_PARAMETER, WORD_CLASS, fp);
12.141 + }
12.142 +
12.143 + if (input_items)
12.144 + {
12.145 + fputs("\n", fp);
12.146 + write_message_access(param, SERVER_ROLE, IN_PARAMETER, ITEM_CLASS, fp);
12.147 + }
12.148 +
12.149 + /* Invoke the actual operation using the variables. */
12.150 +
12.151 + write_server_function_call(param, fp, iface, sig);
12.152 +
12.153 + /* Pack the outputs into the message and perform any other housekeeping. */
12.154 +
12.155 + if (output_words)
12.156 + {
12.157 + write_accessor_initialisation(OUT_PARAMETER, SERVER_ROLE, opname, fp);
12.158 + write_message_access(param, SERVER_ROLE, OUT_PARAMETER, WORD_CLASS, fp);
12.159 + }
12.160 +
12.161 + if (output_items)
12.162 + {
12.163 + fputs("\n", fp);
12.164 + write_message_access(param, SERVER_ROLE, OUT_PARAMETER, ITEM_CLASS, fp);
12.165 + }
12.166 +
12.167 + /* Return success. */
12.168 +
12.169 + fprintf(fp, "\n return L4_EOK;\n");
12.170 +
12.171 + /* Free allocated strings. */
12.172 +
12.173 + free(opname);
12.174 +}
12.175 +
12.176 +/* Generate an invocation of the actual server operation. */
12.177 +
12.178 +void write_server_function_call(struct parameter *param, FILE *fp,
12.179 + struct interface *iface, struct signature *sig)
12.180 +{
12.181 + char *name, *addr,
12.182 + *opname = get_interface_operation_name(iface, sig, output_language);
12.183 +
12.184 + fputs("\n err = ", fp);
12.185 +
12.186 + /* Access a method when emitting C++. */
12.187 +
12.188 + if (output_language == CPP_LANGUAGE)
12.189 + fprintf(fp, "_self->%s(", opname);
12.190 +
12.191 + /* Employ a function otherwise. */
12.192 +
12.193 + else
12.194 + {
12.195 + fprintf(fp, "%s(_self", opname);
12.196 + write_parameter_separator(param, fp);
12.197 + }
12.198 +
12.199 + /* Generate the parameter list, employing addresses for output parameters. */
12.200 +
12.201 + for (; param != NULL; param = param->tail)
12.202 + {
12.203 + addr = param->specifier & OUT_PARAMETER ? "&" : "";
12.204 + name = get_parameter_name(param->identifiers);
12.205 + fprintf(fp, "%s%s", addr, name);
12.206 + write_parameter_separator(param->tail, fp);
12.207 + }
12.208 +
12.209 + fputs(");\n", fp);
12.210 +
12.211 + /* Emit post-invocation details. */
12.212 +
12.213 + fputs(server_function_body_call, fp);
12.214 +
12.215 + /* Free allocated strings. */
12.216 +
12.217 + free(opname);
12.218 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/server.h Sat Nov 09 01:18:22 2019 +0100
13.3 @@ -0,0 +1,37 @@
13.4 +/*
13.5 + * Server code generation.
13.6 + *
13.7 + * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
13.8 + *
13.9 + * This program is free software; you can redistribute it and/or
13.10 + * modify it under the terms of the GNU General Public License as
13.11 + * published by the Free Software Foundation; either version 2 of
13.12 + * the License, or (at your option) any later version.
13.13 + *
13.14 + * This program is distributed in the hope that it will be useful,
13.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13.17 + * GNU General Public License for more details.
13.18 + *
13.19 + * You should have received a copy of the GNU General Public License
13.20 + * along with this program; if not, write to the Free Software
13.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
13.22 + * Boston, MA 02110-1301, USA
13.23 + */
13.24 +
13.25 +#pragma once
13.26 +
13.27 +#include <stdio.h>
13.28 +#include "types.h"
13.29 +
13.30 +void write_server_signature(struct signature *sig, FILE *fp, struct interface *iface);
13.31 +
13.32 +void write_server_interface_signature(struct signature *sig, FILE *fp, struct interface *iface);
13.33 +
13.34 +void write_server_function(struct signature *sig, FILE *fp, struct interface *iface);
13.35 +
13.36 +void write_server_function_body(struct parameter *param, FILE *fp,
13.37 + struct interface *iface, struct signature *sig);
13.38 +
13.39 +void write_server_function_call(struct parameter *param, FILE *fp,
13.40 + struct interface *iface, struct signature *sig);
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/structure.c Sat Nov 09 01:18:22 2019 +0100
14.3 @@ -0,0 +1,99 @@
14.4 +/*
14.5 + * Structure definition.
14.6 + *
14.7 + * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
14.8 + *
14.9 + * This program is free software; you can redistribute it and/or
14.10 + * modify it under the terms of the GNU General Public License as
14.11 + * published by the Free Software Foundation; either version 2 of
14.12 + * the License, or (at your option) any later version.
14.13 + *
14.14 + * This program is distributed in the hope that it will be useful,
14.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.17 + * GNU General Public License for more details.
14.18 + *
14.19 + * You should have received a copy of the GNU General Public License
14.20 + * along with this program; if not, write to the Free Software
14.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
14.22 + * Boston, MA 02110-1301, USA
14.23 + */
14.24 +
14.25 +#include <stdlib.h>
14.26 +#include "common.h"
14.27 +#include "declaration.h"
14.28 +#include "structure.h"
14.29 +
14.30 +/* Generate an enumeration of operator codes. */
14.31 +
14.32 +void write_opcode_definition(struct interface *iface, FILE *fp)
14.33 +{
14.34 + fprintf(fp, "\nenum opcodes_%s\n{\n", iface->name);
14.35 + write_opcodes(iface->signatures, fp, iface->name);
14.36 + fputs("};\n", fp);
14.37 +}
14.38 +
14.39 +/* Generate operator code enumeration entries. */
14.40 +
14.41 +void write_opcodes(struct signature *sig, FILE *fp, const char *name)
14.42 +{
14.43 + char *opcode;
14.44 +
14.45 + if (sig == NULL)
14.46 + return;
14.47 +
14.48 + fprintf(fp, " opcode_%s_%s", name, sig->operation);
14.49 +
14.50 + /* Obtain any explicit opcode from the signature attributes. */
14.51 +
14.52 + opcode = get_opcode(sig->attributes);
14.53 + if (opcode != NULL)
14.54 + fprintf(fp, " = %s", opcode);
14.55 +
14.56 + fputs(",\n", fp);
14.57 +
14.58 + write_opcodes(sig->tail, fp, name);
14.59 +}
14.60 +
14.61 +/* Generate structures for messages corresponding to the signatures. */
14.62 +
14.63 +void write_structures(struct signature *sig, FILE *fp, struct interface *iface)
14.64 +{
14.65 + if (sig == NULL)
14.66 + return;
14.67 +
14.68 + write_structure(sig, fp, iface);
14.69 + write_structures(sig->tail, fp, iface);
14.70 +}
14.71 +
14.72 +/* Generate message structures for a signature. */
14.73 +
14.74 +void write_structure(struct signature *sig, FILE *fp, struct interface *iface)
14.75 +{
14.76 + struct parameter *param = sig->parameters;
14.77 + char *opname = get_operation_name(iface, sig),
14.78 + *protocol = get_protocol(iface->attributes);
14.79 + int input_words, input_items, output_words, output_items;
14.80 +
14.81 + count_parameters(param, &input_words, &input_items, &output_words, &output_items);
14.82 +
14.83 + if (input_words)
14.84 + {
14.85 + fprintf(fp, "\nstruct in_words_%s\n{\n", opname);
14.86 + if (protocol != NULL)
14.87 + fprintf(fp, " %s _op;\n", L4_WORD_TYPE);
14.88 + write_declarations(param, IN_PARAMETER, WORD_CLASS, fp);
14.89 + fprintf(fp, "};\n");
14.90 + }
14.91 +
14.92 + if (output_words)
14.93 + {
14.94 + fprintf(fp, "\nstruct out_words_%s\n{\n", opname);
14.95 + write_declarations(param, OUT_PARAMETER, WORD_CLASS, fp);
14.96 + fprintf(fp, "};\n");
14.97 + }
14.98 +
14.99 + /* Free allocated strings. */
14.100 +
14.101 + free(opname);
14.102 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/structure.h Sat Nov 09 01:18:22 2019 +0100
15.3 @@ -0,0 +1,35 @@
15.4 +/*
15.5 + * Structure definition.
15.6 + *
15.7 + * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
15.8 + *
15.9 + * This program is free software; you can redistribute it and/or
15.10 + * modify it under the terms of the GNU General Public License as
15.11 + * published by the Free Software Foundation; either version 2 of
15.12 + * the License, or (at your option) any later version.
15.13 + *
15.14 + * This program is distributed in the hope that it will be useful,
15.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15.17 + * GNU General Public License for more details.
15.18 + *
15.19 + * You should have received a copy of the GNU General Public License
15.20 + * along with this program; if not, write to the Free Software
15.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
15.22 + * Boston, MA 02110-1301, USA
15.23 + */
15.24 +
15.25 +#pragma once
15.26 +
15.27 +#include <stdio.h>
15.28 +#include "types.h"
15.29 +
15.30 +/* Message access structures. */
15.31 +
15.32 +void write_structures(struct signature *sig, FILE *fp, struct interface *iface);
15.33 +void write_structure(struct signature *sig, FILE *fp, struct interface *iface);
15.34 +
15.35 +/* Operation codes. */
15.36 +
15.37 +void write_opcode_definition(struct interface *iface, FILE *fp);
15.38 +void write_opcodes(struct signature *sig, FILE *fp, const char *name);