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