xref: /illumos-gate/usr/src/cmd/abi/spectrans/spec2trace/bindings.c (revision 07c94cbf80ccbba93ea61425c2074f6bfd608a19)
1753d2d2eSraf /*
2753d2d2eSraf  * CDDL HEADER START
3753d2d2eSraf  *
4753d2d2eSraf  * The contents of this file are subject to the terms of the
5753d2d2eSraf  * Common Development and Distribution License, Version 1.0 only
6753d2d2eSraf  * (the "License").  You may not use this file except in compliance
7753d2d2eSraf  * with the License.
8753d2d2eSraf  *
9753d2d2eSraf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10753d2d2eSraf  * or http://www.opensolaris.org/os/licensing.
11753d2d2eSraf  * See the License for the specific language governing permissions
12753d2d2eSraf  * and limitations under the License.
13753d2d2eSraf  *
14753d2d2eSraf  * When distributing Covered Code, include this CDDL HEADER in each
15753d2d2eSraf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16753d2d2eSraf  * If applicable, add the following below this CDDL HEADER, with the
17753d2d2eSraf  * fields enclosed by brackets "[]" replaced with your own identifying
18753d2d2eSraf  * information: Portions Copyright [yyyy] [name of copyright owner]
19753d2d2eSraf  *
20753d2d2eSraf  * CDDL HEADER END
21753d2d2eSraf  */
22753d2d2eSraf /*
23753d2d2eSraf  * Copyright (c) 1997-1999 by Sun Microsystems, Inc.
24753d2d2eSraf  * All rights reserved.
25753d2d2eSraf  */
26753d2d2eSraf 
27753d2d2eSraf #include <stdio.h>
28753d2d2eSraf #include <string.h>
29753d2d2eSraf #include "parser.h"
30753d2d2eSraf #include "trace.h"
31753d2d2eSraf #include "util.h"
32753d2d2eSraf #include "symtab.h"
33753d2d2eSraf #include "io.h"
34753d2d2eSraf #include "bindings.h"
35753d2d2eSraf #include "errlog.h"
36753d2d2eSraf 
37753d2d2eSraf 
38753d2d2eSraf /* File globals. */
39753d2d2eSraf static void generate_a_binding(char *, char *);
40753d2d2eSraf 
41753d2d2eSraf static int strpqcmp(char *, char *, char *);
42753d2d2eSraf static void strpqprint(char *, char *, FILE *);
43753d2d2eSraf 
44753d2d2eSraf /*
45753d2d2eSraf  * Bindings: do three-valued logic, where a binding can be
46753d2d2eSraf  *	an expression to evaluate for truthfulness,
47753d2d2eSraf  *	true,
48753d2d2eSraf  *	false, or
49753d2d2eSraf  *	empty.
50753d2d2eSraf  *
51753d2d2eSraf  *	Exception	Result	Evaluate?	Notes
52753d2d2eSraf  *	---------	------	---------	-----
53753d2d2eSraf  *
54753d2d2eSraf  *	true		ok	yes		warn[1]
55753d2d2eSraf  *	false		ok	no
56753d2d2eSraf  *	empty		ok	no		treat as true
57753d2d2eSraf  *	expr		ok	yes		s = !e
58753d2d2eSraf  *
59753d2d2eSraf  * Notes:
60753d2d2eSraf  *	[1] Always exceptional, shows errno at run-time
61753d2d2eSraf  *
62753d2d2eSraf  */
63753d2d2eSraf 
64753d2d2eSraf /*
65753d2d2eSraf  * need_bindings -- see if we have to do anything at all. Implements
66753d2d2eSraf  *	the following rows from the table above (die and evaluate=no lines)
67753d2d2eSraf  *	Returns NO if we don't have to evaluate bindings at all.
68753d2d2eSraf  *
69753d2d2eSraf  *	Exception	Result	Evaluate?	Notes
70753d2d2eSraf  *	---------	------	---------	-----
71753d2d2eSraf  *	false		ok	no
72753d2d2eSraf  *	empty		ok	no		treat as true
73753d2d2eSraf  */
74753d2d2eSraf int
need_bindings(char * exception)75753d2d2eSraf need_bindings(char *exception)
76753d2d2eSraf {
77753d2d2eSraf 
78753d2d2eSraf 	errlog(BEGIN, "need_bindings() {");
79753d2d2eSraf 
80753d2d2eSraf 	if (exception == NULL)
81753d2d2eSraf 		exception = "";
82753d2d2eSraf 
83753d2d2eSraf 	/*	empty		false		ok	no */
84753d2d2eSraf 	/*	empty		empty		ok	no, treat as true */
85753d2d2eSraf 	if (strcmp(exception, "false") == 0 ||
86753d2d2eSraf 	    *exception == '\0') {
87753d2d2eSraf 		errlog(END, "}");
88753d2d2eSraf 		return (NO);
89753d2d2eSraf 	}
90753d2d2eSraf 	errlog(END, "}");
91753d2d2eSraf 	return (YES);
92753d2d2eSraf }
93753d2d2eSraf 
94753d2d2eSraf 
95753d2d2eSraf int
need_exception_binding(void)96753d2d2eSraf need_exception_binding(void)
97753d2d2eSraf {
98753d2d2eSraf 	ENTRY	*e;
99753d2d2eSraf 	char *exception;
100753d2d2eSraf 
101753d2d2eSraf 	exception = ((e = symtab_get_exception()) != NULL)?
102753d2d2eSraf 	    (name_of(e)? name_of(e): ""): "";
103753d2d2eSraf 
104753d2d2eSraf 	return (need_bindings(exception));
105753d2d2eSraf 
106753d2d2eSraf }
107753d2d2eSraf 
108753d2d2eSraf /*
109753d2d2eSraf  * generate_bindings -- make the code for exception bindings
110753d2d2eSraf  *
111753d2d2eSraf  *	Exception	Result	Evaluate?	Notes
112753d2d2eSraf  *	---------	------	---------	-----
113753d2d2eSraf  *	true		ok	yes		warn[2]
114753d2d2eSraf  *	expr		ok	yes		s::= !e
115753d2d2eSraf  *
116753d2d2eSraf  *	Returns NO if we need both bindings, YES (ANTONYM) if we
117753d2d2eSraf  *	only need to evaluate success.
118753d2d2eSraf  */
119753d2d2eSraf int
generate_bindings(char * exception)120753d2d2eSraf generate_bindings(char *exception)
121753d2d2eSraf {
122753d2d2eSraf 	int ret = NO;
123753d2d2eSraf 
124753d2d2eSraf 	errlog(BEGIN, "generate_bindings() {");
125753d2d2eSraf 	errlog(TRACING,  "exception=%s\n", exception ? exception : "NULL");
126753d2d2eSraf 
127753d2d2eSraf 	/* Exception	Result	Evaluate?	Notes	*/
128753d2d2eSraf 	/* ---------	------	---------	-----	*/
129753d2d2eSraf 	/* true		ok	yes		warn[2] */
130753d2d2eSraf 	if (exception != NULL) {
131753d2d2eSraf 		generate_a_binding("exception", exception);
132753d2d2eSraf 		errlog(END, "}");
133753d2d2eSraf 	}
134753d2d2eSraf 
135753d2d2eSraf 	return (ret);
136753d2d2eSraf }
137753d2d2eSraf 
138753d2d2eSraf /*
139753d2d2eSraf  * bindings_exist -- make sure we don't use one if they're not there.
140753d2d2eSraf  */
141753d2d2eSraf int
bindings_exist(void)142753d2d2eSraf bindings_exist(void)
143753d2d2eSraf {
144753d2d2eSraf 	int ret;
145753d2d2eSraf 
146753d2d2eSraf 	errlog(BEGIN, "bindings_exist() {");
147753d2d2eSraf 	errlog(END, "}");
148753d2d2eSraf 
149753d2d2eSraf 	ret = validity_of(symtab_get_exception()) == YES;
150753d2d2eSraf 
151753d2d2eSraf 	return (ret);
152753d2d2eSraf }
153753d2d2eSraf 
154753d2d2eSraf 
155753d2d2eSraf 
156753d2d2eSraf /*
157753d2d2eSraf  * generate_a_binding -- generate just one, with a set of transformations
158753d2d2eSraf  *	applied. Eg, return->_return, errno->functions_errvar,
159753d2d2eSraf  *	unchanged(x)->x == 0, etc. Oneof and someof TBD.
160753d2d2eSraf  */
161753d2d2eSraf static void
generate_a_binding(char * name,char * value)162753d2d2eSraf generate_a_binding(char *name, char *value)
163753d2d2eSraf {
164753d2d2eSraf 	char *p = value;
165753d2d2eSraf 	ENTRY	*e = symtab_get_errval();
166753d2d2eSraf 	char	*errvar = (e == NULL)? NULL: name_of(e);
167753d2d2eSraf 	char	*q;
168753d2d2eSraf 
169753d2d2eSraf 	errlog(BEGIN, "generate_a_binding() {");
170*07c94cbfSToomas Soome 	if (*value == '\0') {
171753d2d2eSraf 		errlog(FATAL, "programmer error: asked to generate an "
172753d2d2eSraf 			"empty binding");
173753d2d2eSraf 	}
174753d2d2eSraf 
175753d2d2eSraf 	{
176753d2d2eSraf 		/*
177753d2d2eSraf 		 * XXX - friggin spaghetti
178753d2d2eSraf 		 */
179753d2d2eSraf 		ENTRY	*exc = symtab_get_exception();
180753d2d2eSraf 
181753d2d2eSraf 		if (exc != NULL)
182753d2d2eSraf 			(void) fprintf(Bodyfp,
183753d2d2eSraf 			    "#line %d \"%s\"\n",
184753d2d2eSraf 			    line_of(exc), symtab_get_filename());
185753d2d2eSraf 	}
186753d2d2eSraf 
187753d2d2eSraf 	/* Generate prefix. */
188753d2d2eSraf 	(void) fprintf(Bodyfp, "    %s = (", name);
189753d2d2eSraf 
190753d2d2eSraf 	/* Walk across line, emitting tokens and transformed tokens */
191753d2d2eSraf 
192*07c94cbfSToomas Soome 	for (; *p != '\0'; p = q) {
193753d2d2eSraf 		p = skipb(p);
194753d2d2eSraf 		q = nextsep(p);
195753d2d2eSraf 
196753d2d2eSraf 		if (p == q) {
197753d2d2eSraf 			/* We're at the end, a "(", ")" or an operator. */
198753d2d2eSraf 			if (*p == '(') {
199753d2d2eSraf 				/* We're at a parenthesized expression */
200753d2d2eSraf 				q++;
201753d2d2eSraf 			} else if (*p == ')') {
202753d2d2eSraf 				/* And the end of an expression. */
203753d2d2eSraf 				q++;
204753d2d2eSraf 			} else if (*p == '!' && *(p+1) != '=') {
205753d2d2eSraf 				/* Or a negated expression */
206753d2d2eSraf 				q++;
207753d2d2eSraf 			} else if ((q = nextb(p)) == p) {
208753d2d2eSraf 				/* Real end! */
209753d2d2eSraf 				break;
210753d2d2eSraf 			}
211753d2d2eSraf 
212753d2d2eSraf 			/* Else it was an operator, boogy onwards. */
213753d2d2eSraf 		}
214753d2d2eSraf 		if (strpqcmp("$return", p, q) == 0) {
215753d2d2eSraf 			(void) fputs("_return", Bodyfp);
216753d2d2eSraf 		} else if (errvar != NULL && strpqcmp(errvar, p, q) == 0) {
217753d2d2eSraf 			(void) fputs("functions_errvar", Bodyfp);
218753d2d2eSraf 		} else if (strpqcmp("unchanged", p, q) == 0) {
219753d2d2eSraf 			/* This will look odd. */
220753d2d2eSraf 			(void) fputs("0 == ", Bodyfp);
221753d2d2eSraf 		} else if (strpqcmp("oneof", p, q) == 0) {
222753d2d2eSraf 			errlog(WARNING,  "Oneof unimplemented in spec2trace"
223753d2d2eSraf 				"It will be treated as the token 'false'");
224753d2d2eSraf 			(void) fputs("false", Bodyfp);
225753d2d2eSraf 			break;
226753d2d2eSraf 		} else if (strpqcmp("someof", p, q) == 0) {
227753d2d2eSraf 			errlog(WARNING, "Someof unimplemented in spec2trace, "
228753d2d2eSraf 				"It will be treated as the token 'false'");
229753d2d2eSraf 			(void) fputs("false", Bodyfp);
230753d2d2eSraf 			break;
231753d2d2eSraf 		} else if (strpqcmp("errno", p, q) == 0) {
232753d2d2eSraf 			(void) fputs("ABI_ERRNO", Bodyfp);
233753d2d2eSraf 		} else {
234753d2d2eSraf 			/* Just copy it. */
235753d2d2eSraf 
236753d2d2eSraf 			strpqprint(p, q, Bodyfp);
237753d2d2eSraf 		}
238753d2d2eSraf 		(void) putc(' ', Bodyfp);
239753d2d2eSraf 	}
240753d2d2eSraf 	(void) (void) fputs(");\n", Bodyfp);
241753d2d2eSraf 	errlog(END, "}");
242753d2d2eSraf }
243753d2d2eSraf 
244753d2d2eSraf /*
245753d2d2eSraf  * strpqcmp -- compare a null-terminated string with a pq-bracketed string.
246753d2d2eSraf  */
247753d2d2eSraf static int
strpqcmp(char * v1,char * p,char * q)248753d2d2eSraf strpqcmp(char *v1, char *p, char *q)
249753d2d2eSraf {
250753d2d2eSraf 	int	rc;
251753d2d2eSraf 	char	saved;
252753d2d2eSraf 
253753d2d2eSraf 	errlog(BEGIN, "strpqcmp() {");
254753d2d2eSraf 	saved = *q;
255*07c94cbfSToomas Soome 	*q = '\0';
256753d2d2eSraf 	rc = (strcmp(v1, p));
257753d2d2eSraf 	*q = saved;
258753d2d2eSraf 	errlog(END, "}");
259753d2d2eSraf 	return (rc);
260753d2d2eSraf }
261753d2d2eSraf 
262753d2d2eSraf /*
263753d2d2eSraf  * strpqprint -- print a pq-bracketed string
264753d2d2eSraf  */
265753d2d2eSraf static void
strpqprint(char * p,char * q,FILE * fp)266753d2d2eSraf strpqprint(char *p, char *q, FILE *fp)
267753d2d2eSraf {
268753d2d2eSraf 	char	saved;
269753d2d2eSraf 
270753d2d2eSraf 	errlog(BEGIN, "strpqprint() {");
271753d2d2eSraf 	saved = *q;
272*07c94cbfSToomas Soome 	*q = '\0';
273753d2d2eSraf 	(void) fputs(p, fp);
274753d2d2eSraf 	*q = saved;
275753d2d2eSraf 	errlog(END, "}");
276753d2d2eSraf }
277