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