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
tdata_dump(void)41 tdata_dump(void)
42 {
43 print_node_list(construct_list);
44 }
45
46 void
print_node(ndr_node_t * np)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
print_field_attr(ndr_node_t * np)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
print_declaration(ndr_node_t * np)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
print_advice_list(ndr_node_t * np)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
print_node_list(ndr_node_t * np)298 print_node_list(ndr_node_t *np)
299 {
300 for (; np; np = np->n_next) {
301 print_node(np);
302 }
303 }
304