# HG changeset patch # User Paul Boddie # Date 1572634287 -3600 # Node ID 393ad3cc80e927f3228b39751130b5e798be53b0 # Parent 6d74b6740f4d9a35f817c84e86b2d0fc5fbfe1ff Introduced common functions for message accessor declaration and initialisation. Introduced a component role enumeration to support such common functionality. diff -r 6d74b6740f4d -r 393ad3cc80e9 program.c --- a/program.c Fri Nov 01 19:14:33 2019 +0100 +++ b/program.c Fri Nov 01 19:51:27 2019 +0100 @@ -67,10 +67,10 @@ " long err;\n"; static char client_function_body_call[] = -" ipc_message_request(&msg, %s, _endp);\n\n" +"\n ipc_message_request(&msg, %s, _endp);\n\n" " err = l4_error(msg.tag);\n" " if (err)\n" -" return err;\n\n"; +" return err;\n"; static char common_prologue[] = "#pragma once\n\n" @@ -109,7 +109,7 @@ static char server_function_body_call[] = " if (err)\n" -" return err;\n\n"; +" return err;\n"; static char server_function_dispatcher_body_epilogue[] = " default:\n" @@ -768,22 +768,18 @@ /* Generate types parameterised with the qualified operation name. */ - if (input_words) - fprintf(fp, " struct in_words_%s *in_words;\n", opname); - - if (output_words) - fprintf(fp, " struct out_words_%s *out_words;\n", opname); + write_accessor_declaration(input_words, output_words, opname, fp); /* Initialise the message. */ - fprintf(fp, "\n ipc_message_new(&msg);\n\n"); + fprintf(fp, "\n ipc_message_new(&msg);\n"); /* Generate expected output item requirements. */ if (output_items) fprintf(fp, " err = ipc_message_expect(&msg, %d);\n" " if (err)\n" - " return err;\n\n", output_items); + " return err;\n", output_items); /* Populate input parameters in the message. Dereference function parameters acting as "inout" parameters. */ @@ -793,9 +789,7 @@ /* Reserve space for the words before any items, obtaining a pointer to the words. */ - fprintf(fp, " in_words = (struct in_words_%s *)" - " ipc_message_reserve_words(&msg," - " sizeof(struct in_words_%s));\n", opname, opname); + write_accessor_initialisation(IN_PARAMETER, CLIENT_ROLE, opname, fp); if (protocol != NULL) fprintf(fp, " in_words->_op = %s;\n", opname); @@ -806,7 +800,10 @@ /* Do the same for items. */ if (input_items) + { + fputs("\n", fp); copy_items_to_message(param, IN_PARAMETER, fp); + } /* Send the request. */ @@ -816,20 +813,21 @@ if (output_words) { - fprintf(fp, " out_words = (struct out_words_%s *)" - " ipc_message_get_word_address(&msg, 0);\n", opname); - + write_accessor_initialisation(OUT_PARAMETER, CLIENT_ROLE, opname, fp); copy_words_from_message(param, OUT_PARAMETER, fp); } /* Do the same for items. */ if (output_items) + { + fputs("\n", fp); copy_items_from_message(param, OUT_PARAMETER, fp); + } /* Return success. */ - fprintf(fp, " return L4_EOK;\n"); + fprintf(fp, "\n return L4_EOK;\n"); /* Free allocated strings. */ @@ -861,24 +859,21 @@ /* Generate types parameterised with the qualified operation name. */ - if (input_words) - fprintf(fp, " struct in_words_%s *in_words;\n", opname); - - if (output_words) - fprintf(fp, " struct out_words_%s *out_words;\n", opname); + write_accessor_declaration(input_words, output_words, opname, fp); /* Unpack each word and item from the message into variables. */ if (input_words) { - fprintf(fp, "\n in_words = (struct in_words_%s *)" - " ipc_message_get_word_address(msg, 0);\n", opname); - + write_accessor_initialisation(IN_PARAMETER, SERVER_ROLE, opname, fp); copy_words_from_message(param, IN_PARAMETER, fp); } if (input_items) + { + fputs("\n", fp); copy_items_from_message(param, IN_PARAMETER, fp); + } /* Invoke the actual operation using the variables. */ @@ -888,19 +883,19 @@ if (output_words) { - fprintf(fp, " out_words = (struct out_words_%s *)" - " ipc_message_reserve_words(msg," - " sizeof(struct out_words_%s));\n", opname, opname); - + write_accessor_initialisation(OUT_PARAMETER, SERVER_ROLE, opname, fp); copy_words_to_message(param, OUT_PARAMETER, fp); } if (output_items) + { + fputs("\n", fp); copy_items_to_message(param, OUT_PARAMETER, fp); + } /* Return success. */ - fprintf(fp, " return L4_EOK;\n"); + fprintf(fp, "\n return L4_EOK;\n"); /* Free allocated strings. */ @@ -927,6 +922,42 @@ fputs(server_function_body_call, fp); } +/* Generate a variable declaration for message word accessors. */ + +void write_accessor_declaration(int input_words, int output_words, + char *opname, FILE *fp) +{ + if (input_words) + fprintf(fp, " struct in_words_%s *in_words;\n", opname); + + if (output_words) + fprintf(fp, " struct out_words_%s *out_words;\n", opname); +} + +/* Generate a variable initialisation for message word accessors. */ + +void write_accessor_initialisation(enum specifier direction, + enum component_role component, + char *opname, FILE *fp) +{ + char *prefix = direction == IN_PARAMETER ? "in" : "out"; + char *addr = component == CLIENT_ROLE ? "&" : ""; + + int writing = (component == CLIENT_ROLE) && (direction & IN_PARAMETER) || + (component == SERVER_ROLE) && (direction & OUT_PARAMETER); + + fprintf(fp, "\n %s_words = (struct %s_words_%s *)", prefix, prefix, opname); + + /* When writing to the message, the accessor will reserve space. + When reading from the message, only words will be present. */ + + if (writing) + fprintf(fp, " ipc_message_reserve_words(%smsg," + " sizeof(struct %s_words_%s));\n", addr, prefix, opname); + else + fprintf(fp, " ipc_message_get_word_address(%smsg, 0);\n", addr); +} + /* Generate structures for messages corresponding to the signatures. */ void write_structures(struct signature *sig, FILE *fp, struct interface *iface) diff -r 6d74b6740f4d -r 393ad3cc80e9 program.h --- a/program.h Fri Nov 01 19:14:33 2019 +0100 +++ b/program.h Fri Nov 01 19:51:27 2019 +0100 @@ -35,6 +35,14 @@ STRUCTURE_ROLE, }; +/* Component roles. */ + +enum component_role +{ + CLIENT_ROLE, + SERVER_ROLE, +}; + /* Component-level processing. */ void begin_common_dispatcher(void); @@ -100,7 +108,14 @@ void write_opcodes(struct signature *sig, FILE *fp, const char *name); -/* Structure members and variable lists. */ +/* Structure member and variable declaration/initialisation. */ void write_declarations(struct parameter *param, enum specifier direction, enum parameter_class cls, FILE *fp); + +void write_accessor_declaration(int input_words, int output_words, + char *opname, FILE *fp); + +void write_accessor_initialisation(enum specifier direction, + enum component_role component, + char *opname, FILE *fp);