1.1 --- a/client.c Mon Nov 25 23:40:37 2019 +0100
1.2 +++ b/client.c Tue Nov 26 21:16:24 2019 +0100
1.3 @@ -101,12 +101,14 @@
1.4 /* Reserve space for the words before any items, obtaining a pointer to the
1.5 words. */
1.6
1.7 - write_accessor_initialisation(IN_PARAMETER, CLIENT_ROLE, opname, fp);
1.8 + write_accessor_initialisation(IN_PARAMETER, CLIENT_ROLE, GENERAL_FUNCTION_ROLE,
1.9 + opname, fp);
1.10
1.11 if (protocol != NULL)
1.12 fprintf(fp, " in_words->_op = %s;\n", opname);
1.13
1.14 - write_message_access(param, CLIENT_ROLE, IN_PARAMETER, WORD_CLASS, fp);
1.15 + write_message_access(param, CLIENT_ROLE, GENERAL_FUNCTION_ROLE, IN_PARAMETER,
1.16 + WORD_CLASS, fp);
1.17 }
1.18
1.19 /* Do the same for items. */
1.20 @@ -114,7 +116,8 @@
1.21 if (input_items)
1.22 {
1.23 fputs("\n", fp);
1.24 - write_message_access(param, CLIENT_ROLE, IN_PARAMETER, ITEM_CLASS, fp);
1.25 + write_message_access(param, CLIENT_ROLE, GENERAL_FUNCTION_ROLE, IN_PARAMETER,
1.26 + ITEM_CLASS, fp);
1.27 }
1.28
1.29 /* Send the request. */
1.30 @@ -125,8 +128,10 @@
1.31
1.32 if (output_words)
1.33 {
1.34 - write_accessor_initialisation(OUT_PARAMETER, CLIENT_ROLE, opname, fp);
1.35 - write_message_access(param, CLIENT_ROLE, OUT_PARAMETER, WORD_CLASS, fp);
1.36 + write_accessor_initialisation(OUT_PARAMETER, CLIENT_ROLE, GENERAL_FUNCTION_ROLE,
1.37 + opname, fp);
1.38 + write_message_access(param, CLIENT_ROLE, GENERAL_FUNCTION_ROLE, OUT_PARAMETER,
1.39 + WORD_CLASS, fp);
1.40 }
1.41
1.42 /* Do the same for items. */
1.43 @@ -134,7 +139,8 @@
1.44 if (output_items)
1.45 {
1.46 fputs("\n", fp);
1.47 - write_message_access(param, CLIENT_ROLE, OUT_PARAMETER, ITEM_CLASS, fp);
1.48 + write_message_access(param, CLIENT_ROLE, GENERAL_FUNCTION_ROLE, OUT_PARAMETER,
1.49 + ITEM_CLASS, fp);
1.50 }
1.51
1.52 /* Return success. */
2.1 --- a/common.c Mon Nov 25 23:40:37 2019 +0100
2.2 +++ b/common.c Tue Nov 26 21:16:24 2019 +0100
2.3 @@ -222,12 +222,15 @@
2.4 return opcode;
2.5 }
2.6
2.7 -/* Return the appropriate parameter decoration. */
2.8 +/* Return the appropriate parameter decoration. Generally, output parameters
2.9 + involve addresses. However, completion functions accept output parameters as
2.10 + values. */
2.11
2.12 const char *get_parameter_decoration(struct parameter *param,
2.13 - enum parameter_role role)
2.14 + enum parameter_role role,
2.15 + enum function_role function)
2.16 {
2.17 - if (param->specifier & OUT_PARAMETER)
2.18 + if ((param->specifier & OUT_PARAMETER) && (function != COMPLETION_ROLE))
2.19 {
2.20 switch (role)
2.21 {
2.22 @@ -282,7 +285,8 @@
2.23 if (param->cls & ITEM_CLASS) (*input_items)++;
2.24 else (*input_words)++;
2.25 }
2.26 - else
2.27 +
2.28 + if (param->specifier & OUT_PARAMETER)
2.29 {
2.30 if (param->cls & ITEM_CLASS) (*output_items)++;
2.31 else (*output_words)++;
2.32 @@ -337,12 +341,14 @@
2.33 return param->cls == FPAGE_ITEM ? "fpage" : "capability";
2.34 }
2.35
2.36 -/* When copying output items from the message (in the client), the message
2.37 - address must be obtained using the appropriate operator. */
2.38 +/* When copying output items from the message (in the client) or copying into
2.39 + the message (in the server, but only with a new message), the message address
2.40 + must be obtained using the appropriate operator. */
2.41
2.42 -char *reference_message(enum component_role component)
2.43 +char *reference_message(enum component_role component,
2.44 + enum function_role function)
2.45 {
2.46 - return (component == CLIENT_ROLE) ? "&" : "";
2.47 + return (component == CLIENT_ROLE) || (function == COMPLETION_ROLE) ? "&" : "";
2.48 }
2.49
2.50 /* Return the naming prefix for structure access to a message. */
3.1 --- a/common.h Mon Nov 25 23:40:37 2019 +0100
3.2 +++ b/common.h Tue Nov 26 21:16:24 2019 +0100
3.3 @@ -60,7 +60,8 @@
3.4 char *get_opcode_identifier(char *protocol, char *opname);
3.5
3.6 const char *get_parameter_decoration(struct parameter *param,
3.7 - enum parameter_role role);
3.8 + enum parameter_role role,
3.9 + enum function_role function);
3.10
3.11 char *get_parameter_name(struct identifier *ident);
3.12 char *get_signature_terminator(enum signature_role role);
3.13 @@ -74,6 +75,6 @@
3.14
3.15 char *access_name(struct parameter *param, enum component_role component);
3.16 char *item_type_name(struct parameter *param);
3.17 -char *reference_message(enum component_role component);
3.18 +char *reference_message(enum component_role component, enum function_role function);
3.19 char *structure_prefix(enum specifier direction);
3.20 int writing_to_message(enum component_role component, enum specifier direction);
4.1 --- a/declaration.c Mon Nov 25 23:40:37 2019 +0100
4.2 +++ b/declaration.c Tue Nov 26 21:16:24 2019 +0100
4.3 @@ -39,7 +39,8 @@
4.4 int member = (role & MEMBER_ROLE);
4.5 int server = (component == SERVER_ROLE);
4.6 int completion = have_attribute(sig->attributes, "completion");
4.7 - enum specifier specifier = completion ? IN_PARAMETER : ANY_PARAMETER;
4.8 + enum specifier specifier = (server && completion) ? IN_PARAMETER : ANY_PARAMETER;
4.9 + enum function_role function = (server && completion) ? COMPLETION_ROLE : GENERAL_FUNCTION_ROLE;
4.10
4.11 /* Indent and provide a qualifier for C++ class declarations. */
4.12
4.13 @@ -62,7 +63,8 @@
4.14
4.15 /* Emit the parameters. */
4.16
4.17 - write_parameters(sig->parameters, fp, SIGNATURE_ROLE, specifier, have_init_param);
4.18 + write_parameters(sig->parameters, fp, SIGNATURE_ROLE, function, specifier,
4.19 + have_init_param);
4.20
4.21 fputs(")", fp);
4.22
4.23 @@ -108,7 +110,8 @@
4.24 /* Generate parameters in each function signature. */
4.25
4.26 void write_parameters(struct parameter *param, FILE *fp, enum parameter_role role,
4.27 - enum specifier specifier, int continuing)
4.28 + enum function_role function, enum specifier specifier,
4.29 + int continuing)
4.30 {
4.31 for (; param != NULL; param = param->tail)
4.32 {
4.33 @@ -119,14 +122,15 @@
4.34 else
4.35 continuing = 1;
4.36
4.37 - write_parameter(param, fp, role);
4.38 + write_parameter(param, fp, role, function);
4.39 }
4.40 }
4.41 }
4.42
4.43 /* Generate a parameter in a signature or invocation. */
4.44
4.45 -void write_parameter(struct parameter *param, FILE *fp, enum parameter_role role)
4.46 +void write_parameter(struct parameter *param, FILE *fp,
4.47 + enum parameter_role role, enum function_role function)
4.48 {
4.49 struct identifier *ident = param->identifiers;
4.50 char *type;
4.51 @@ -168,7 +172,8 @@
4.52
4.53 /* Emit the decoration and parameter name. */
4.54
4.55 - fprintf(fp, "%s%s", get_parameter_decoration(param, role), ident->identifier);
4.56 + fprintf(fp, "%s%s", get_parameter_decoration(param, role, function),
4.57 + ident->identifier);
4.58 }
4.59
4.60 ident = ident->tail;
4.61 @@ -186,7 +191,7 @@
4.62 if ((param->specifier & direction) && (param->cls & cls))
4.63 {
4.64 fputs(INDENT_MEMBER, fp);
4.65 - write_parameter(param, fp, STRUCTURE_ROLE);
4.66 + write_parameter(param, fp, STRUCTURE_ROLE, GENERAL_FUNCTION_ROLE);
4.67 fputs(COMPLETE_MEMBER, fp);
4.68 }
4.69 }
5.1 --- a/declaration.h Mon Nov 25 23:40:37 2019 +0100
5.2 +++ b/declaration.h Tue Nov 26 21:16:24 2019 +0100
5.3 @@ -40,9 +40,11 @@
5.4 /* Parameter lists. */
5.5
5.6 void write_parameters(struct parameter *param, FILE *fp, enum parameter_role role,
5.7 - enum specifier specifier, int continuing);
5.8 + enum function_role function, enum specifier specifier,
5.9 + int continuing);
5.10
5.11 -void write_parameter(struct parameter *param, FILE *fp, enum parameter_role role);
5.12 +void write_parameter(struct parameter *param, FILE *fp, enum parameter_role role,
5.13 + enum function_role function);
5.14
5.15 /* Structure member and variable declaration/initialisation. */
5.16
6.1 --- a/message.c Mon Nov 25 23:40:37 2019 +0100
6.2 +++ b/message.c Tue Nov 26 21:16:24 2019 +0100
6.3 @@ -39,10 +39,11 @@
6.4
6.5 void write_accessor_initialisation(enum specifier direction,
6.6 enum component_role component,
6.7 + enum function_role function,
6.8 const char *opname, FILE *fp)
6.9 {
6.10 char *prefix = structure_prefix(direction);
6.11 - char *addr = reference_message(component);
6.12 + char *addr = reference_message(component, function);
6.13
6.14 fprintf(fp, message_accessor_initialisation, prefix, prefix, opname);
6.15
6.16 @@ -58,8 +59,8 @@
6.17 /* Copy values between a message and local names. */
6.18
6.19 void write_message_access(struct parameter *param, enum component_role component,
6.20 - enum specifier direction, enum parameter_class cls,
6.21 - FILE *fp)
6.22 + enum function_role function, enum specifier direction,
6.23 + enum parameter_class cls, FILE *fp)
6.24 {
6.25 char *name, *access, *prefix, *addr;
6.26 int writing = writing_to_message(component, direction);
6.27 @@ -70,7 +71,7 @@
6.28 switch (cls)
6.29 {
6.30 case WORD_CLASS: prefix = structure_prefix(direction); break;
6.31 - case ITEM_CLASS: addr = reference_message(component); break;
6.32 + case ITEM_CLASS: addr = reference_message(component, function); break;
6.33 }
6.34
6.35 /* Generate an access operation for parameters having the indicated direction,
7.1 --- a/message.h Mon Nov 25 23:40:37 2019 +0100
7.2 +++ b/message.h Tue Nov 26 21:16:24 2019 +0100
7.3 @@ -29,8 +29,9 @@
7.4
7.5 void write_accessor_initialisation(enum specifier direction,
7.6 enum component_role component,
7.7 + enum function_role function,
7.8 const char *opname, FILE *fp);
7.9
7.10 void write_message_access(struct parameter *param, enum component_role component,
7.11 - enum specifier direction, enum parameter_class cls,
7.12 - FILE *fp);
7.13 + enum function_role function, enum specifier direction,
7.14 + enum parameter_class cls, FILE *fp);
8.1 --- a/server.c Mon Nov 25 23:40:37 2019 +0100
8.2 +++ b/server.c Tue Nov 26 21:16:24 2019 +0100
8.3 @@ -92,7 +92,10 @@
8.4 "inout" parameters. */
8.5
8.6 fprintf(fp, server_completion_function_signature_prologue, opname, iface->name);
8.7 - write_parameters(sig->parameters, fp, SIGNATURE_ROLE, OUT_PARAMETER, 1);
8.8 +
8.9 + write_parameters(sig->parameters, fp, SIGNATURE_ROLE, COMPLETION_ROLE,
8.10 + OUT_PARAMETER, 1);
8.11 +
8.12 fputs(")", fp);
8.13 fputs(get_signature_terminator(role), fp);
8.14
8.15 @@ -157,7 +160,7 @@
8.16
8.17 /* Pack the outputs into the message and perform any other housekeeping. */
8.18
8.19 - write_output_initialisation(param, fp, opname, output_words, output_items);
8.20 + write_output_initialisation(param, fp, opname, output_words, output_items, GENERAL_FUNCTION_ROLE);
8.21
8.22 /* Return the success of the reply operation. */
8.23
8.24 @@ -227,11 +230,6 @@
8.25
8.26 count_parameters(param, &input_words, &input_items, &output_words, &output_items);
8.27
8.28 - /* Generate variable declarations for serialising "out" and "inout"
8.29 - parameters. */
8.30 -
8.31 - write_declarations(param, 0, ANY_CLASS, fp);
8.32 -
8.33 /* Generate types parameterised with the qualified operation name. */
8.34
8.35 write_accessor_declaration(0, output_words, opname, fp);
8.36 @@ -242,7 +240,7 @@
8.37
8.38 /* Pack the outputs into the message and perform any other housekeeping. */
8.39
8.40 - write_output_initialisation(param, fp, opname, output_words, output_items);
8.41 + write_output_initialisation(param, fp, opname, output_words, output_items, COMPLETION_ROLE);
8.42
8.43 /* Send the response.
8.44 NOTE: The label 0 is employed but an error condition could be communicated. */
8.45 @@ -262,14 +260,17 @@
8.46 {
8.47 if (input_words)
8.48 {
8.49 - write_accessor_initialisation(IN_PARAMETER, SERVER_ROLE, opname, fp);
8.50 - write_message_access(param, SERVER_ROLE, IN_PARAMETER, WORD_CLASS, fp);
8.51 + write_accessor_initialisation(IN_PARAMETER, SERVER_ROLE, GENERAL_FUNCTION_ROLE,
8.52 + opname, fp);
8.53 + write_message_access(param, SERVER_ROLE, GENERAL_FUNCTION_ROLE, IN_PARAMETER,
8.54 + WORD_CLASS, fp);
8.55 }
8.56
8.57 if (input_items)
8.58 {
8.59 fputs("\n", fp);
8.60 - write_message_access(param, SERVER_ROLE, IN_PARAMETER, ITEM_CLASS, fp);
8.61 + write_message_access(param, SERVER_ROLE, GENERAL_FUNCTION_ROLE, IN_PARAMETER,
8.62 + ITEM_CLASS, fp);
8.63 }
8.64 }
8.65
8.66 @@ -277,18 +278,21 @@
8.67
8.68 void write_output_initialisation(struct parameter *param, FILE *fp,
8.69 const char *opname, int output_words,
8.70 - int output_items)
8.71 + int output_items, enum function_role function)
8.72 {
8.73 if (output_words)
8.74 {
8.75 - write_accessor_initialisation(OUT_PARAMETER, SERVER_ROLE, opname, fp);
8.76 - write_message_access(param, SERVER_ROLE, OUT_PARAMETER, WORD_CLASS, fp);
8.77 + write_accessor_initialisation(OUT_PARAMETER, SERVER_ROLE, function,
8.78 + opname, fp);
8.79 + write_message_access(param, SERVER_ROLE, function, OUT_PARAMETER,
8.80 + WORD_CLASS, fp);
8.81 }
8.82
8.83 if (output_items)
8.84 {
8.85 fputs("\n", fp);
8.86 - write_message_access(param, SERVER_ROLE, OUT_PARAMETER, ITEM_CLASS, fp);
8.87 + write_message_access(param, SERVER_ROLE, function, OUT_PARAMETER,
8.88 + ITEM_CLASS, fp);
8.89 }
8.90 }
8.91
8.92 @@ -320,7 +324,8 @@
8.93
8.94 /* Generate the parameter list, employing addresses for output parameters. */
8.95
8.96 - write_parameters(param, fp, INVOCATION_ROLE, specifier, continuing);
8.97 + write_parameters(param, fp, INVOCATION_ROLE, GENERAL_FUNCTION_ROLE, specifier,
8.98 + continuing);
8.99 fputs(");\n", fp);
8.100
8.101 /* Emit post-invocation details. */
9.1 --- a/server.h Mon Nov 25 23:40:37 2019 +0100
9.2 +++ b/server.h Tue Nov 26 21:16:24 2019 +0100
9.3 @@ -75,7 +75,7 @@
9.4
9.5 void write_output_initialisation(struct parameter *param, FILE *fp,
9.6 const char *opname, int output_words,
9.7 - int output_items);
9.8 + int output_items, enum function_role function);
9.9
9.10 void write_server_function_call(struct parameter *param, FILE *fp,
9.11 struct interface *iface, struct signature *sig,