1 /* 2 * Generation of message structure access operations. 3 * 4 * Copyright (C) 2019, 2022, 2024 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 "common.h" 23 #include "message.h" 24 #include "templates.h" 25 26 /* Generate a variable declaration for message word accessors. */ 27 28 void write_accessor_declaration(int input_words, int output_words, 29 const char *opname, FILE *fp) 30 { 31 if (input_words) 32 fprintf(fp, message_accessor_declaration, "in", opname, "in"); 33 34 if (output_words) 35 fprintf(fp, message_accessor_declaration, "out", opname, "out"); 36 } 37 38 /* Generate a variable initialisation for message word accessors. */ 39 40 void write_accessor_initialisation(enum specifier direction, 41 enum component_role component, 42 enum function_role function, 43 const char *opname, FILE *fp) 44 { 45 char *prefix = structure_prefix(direction); 46 char *addr = reference_message(component, function); 47 48 fprintf(fp, message_accessor_initialisation, prefix, prefix, opname); 49 50 /* When writing to the message, the accessor will reserve space. 51 When reading from the message, only words will be present. */ 52 53 if (writing_to_message(component, direction)) 54 fprintf(fp, message_accessor_writing_initialiser, addr, prefix, opname); 55 else 56 fprintf(fp, message_accessor_reading_initialiser, addr); 57 } 58 59 /* Copy values between a message and local names. */ 60 61 void write_message_access(struct parameter *param, enum component_role component, 62 enum function_role function, enum specifier direction, 63 enum parameter_class cls, FILE *fp) 64 { 65 char *name, *access, *prefix, *suffix, *addr; 66 int writing = writing_to_message(component, direction); 67 int index; 68 69 /* Establish type and variable naming or message access conventions. */ 70 71 switch (cls) 72 { 73 case WORD_CLASS: prefix = structure_prefix(direction); break; 74 case ITEM_CLASS: addr = reference_message(component, function); break; 75 } 76 77 /* Generate an access operation for parameters having the indicated direction, 78 and having the indicated class (word or item). */ 79 80 for (index = 0; param != NULL; param = param->tail) 81 { 82 /* Permit the specification of receive window flexpage and returned 83 capability items for "out fpage" and "out cap" parameters, even when 84 processing inputs to an operation. */ 85 86 if ((param->cls & cls) && 87 ((param->specifier & direction) || 88 specify_receive_item(param, component, writing))) 89 { 90 name = get_parameter_name(param->identifiers); 91 access = access_name(param, component, writing); 92 93 switch (cls) 94 { 95 /* For words, access the message structure. */ 96 97 case WORD_CLASS: 98 if (writing) 99 fprintf(fp, " %s_words->%s = %s%s;\n", prefix, name, access, name); 100 else 101 fprintf(fp, " %s%s = %s_words->%s;\n", access, name, prefix, name); 102 break; 103 104 /* For items, perform access operations. */ 105 106 case ITEM_CLASS: 107 suffix = item_type_name(param, component, writing); 108 109 if (writing) 110 fprintf(fp, " ipc_message_add_%s(%smsg, %s%s);\n", 111 suffix, addr, access, name); 112 else 113 { 114 /* For servers, update the buffer registers for future capabilities, 115 allocating new capability slots. */ 116 117 if (component == SERVER_ROLE) 118 fprintf(fp, " ipc_message_import_and_expect_%s(%smsg, %d, %s%s);\n", 119 suffix, addr, index, access, name); 120 else 121 fprintf(fp, " ipc_message_import_%s(%smsg, %d, %s%s);\n", 122 suffix, addr, index, access, name); 123 } 124 index++; 125 break; 126 127 default: 128 break; 129 } 130 } 131 } 132 }