xref: /titanic_44/usr/src/cmd/abi/spectrans/spec2trace/bindings.c (revision 753d2d2e8e7fd0c9bcf736d9bf2f2faf4d6234cc)
1*753d2d2eSraf /*
2*753d2d2eSraf  * CDDL HEADER START
3*753d2d2eSraf  *
4*753d2d2eSraf  * The contents of this file are subject to the terms of the
5*753d2d2eSraf  * Common Development and Distribution License, Version 1.0 only
6*753d2d2eSraf  * (the "License").  You may not use this file except in compliance
7*753d2d2eSraf  * with the License.
8*753d2d2eSraf  *
9*753d2d2eSraf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*753d2d2eSraf  * or http://www.opensolaris.org/os/licensing.
11*753d2d2eSraf  * See the License for the specific language governing permissions
12*753d2d2eSraf  * and limitations under the License.
13*753d2d2eSraf  *
14*753d2d2eSraf  * When distributing Covered Code, include this CDDL HEADER in each
15*753d2d2eSraf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*753d2d2eSraf  * If applicable, add the following below this CDDL HEADER, with the
17*753d2d2eSraf  * fields enclosed by brackets "[]" replaced with your own identifying
18*753d2d2eSraf  * information: Portions Copyright [yyyy] [name of copyright owner]
19*753d2d2eSraf  *
20*753d2d2eSraf  * CDDL HEADER END
21*753d2d2eSraf  */
22*753d2d2eSraf /*
23*753d2d2eSraf  * Copyright (c) 1997-1999 by Sun Microsystems, Inc.
24*753d2d2eSraf  * All rights reserved.
25*753d2d2eSraf  */
26*753d2d2eSraf 
27*753d2d2eSraf #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*753d2d2eSraf 
29*753d2d2eSraf #include <stdio.h>
30*753d2d2eSraf #include <string.h>
31*753d2d2eSraf #include "parser.h"
32*753d2d2eSraf #include "trace.h"
33*753d2d2eSraf #include "util.h"
34*753d2d2eSraf #include "symtab.h"
35*753d2d2eSraf #include "io.h"
36*753d2d2eSraf #include "bindings.h"
37*753d2d2eSraf #include "errlog.h"
38*753d2d2eSraf 
39*753d2d2eSraf 
40*753d2d2eSraf /* File globals. */
41*753d2d2eSraf static void generate_a_binding(char *, char *);
42*753d2d2eSraf 
43*753d2d2eSraf static int strpqcmp(char *, char *, char *);
44*753d2d2eSraf static void strpqprint(char *, char *, FILE *);
45*753d2d2eSraf 
46*753d2d2eSraf /*
47*753d2d2eSraf  * Bindings: do three-valued logic, where a binding can be
48*753d2d2eSraf  *	an expression to evaluate for truthfulness,
49*753d2d2eSraf  *	true,
50*753d2d2eSraf  *	false, or
51*753d2d2eSraf  *	empty.
52*753d2d2eSraf  *
53*753d2d2eSraf  *	Exception	Result	Evaluate?	Notes
54*753d2d2eSraf  *	---------	------	---------	-----
55*753d2d2eSraf  *
56*753d2d2eSraf  *	true		ok	yes		warn[1]
57*753d2d2eSraf  *	false		ok	no
58*753d2d2eSraf  *	empty		ok	no		treat as true
59*753d2d2eSraf  *	expr		ok	yes		s = !e
60*753d2d2eSraf  *
61*753d2d2eSraf  * Notes:
62*753d2d2eSraf  *	[1] Always exceptional, shows errno at run-time
63*753d2d2eSraf  *
64*753d2d2eSraf  */
65*753d2d2eSraf 
66*753d2d2eSraf /*
67*753d2d2eSraf  * need_bindings -- see if we have to do anything at all. Implements
68*753d2d2eSraf  *	the following rows from the table above (die and evaluate=no lines)
69*753d2d2eSraf  *	Returns NO if we don't have to evaluate bindings at all.
70*753d2d2eSraf  *
71*753d2d2eSraf  *	Exception	Result	Evaluate?	Notes
72*753d2d2eSraf  *	---------	------	---------	-----
73*753d2d2eSraf  *	false		ok	no
74*753d2d2eSraf  *	empty		ok	no		treat as true
75*753d2d2eSraf  */
76*753d2d2eSraf int
need_bindings(char * exception)77*753d2d2eSraf need_bindings(char *exception)
78*753d2d2eSraf {
79*753d2d2eSraf 
80*753d2d2eSraf 	errlog(BEGIN, "need_bindings() {");
81*753d2d2eSraf 
82*753d2d2eSraf 	if (exception == NULL)
83*753d2d2eSraf 		exception = "";
84*753d2d2eSraf 
85*753d2d2eSraf 	/*	empty		false		ok	no */
86*753d2d2eSraf 	/*	empty		empty		ok	no, treat as true */
87*753d2d2eSraf 	if (strcmp(exception, "false") == 0 ||
88*753d2d2eSraf 	    *exception == '\0') {
89*753d2d2eSraf 		errlog(END, "}");
90*753d2d2eSraf 		return (NO);
91*753d2d2eSraf 	}
92*753d2d2eSraf 	errlog(END, "}");
93*753d2d2eSraf 	return (YES);
94*753d2d2eSraf }
95*753d2d2eSraf 
96*753d2d2eSraf 
97*753d2d2eSraf int
need_exception_binding(void)98*753d2d2eSraf need_exception_binding(void)
99*753d2d2eSraf {
100*753d2d2eSraf 	ENTRY	*e;
101*753d2d2eSraf 	char *exception;
102*753d2d2eSraf 
103*753d2d2eSraf 	exception = ((e = symtab_get_exception()) != NULL)?
104*753d2d2eSraf 	    (name_of(e)? name_of(e): ""): "";
105*753d2d2eSraf 
106*753d2d2eSraf 	return (need_bindings(exception));
107*753d2d2eSraf 
108*753d2d2eSraf }
109*753d2d2eSraf 
110*753d2d2eSraf /*
111*753d2d2eSraf  * generate_bindings -- make the code for exception bindings
112*753d2d2eSraf  *
113*753d2d2eSraf  *	Exception	Result	Evaluate?	Notes
114*753d2d2eSraf  *	---------	------	---------	-----
115*753d2d2eSraf  *	true		ok	yes		warn[2]
116*753d2d2eSraf  *	expr		ok	yes		s::= !e
117*753d2d2eSraf  *
118*753d2d2eSraf  *	Returns NO if we need both bindings, YES (ANTONYM) if we
119*753d2d2eSraf  *	only need to evaluate success.
120*753d2d2eSraf  */
121*753d2d2eSraf int
generate_bindings(char * exception)122*753d2d2eSraf generate_bindings(char *exception)
123*753d2d2eSraf {
124*753d2d2eSraf 	int ret = NO;
125*753d2d2eSraf 
126*753d2d2eSraf 	errlog(BEGIN, "generate_bindings() {");
127*753d2d2eSraf 	errlog(TRACING,  "exception=%s\n", exception ? exception : "NULL");
128*753d2d2eSraf 
129*753d2d2eSraf 	/* Exception	Result	Evaluate?	Notes	*/
130*753d2d2eSraf 	/* ---------	------	---------	-----	*/
131*753d2d2eSraf 	/* true		ok	yes		warn[2] */
132*753d2d2eSraf 	if (exception != NULL) {
133*753d2d2eSraf 		generate_a_binding("exception", exception);
134*753d2d2eSraf 		errlog(END, "}");
135*753d2d2eSraf 	}
136*753d2d2eSraf 
137*753d2d2eSraf 	return (ret);
138*753d2d2eSraf }
139*753d2d2eSraf 
140*753d2d2eSraf /*
141*753d2d2eSraf  * bindings_exist -- make sure we don't use one if they're not there.
142*753d2d2eSraf  */
143*753d2d2eSraf int
bindings_exist(void)144*753d2d2eSraf bindings_exist(void)
145*753d2d2eSraf {
146*753d2d2eSraf 	int ret;
147*753d2d2eSraf 
148*753d2d2eSraf 	errlog(BEGIN, "bindings_exist() {");
149*753d2d2eSraf 	errlog(END, "}");
150*753d2d2eSraf 
151*753d2d2eSraf 	ret = validity_of(symtab_get_exception()) == YES;
152*753d2d2eSraf 
153*753d2d2eSraf 	return (ret);
154*753d2d2eSraf }
155*753d2d2eSraf 
156*753d2d2eSraf 
157*753d2d2eSraf 
158*753d2d2eSraf /*
159*753d2d2eSraf  * generate_a_binding -- generate just one, with a set of transformations
160*753d2d2eSraf  *	applied. Eg, return->_return, errno->functions_errvar,
161*753d2d2eSraf  *	unchanged(x)->x == 0, etc. Oneof and someof TBD.
162*753d2d2eSraf  */
163*753d2d2eSraf static void
generate_a_binding(char * name,char * value)164*753d2d2eSraf generate_a_binding(char *name, char *value)
165*753d2d2eSraf {
166*753d2d2eSraf 	char *p = value;
167*753d2d2eSraf 	ENTRY	*e = symtab_get_errval();
168*753d2d2eSraf 	char	*errvar = (e == NULL)? NULL: name_of(e);
169*753d2d2eSraf 	char	*q;
170*753d2d2eSraf 
171*753d2d2eSraf 	errlog(BEGIN, "generate_a_binding() {");
172*753d2d2eSraf 	if (*value == NULL) {
173*753d2d2eSraf 		errlog(FATAL, "programmer error: asked to generate an "
174*753d2d2eSraf 			"empty binding");
175*753d2d2eSraf 	}
176*753d2d2eSraf 
177*753d2d2eSraf 	{
178*753d2d2eSraf 		/*
179*753d2d2eSraf 		 * XXX - friggin spaghetti
180*753d2d2eSraf 		 */
181*753d2d2eSraf 		ENTRY	*exc = symtab_get_exception();
182*753d2d2eSraf 
183*753d2d2eSraf 		if (exc != NULL)
184*753d2d2eSraf 			(void) fprintf(Bodyfp,
185*753d2d2eSraf 			    "#line %d \"%s\"\n",
186*753d2d2eSraf 			    line_of(exc), symtab_get_filename());
187*753d2d2eSraf 	}
188*753d2d2eSraf 
189*753d2d2eSraf 	/* Generate prefix. */
190*753d2d2eSraf 	(void) fprintf(Bodyfp, "    %s = (", name);
191*753d2d2eSraf 
192*753d2d2eSraf 	/* Walk across line, emitting tokens and transformed tokens */
193*753d2d2eSraf 
194*753d2d2eSraf 	for (; *p != NULL; p = q) {
195*753d2d2eSraf 		p = skipb(p);
196*753d2d2eSraf 		q = nextsep(p);
197*753d2d2eSraf 
198*753d2d2eSraf 		if (p == q) {
199*753d2d2eSraf 			/* We're at the end, a "(", ")" or an operator. */
200*753d2d2eSraf 			if (*p == '(') {
201*753d2d2eSraf 				/* We're at a parenthesized expression */
202*753d2d2eSraf 				q++;
203*753d2d2eSraf 			} else if (*p == ')') {
204*753d2d2eSraf 				/* And the end of an expression. */
205*753d2d2eSraf 				q++;
206*753d2d2eSraf 			} else if (*p == '!' && *(p+1) != '=') {
207*753d2d2eSraf 				/* Or a negated expression */
208*753d2d2eSraf 				q++;
209*753d2d2eSraf 			} else if ((q = nextb(p)) == p) {
210*753d2d2eSraf 				/* Real end! */
211*753d2d2eSraf 				break;
212*753d2d2eSraf 			}
213*753d2d2eSraf 
214*753d2d2eSraf 			/* Else it was an operator, boogy onwards. */
215*753d2d2eSraf 		}
216*753d2d2eSraf 		if (strpqcmp("$return", p, q) == 0) {
217*753d2d2eSraf 			(void) fputs("_return", Bodyfp);
218*753d2d2eSraf 		} else if (errvar != NULL && strpqcmp(errvar, p, q) == 0) {
219*753d2d2eSraf 			(void) fputs("functions_errvar", Bodyfp);
220*753d2d2eSraf 		} else if (strpqcmp("unchanged", p, q) == 0) {
221*753d2d2eSraf 			/* This will look odd. */
222*753d2d2eSraf 			(void) fputs("0 == ", Bodyfp);
223*753d2d2eSraf 		} else if (strpqcmp("oneof", p, q) == 0) {
224*753d2d2eSraf 			errlog(WARNING,  "Oneof unimplemented in spec2trace"
225*753d2d2eSraf 				"It will be treated as the token 'false'");
226*753d2d2eSraf 			(void) fputs("false", Bodyfp);
227*753d2d2eSraf 			break;
228*753d2d2eSraf 		} else if (strpqcmp("someof", p, q) == 0) {
229*753d2d2eSraf 			errlog(WARNING, "Someof unimplemented in spec2trace, "
230*753d2d2eSraf 				"It will be treated as the token 'false'");
231*753d2d2eSraf 			(void) fputs("false", Bodyfp);
232*753d2d2eSraf 			break;
233*753d2d2eSraf 		} else if (strpqcmp("errno", p, q) == 0) {
234*753d2d2eSraf 			(void) fputs("ABI_ERRNO", Bodyfp);
235*753d2d2eSraf 		} else {
236*753d2d2eSraf 			/* Just copy it. */
237*753d2d2eSraf 
238*753d2d2eSraf 			strpqprint(p, q, Bodyfp);
239*753d2d2eSraf 		}
240*753d2d2eSraf 		(void) putc(' ', Bodyfp);
241*753d2d2eSraf 	}
242*753d2d2eSraf 	(void) (void) fputs(");\n", Bodyfp);
243*753d2d2eSraf 	errlog(END, "}");
244*753d2d2eSraf }
245*753d2d2eSraf 
246*753d2d2eSraf /*
247*753d2d2eSraf  * strpqcmp -- compare a null-terminated string with a pq-bracketed string.
248*753d2d2eSraf  */
249*753d2d2eSraf static int
strpqcmp(char * v1,char * p,char * q)250*753d2d2eSraf strpqcmp(char *v1, char *p, char *q)
251*753d2d2eSraf {
252*753d2d2eSraf 	int	rc;
253*753d2d2eSraf 	char	saved;
254*753d2d2eSraf 
255*753d2d2eSraf 	errlog(BEGIN, "strpqcmp() {");
256*753d2d2eSraf 	saved = *q;
257*753d2d2eSraf 	*q = NULL;
258*753d2d2eSraf 	rc = (strcmp(v1, p));
259*753d2d2eSraf 	*q = saved;
260*753d2d2eSraf 	errlog(END, "}");
261*753d2d2eSraf 	return (rc);
262*753d2d2eSraf }
263*753d2d2eSraf 
264*753d2d2eSraf /*
265*753d2d2eSraf  * strpqprint -- print a pq-bracketed string
266*753d2d2eSraf  */
267*753d2d2eSraf static void
strpqprint(char * p,char * q,FILE * fp)268*753d2d2eSraf strpqprint(char *p, char *q, FILE *fp)
269*753d2d2eSraf {
270*753d2d2eSraf 	char	saved;
271*753d2d2eSraf 
272*753d2d2eSraf 	errlog(BEGIN, "strpqprint() {");
273*753d2d2eSraf 	saved = *q;
274*753d2d2eSraf 	*q = NULL;
275*753d2d2eSraf 	(void) fputs(p, fp);
276*753d2d2eSraf 	*q = saved;
277*753d2d2eSraf 	errlog(END, "}");
278*753d2d2eSraf }
279