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
tdata_dump(void)37 tdata_dump(void)
38 {
39 print_node_list(construct_list);
40 }
41
42 void
print_node(ndr_node_t * np)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
print_field_attr(ndr_node_t * np)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
print_declaration(ndr_node_t * np)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
print_advice_list(ndr_node_t * np)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
print_node_list(ndr_node_t * np)292 print_node_list(ndr_node_t *np)
293 {
294 for (; np; np = np->n_next) {
295 print_node(np);
296 }
297 }
298