1 /* 2 * Structure definition. 3 * 4 * Copyright (C) 2019, 2023 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 <stdlib.h> 23 #include <string.h> 24 #include "common.h" 25 #include "config.h" 26 #include "declaration.h" 27 #include "structure.h" 28 #include "templates.h" 29 30 /* Generate an enumeration of operator codes. */ 31 32 void write_opcode_definition(struct interface *iface, FILE *fp) 33 { 34 fprintf(fp, opcode_enumeration_prologue, iface->name); 35 write_opcodes(iface->signatures, fp, iface->name); 36 fputs(opcode_enumeration_epilogue, fp); 37 } 38 39 /* Generate operator code enumeration entries. */ 40 41 void write_opcodes(struct signature *sig, FILE *fp, const char *name) 42 { 43 char *opcode; 44 45 if (sig == NULL) 46 return; 47 48 fprintf(fp, opcode_identifier, name, sig->operation); 49 50 /* Obtain any explicit opcode from the signature attributes. */ 51 52 opcode = get_opcode(sig->attributes); 53 if (opcode != NULL) 54 fprintf(fp, " = %s", opcode); 55 56 fputs(",\n", fp); 57 58 write_opcodes(sig->tail, fp, name); 59 } 60 61 /* Generate structures for messages corresponding to the signatures. */ 62 63 void write_structures(struct signature *sig, FILE *fp, struct interface *iface) 64 { 65 if (sig == NULL) 66 return; 67 68 write_structure(sig, fp, iface); 69 write_structures(sig->tail, fp, iface); 70 } 71 72 /* Terminate a structure definition, setting any explicit structure 73 alignment. */ 74 75 static void write_structure_alignment(FILE *fp) 76 { 77 char alignment[32]; 78 79 if (conf.alignment) 80 sprintf(alignment, structure_epilogue_alignment, conf.alignment); 81 else 82 strcpy(alignment, ""); 83 84 fprintf(fp, structure_epilogue, alignment); 85 } 86 87 /* Generate message structures for a signature. */ 88 89 void write_structure(struct signature *sig, FILE *fp, struct interface *iface) 90 { 91 struct parameter *param = sig->parameters; 92 char *opname = get_operation_name(iface, sig), 93 *protocol = get_protocol(iface->attributes), 94 *opcode_type; 95 int input_words, input_items, output_words, output_items; 96 97 count_parameters(param, &input_words, &input_items, &output_words, &output_items); 98 99 /* Adjust the input words where a protocol is used as the opcode. */ 100 101 if (protocol != NULL) 102 input_words++; 103 104 /* Generate the structures for populating and interpreting messages. */ 105 106 if (input_words) 107 { 108 fprintf(fp, structure_prologue, "in", opname); 109 if (protocol != NULL) 110 { 111 opcode_type = get_opcode_type(sig->attributes); 112 113 if (opcode_type != NULL) 114 fprintf(fp, structure_opcode_member, opcode_type); 115 else 116 fprintf(fp, structure_opcode_member, L4_OPCODE_TYPE); 117 } 118 write_declarations(param, IN_PARAMETER, WORD_CLASS, fp); 119 write_structure_alignment(fp); 120 } 121 122 if (output_words) 123 { 124 fprintf(fp, structure_prologue, "out", opname); 125 write_declarations(param, OUT_PARAMETER, WORD_CLASS, fp); 126 write_structure_alignment(fp); 127 } 128 129 /* Free allocated strings. */ 130 131 free(opname); 132 }