1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Copyright 2020 Tintri by DDN, Inc. All rights reserved. 29 */ 30 31 #include "ndrgen.h" 32 #include "y.tab.h" 33 34 35 static void print_declaration(ndr_node_t *); 36 static void print_advice_list(ndr_node_t *); 37 static void print_node_list(ndr_node_t *); 38 39 40 void 41 tdata_dump(void) 42 { 43 print_node_list(construct_list); 44 } 45 46 void 47 print_node(ndr_node_t *np) 48 { 49 char *nm; 50 51 if (!np) { 52 (void) printf("<null>"); 53 return; 54 } 55 56 switch (np->label) { 57 case ALIGN_KW: nm = "align"; break; 58 case FAKE_KW: nm = "fake"; break; 59 case STRUCT_KW: nm = "struct"; break; 60 case UNION_KW: nm = "union"; break; 61 case TYPEDEF_KW: nm = "typedef"; break; 62 case INTERFACE_KW: nm = "interface"; break; 63 case IN_KW: nm = "in"; break; 64 case OUT_KW: nm = "out"; break; 65 case SIZE_IS_KW: nm = "size_is"; break; 66 case LENGTH_IS_KW: nm = "length_is"; break; 67 case STRING_KW: nm = "string"; break; 68 case TRANSMIT_AS_KW: nm = "transmit_as"; break; 69 case OPERATION_KW: nm = "operation"; break; 70 case UUID_KW: nm = "uuid"; break; 71 case _NO_REORDER_KW: nm = "_no_reorder"; break; 72 case EXTERN_KW: nm = "extern"; break; 73 case ARG_IS_KW: nm = "arg_is"; break; 74 case CASE_KW: nm = "case"; break; 75 case DEFAULT_KW: nm = "default"; break; 76 case BASIC_TYPE: nm = "<btype>"; break; 77 case TYPENAME: nm = "<tname>"; break; 78 case IDENTIFIER: nm = "<ident>"; break; 79 case INTEGER: nm = "<intg>"; break; 80 case STRING: nm = "<string>"; break; 81 case STAR: nm = "<*>"; break; 82 case LB: nm = "<[>"; break; 83 case LP: nm = "<(>"; break; 84 case L_MEMBER: nm = "<member>"; break; 85 default: 86 (void) printf("<<lab=%d>>", np->label); 87 return; 88 } 89 90 switch (np->label) { 91 case STRUCT_KW: 92 case UNION_KW: 93 case TYPEDEF_KW: 94 (void) printf("\n"); 95 if (np->n_c_advice) { 96 print_advice_list(np->n_c_advice); 97 (void) printf("\n"); 98 } 99 (void) printf("%s ", nm); 100 print_node(np->n_c_typename); 101 (void) printf(" {\n"); 102 print_node_list(np->n_c_members); 103 (void) printf("};\n"); 104 break; 105 106 case IN_KW: 107 case OUT_KW: 108 case STRING_KW: 109 case DEFAULT_KW: 110 case _NO_REORDER_KW: 111 case EXTERN_KW: 112 case FAKE_KW: 113 (void) printf("%s", nm); 114 break; 115 116 case ALIGN_KW: 117 /* 118 * Don't output anything for default alignment. 119 */ 120 if ((np->n_a_arg == NULL) || (np->n_a_arg->n_int == 0)) 121 break; 122 (void) printf("%s(", nm); 123 print_node(np->n_a_arg); 124 (void) printf(")"); 125 break; 126 127 case SIZE_IS_KW: 128 case LENGTH_IS_KW: 129 (void) printf("%s(", nm); 130 print_field_attr(np); 131 (void) printf(")"); 132 break; 133 134 case INTERFACE_KW: 135 case TRANSMIT_AS_KW: 136 case ARG_IS_KW: 137 case CASE_KW: 138 case OPERATION_KW: 139 case UUID_KW: 140 (void) printf("%s(", nm); 141 print_node(np->n_a_arg); 142 (void) printf(")"); 143 break; 144 145 case BASIC_TYPE: 146 case TYPENAME: 147 case IDENTIFIER: 148 (void) printf("%s", np->n_sym->name); 149 break; 150 151 case INTEGER: 152 (void) printf("%ld", np->n_int); 153 break; 154 155 case STRING: 156 (void) printf("\"%s\"", np->n_str); 157 break; 158 159 case STAR: 160 (void) printf("*"); 161 print_node(np->n_d_descend); 162 break; 163 164 case LB: 165 print_node(np->n_d_descend); 166 (void) printf("["); 167 if (np->n_d_dim) 168 print_node(np->n_d_dim); 169 (void) printf("]"); 170 break; 171 172 case LP: 173 (void) printf("("); 174 print_node(np->n_d_descend); 175 (void) printf(")"); 176 break; 177 178 case L_MEMBER: 179 if (np->n_m_advice) { 180 (void) printf(" "); 181 print_advice_list(np->n_m_advice); 182 (void) printf("\n"); 183 } 184 (void) printf("\t"); 185 print_declaration(np); 186 (void) printf(";\n"); 187 break; 188 189 default: 190 return; 191 } 192 } 193 194 /* 195 * Field attributes are used to specify the size of an array, or the portion 196 * of the array, that contains valid data, which is done by associating 197 * another parameter with the array that contains the sizing information. 198 * 199 * Supports formats such as size_is(x) or size_is(x / 2). The supported 200 * operators are: 201 * 202 * * / % + - & | ^ 203 */ 204 void 205 print_field_attr(ndr_node_t *np) 206 { 207 static char *valid = "*/%+-&|^"; 208 ndr_node_t *arg; 209 char *name; 210 char *operator; 211 long value; 212 213 arg = np->n_a_arg; 214 if (arg->label != IDENTIFIER) 215 fatal_error("invalid label %d", arg->label); 216 if ((name = arg->n_sym->name) == NULL) 217 fatal_error("missing symbol name"); 218 219 arg = np->n_a_arg1; 220 operator = NULL; 221 if (arg->label == IDENTIFIER) { 222 operator = arg->n_sym->name; 223 224 if (operator != NULL) { 225 /* 226 * The lexer sets the name and operator to 227 * the same value if there is no operator. 228 */ 229 if (strcmp(name, operator) == 0) 230 operator = NULL; 231 else if (strchr(valid, *operator) == NULL) 232 compile_error("invalid operator: %s", operator); 233 } 234 } 235 236 arg = np->n_a_arg2; 237 if (arg->label == INTEGER) { 238 value = arg->n_int; 239 240 if ((value == 0) && strcmp(operator, "/") == 0) 241 compile_error("divide by zero"); 242 } 243 244 if (operator) 245 (void) printf("%s %s %ldUL", name, operator, value); 246 else 247 (void) printf("%s", name); 248 } 249 250 static void 251 print_declaration(ndr_node_t *np) 252 { 253 ndr_node_t *dnp = np->n_m_decl; 254 char buf[NDLBUFSZ]; 255 char *p = buf; 256 257 if (np->n_m_type && 258 (np->n_m_type->label == IDENTIFIER || 259 np->n_m_type->label == TYPENAME)) { 260 (void) snprintf(buf, NDLBUFSZ, "%s", np->n_m_type->n_sym->name); 261 262 while (*p) 263 p++; 264 265 if (dnp && dnp->label == STAR) { 266 *p++ = ' '; 267 while (dnp && dnp->label == STAR) { 268 *p++ = '*'; 269 dnp = dnp->n_d_descend; 270 } 271 } 272 *p = 0; 273 (void) printf("%-23s ", buf); 274 } else { 275 print_node(np->n_m_type); 276 (void) printf(" "); 277 } 278 279 print_node(dnp); 280 } 281 282 static void 283 print_advice_list(ndr_node_t *np) 284 { 285 if (!np) 286 return; 287 288 (void) printf("["); 289 for (; np; np = np->n_next) { 290 print_node(np); 291 if (np->n_next) 292 (void) printf(" "); 293 } 294 (void) printf("]"); 295 } 296 297 static void 298 print_node_list(ndr_node_t *np) 299 { 300 for (; np; np = np->n_next) { 301 print_node(np); 302 } 303 } 304