paul@98 | 1 | /* |
paul@100 | 2 | * Generation of message structure access operations. |
paul@98 | 3 | * |
paul@202 | 4 | * Copyright (C) 2019, 2022 Paul Boddie <paul@boddie.org.uk> |
paul@98 | 5 | * |
paul@98 | 6 | * This program is free software; you can redistribute it and/or |
paul@98 | 7 | * modify it under the terms of the GNU General Public License as |
paul@98 | 8 | * published by the Free Software Foundation; either version 2 of |
paul@98 | 9 | * the License, or (at your option) any later version. |
paul@98 | 10 | * |
paul@98 | 11 | * This program is distributed in the hope that it will be useful, |
paul@98 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
paul@98 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
paul@98 | 14 | * GNU General Public License for more details. |
paul@98 | 15 | * |
paul@98 | 16 | * You should have received a copy of the GNU General Public License |
paul@98 | 17 | * along with this program; if not, write to the Free Software |
paul@98 | 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, |
paul@98 | 19 | * Boston, MA 02110-1301, USA |
paul@98 | 20 | */ |
paul@98 | 21 | |
paul@98 | 22 | #include "common.h" |
paul@98 | 23 | #include "message.h" |
paul@121 | 24 | #include "templates.h" |
paul@98 | 25 | |
paul@98 | 26 | /* Generate a variable declaration for message word accessors. */ |
paul@98 | 27 | |
paul@98 | 28 | void write_accessor_declaration(int input_words, int output_words, |
paul@124 | 29 | const char *opname, FILE *fp) |
paul@98 | 30 | { |
paul@98 | 31 | if (input_words) |
paul@121 | 32 | fprintf(fp, message_accessor_declaration, "in", opname, "in"); |
paul@98 | 33 | |
paul@98 | 34 | if (output_words) |
paul@121 | 35 | fprintf(fp, message_accessor_declaration, "out", opname, "out"); |
paul@98 | 36 | } |
paul@98 | 37 | |
paul@98 | 38 | /* Generate a variable initialisation for message word accessors. */ |
paul@98 | 39 | |
paul@98 | 40 | void write_accessor_initialisation(enum specifier direction, |
paul@98 | 41 | enum component_role component, |
paul@129 | 42 | enum function_role function, |
paul@124 | 43 | const char *opname, FILE *fp) |
paul@98 | 44 | { |
paul@98 | 45 | char *prefix = structure_prefix(direction); |
paul@129 | 46 | char *addr = reference_message(component, function); |
paul@98 | 47 | |
paul@121 | 48 | fprintf(fp, message_accessor_initialisation, prefix, prefix, opname); |
paul@98 | 49 | |
paul@98 | 50 | /* When writing to the message, the accessor will reserve space. |
paul@98 | 51 | When reading from the message, only words will be present. */ |
paul@98 | 52 | |
paul@98 | 53 | if (writing_to_message(component, direction)) |
paul@121 | 54 | fprintf(fp, message_accessor_writing_initialiser, addr, prefix, opname); |
paul@98 | 55 | else |
paul@121 | 56 | fprintf(fp, message_accessor_reading_initialiser, addr); |
paul@98 | 57 | } |
paul@98 | 58 | |
paul@98 | 59 | /* Copy values between a message and local names. */ |
paul@98 | 60 | |
paul@98 | 61 | void write_message_access(struct parameter *param, enum component_role component, |
paul@129 | 62 | enum function_role function, enum specifier direction, |
paul@129 | 63 | enum parameter_class cls, FILE *fp) |
paul@98 | 64 | { |
paul@203 | 65 | char *name, *access, *prefix, *suffix, *addr; |
paul@98 | 66 | int writing = writing_to_message(component, direction); |
paul@98 | 67 | int index; |
paul@98 | 68 | |
paul@98 | 69 | /* Establish type and variable naming or message access conventions. */ |
paul@98 | 70 | |
paul@98 | 71 | switch (cls) |
paul@98 | 72 | { |
paul@98 | 73 | case WORD_CLASS: prefix = structure_prefix(direction); break; |
paul@129 | 74 | case ITEM_CLASS: addr = reference_message(component, function); break; |
paul@98 | 75 | } |
paul@98 | 76 | |
paul@98 | 77 | /* Generate an access operation for parameters having the indicated direction, |
paul@98 | 78 | and having the indicated class (word or item). */ |
paul@98 | 79 | |
paul@98 | 80 | for (index = 0; param != NULL; param = param->tail) |
paul@98 | 81 | { |
paul@204 | 82 | /* Permit the specification of receive window flexpage input items for |
paul@204 | 83 | "out fpage" parameters. */ |
paul@204 | 84 | |
paul@204 | 85 | if ((param->cls & cls) && |
paul@204 | 86 | ((param->specifier & direction) || |
paul@204 | 87 | specify_receive_fpage(param, component, writing))) |
paul@98 | 88 | { |
paul@98 | 89 | name = get_parameter_name(param->identifiers); |
paul@202 | 90 | access = access_name(param, component, writing); |
paul@98 | 91 | |
paul@98 | 92 | switch (cls) |
paul@98 | 93 | { |
paul@98 | 94 | /* For words, access the message structure. */ |
paul@98 | 95 | |
paul@98 | 96 | case WORD_CLASS: |
paul@98 | 97 | if (writing) |
paul@98 | 98 | fprintf(fp, " %s_words->%s = %s%s;\n", prefix, name, access, name); |
paul@98 | 99 | else |
paul@98 | 100 | fprintf(fp, " %s%s = %s_words->%s;\n", access, name, prefix, name); |
paul@98 | 101 | break; |
paul@98 | 102 | |
paul@98 | 103 | /* For items, perform access operations. */ |
paul@98 | 104 | |
paul@98 | 105 | case ITEM_CLASS: |
paul@203 | 106 | suffix = item_type_name(param, component, writing); |
paul@203 | 107 | |
paul@98 | 108 | if (writing) |
paul@98 | 109 | fprintf(fp, " ipc_message_add_%s(%smsg, %s%s);\n", |
paul@203 | 110 | suffix, addr, access, name); |
paul@98 | 111 | else |
paul@98 | 112 | fprintf(fp, " ipc_message_import_%s(%smsg, %d, %s%s);\n", |
paul@203 | 113 | suffix, addr, index, access, name); |
paul@98 | 114 | index++; |
paul@98 | 115 | break; |
paul@98 | 116 | |
paul@98 | 117 | default: |
paul@98 | 118 | break; |
paul@98 | 119 | } |
paul@98 | 120 | } |
paul@98 | 121 | } |
paul@98 | 122 | } |