xref: /titanic_51/usr/src/lib/libpp/common/ppmisc.c (revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968)
1*da2e3ebdSchin /***********************************************************************
2*da2e3ebdSchin *                                                                      *
3*da2e3ebdSchin *               This software is part of the ast package               *
4*da2e3ebdSchin *           Copyright (c) 1986-2007 AT&T Knowledge Ventures            *
5*da2e3ebdSchin *                      and is licensed under the                       *
6*da2e3ebdSchin *                  Common Public License, Version 1.0                  *
7*da2e3ebdSchin *                      by AT&T Knowledge Ventures                      *
8*da2e3ebdSchin *                                                                      *
9*da2e3ebdSchin *                A copy of the License is available at                 *
10*da2e3ebdSchin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*da2e3ebdSchin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*da2e3ebdSchin *                                                                      *
13*da2e3ebdSchin *              Information and Software Systems Research               *
14*da2e3ebdSchin *                            AT&T Research                             *
15*da2e3ebdSchin *                           Florham Park NJ                            *
16*da2e3ebdSchin *                                                                      *
17*da2e3ebdSchin *                 Glenn Fowler <gsf@research.att.com>                  *
18*da2e3ebdSchin *                                                                      *
19*da2e3ebdSchin ***********************************************************************/
20*da2e3ebdSchin #pragma prototyped
21*da2e3ebdSchin /*
22*da2e3ebdSchin  * Glenn Fowler
23*da2e3ebdSchin  * AT&T Research
24*da2e3ebdSchin  *
25*da2e3ebdSchin  * miscellaneous preprocessor support
26*da2e3ebdSchin  */
27*da2e3ebdSchin 
28*da2e3ebdSchin #include "pplib.h"
29*da2e3ebdSchin 
30*da2e3ebdSchin /*
31*da2e3ebdSchin  * macro symbol def|ref
32*da2e3ebdSchin  */
33*da2e3ebdSchin 
34*da2e3ebdSchin struct ppsymbol*
35*da2e3ebdSchin pprefmac(char* name, int ref)
36*da2e3ebdSchin {
37*da2e3ebdSchin 	register struct ppsymbol*	sym;
38*da2e3ebdSchin 
39*da2e3ebdSchin 	if (!(sym = ppsymget(pp.symtab, name)) && (ref <= REF_NORMAL && pp.macref || ref == REF_CREATE || ref == REF_DELETE && (pp.mode & (INIT|READONLY))))
40*da2e3ebdSchin 	{
41*da2e3ebdSchin 		if ((pp.state & COMPILE) && pp.truncate && strlen(name) > pp.truncate)
42*da2e3ebdSchin 			name[pp.truncate] = 0;
43*da2e3ebdSchin 		sym = ppsymset(pp.symtab, NiL);
44*da2e3ebdSchin 	}
45*da2e3ebdSchin 	if (sym && ref <= REF_NORMAL)
46*da2e3ebdSchin 	{
47*da2e3ebdSchin 		if (pp.macref) (*pp.macref)(sym, error_info.file, error_info.line, ref == REF_NORMAL && (pp.state & CONDITIONAL) ? REF_IF : ref, 0L);
48*da2e3ebdSchin 		if (!sym->macro) sym = 0;
49*da2e3ebdSchin 	}
50*da2e3ebdSchin #if COMPATIBLE
51*da2e3ebdSchin 	if (!(pp.state & COMPATIBILITY))
52*da2e3ebdSchin #endif
53*da2e3ebdSchin 	if (ref == REF_IF && sym && (sym->flags & SYM_PREDEFINED) && *name != '_' && !(pp.mode & (HOSTED|INACTIVE)))
54*da2e3ebdSchin 	{
55*da2e3ebdSchin 		if (pp.state & STRICT)
56*da2e3ebdSchin 		{
57*da2e3ebdSchin 			error(1, "%s: obsolete predefined symbol reference disabled", name);
58*da2e3ebdSchin 			return(0);
59*da2e3ebdSchin 		}
60*da2e3ebdSchin 		error(1, "%s: obsolete predefined symbol referenced", name);
61*da2e3ebdSchin 	}
62*da2e3ebdSchin 	return(sym);
63*da2e3ebdSchin }
64*da2e3ebdSchin 
65*da2e3ebdSchin /*
66*da2e3ebdSchin  * common predicate assertion operations
67*da2e3ebdSchin  * op is DEFINE or UNDEF
68*da2e3ebdSchin  */
69*da2e3ebdSchin 
70*da2e3ebdSchin void
71*da2e3ebdSchin ppassert(int op, char* pred, char* args)
72*da2e3ebdSchin {
73*da2e3ebdSchin 	register struct pplist*		a;
74*da2e3ebdSchin 	register struct ppsymbol*	sym;
75*da2e3ebdSchin 	register struct pplist*		p;
76*da2e3ebdSchin 	register struct pplist*		q;
77*da2e3ebdSchin 
78*da2e3ebdSchin 	if (!args) switch (op)
79*da2e3ebdSchin 	{
80*da2e3ebdSchin 	case DEFINE:
81*da2e3ebdSchin 		goto mark;
82*da2e3ebdSchin 	case UNDEF:
83*da2e3ebdSchin 		a = 0;
84*da2e3ebdSchin 		goto unmark;
85*da2e3ebdSchin 	}
86*da2e3ebdSchin 	if (a = (struct pplist*)hashget(pp.prdtab, pred))
87*da2e3ebdSchin 	{
88*da2e3ebdSchin 		p = 0;
89*da2e3ebdSchin 		q = a;
90*da2e3ebdSchin 		while (q)
91*da2e3ebdSchin 		{
92*da2e3ebdSchin 			if (streq(q->value, args))
93*da2e3ebdSchin 			{
94*da2e3ebdSchin 				if (op == DEFINE) return;
95*da2e3ebdSchin 				q = q->next;
96*da2e3ebdSchin 				if (p) p->next = q;
97*da2e3ebdSchin 				else a = q;
98*da2e3ebdSchin 			}
99*da2e3ebdSchin 			else
100*da2e3ebdSchin 			{
101*da2e3ebdSchin 				p = q;
102*da2e3ebdSchin 				q = q->next;
103*da2e3ebdSchin 			}
104*da2e3ebdSchin 		}
105*da2e3ebdSchin 		if (op == UNDEF)
106*da2e3ebdSchin 		{
107*da2e3ebdSchin 		unmark:
108*da2e3ebdSchin 			hashput(pp.prdtab, pred, a);
109*da2e3ebdSchin 			if (sym = ppsymref(pp.symtab, pred))
110*da2e3ebdSchin 				sym->flags &= ~SYM_PREDICATE;
111*da2e3ebdSchin 			return;
112*da2e3ebdSchin 		}
113*da2e3ebdSchin 	}
114*da2e3ebdSchin 	if (op == DEFINE)
115*da2e3ebdSchin 	{
116*da2e3ebdSchin 		p = newof(0, struct pplist, 1, 0);
117*da2e3ebdSchin 		p->next = a;
118*da2e3ebdSchin 		p->value = strdup(args);
119*da2e3ebdSchin 		hashput(pp.prdtab, NiL, p);
120*da2e3ebdSchin 	mark:
121*da2e3ebdSchin 		if ((pp.state & COMPILE) && pp.truncate) return;
122*da2e3ebdSchin 		if (sym = ppsymset(pp.symtab, pred))
123*da2e3ebdSchin 			sym->flags |= SYM_PREDICATE;
124*da2e3ebdSchin 	}
125*da2e3ebdSchin }
126*da2e3ebdSchin 
127*da2e3ebdSchin /*
128*da2e3ebdSchin  * parse a predicate argument list
129*da2e3ebdSchin  * the args are placed in pp.args
130*da2e3ebdSchin  * the first non-space/paren argument token type is returned
131*da2e3ebdSchin  * forms:
132*da2e3ebdSchin  *
133*da2e3ebdSchin  *	predicate <identifier>			type=T_ID
134*da2e3ebdSchin  *	predicate ( <identifier> )		type=T_ID
135*da2e3ebdSchin  *	predicate ( )				type=0
136*da2e3ebdSchin  *	predicate ( <balanced-paren-list> )	type=T_STRING
137*da2e3ebdSchin  *	otherwise				type=<other>
138*da2e3ebdSchin  */
139*da2e3ebdSchin 
140*da2e3ebdSchin int
141*da2e3ebdSchin pppredargs(void)
142*da2e3ebdSchin {
143*da2e3ebdSchin 	register int	c;
144*da2e3ebdSchin 	register int	n;
145*da2e3ebdSchin 	register int	type;
146*da2e3ebdSchin 	char*		pptoken;
147*da2e3ebdSchin 
148*da2e3ebdSchin 	pptoken = pp.token;
149*da2e3ebdSchin 	pp.token = pp.args;
150*da2e3ebdSchin 	switch (type = pplex())
151*da2e3ebdSchin 	{
152*da2e3ebdSchin 	case '(':
153*da2e3ebdSchin 		type = 0;
154*da2e3ebdSchin 		n = 1;
155*da2e3ebdSchin 		pp.state |= HEADER;
156*da2e3ebdSchin 		pp.state &= ~STRIP;
157*da2e3ebdSchin 		c = pplex();
158*da2e3ebdSchin 		pp.state &= ~NOSPACE;
159*da2e3ebdSchin 		for (;;)
160*da2e3ebdSchin 		{
161*da2e3ebdSchin 			switch (c)
162*da2e3ebdSchin 			{
163*da2e3ebdSchin 			case '(':
164*da2e3ebdSchin 				n++;
165*da2e3ebdSchin 				break;
166*da2e3ebdSchin 			case '\n':
167*da2e3ebdSchin 				ungetchr(c);
168*da2e3ebdSchin 				error(2, "missing %d )%s in predicate argument list", n, n == 1 ? "" : "'s");
169*da2e3ebdSchin 				type = 0;
170*da2e3ebdSchin 				goto done;
171*da2e3ebdSchin 			case ')':
172*da2e3ebdSchin 				if (!--n) goto done;
173*da2e3ebdSchin 				break;
174*da2e3ebdSchin 			}
175*da2e3ebdSchin 			pp.token = pp.toknxt;
176*da2e3ebdSchin 			if (c != ' ')
177*da2e3ebdSchin 			{
178*da2e3ebdSchin 				if (type) type = T_STRING;
179*da2e3ebdSchin 				else type = (c == T_ID) ? T_ID : T_STRING;
180*da2e3ebdSchin 			}
181*da2e3ebdSchin 			c = pplex();
182*da2e3ebdSchin 		}
183*da2e3ebdSchin 	done:
184*da2e3ebdSchin 		pp.state &= ~HEADER;
185*da2e3ebdSchin 		pp.state |= NOSPACE|STRIP;
186*da2e3ebdSchin 		if (pp.token > pp.args && *(pp.token - 1) == ' ') pp.token--;
187*da2e3ebdSchin 		*pp.token = 0;
188*da2e3ebdSchin 		break;
189*da2e3ebdSchin 	case '\n':
190*da2e3ebdSchin 		ungetchr('\n');
191*da2e3ebdSchin 		type = 0;
192*da2e3ebdSchin 		break;
193*da2e3ebdSchin 	}
194*da2e3ebdSchin 	pp.token = pptoken;
195*da2e3ebdSchin 	return(type);
196*da2e3ebdSchin }
197*da2e3ebdSchin 
198*da2e3ebdSchin /*
199*da2e3ebdSchin  * sync output line number
200*da2e3ebdSchin  */
201*da2e3ebdSchin 
202*da2e3ebdSchin int
203*da2e3ebdSchin ppsync(void)
204*da2e3ebdSchin {
205*da2e3ebdSchin 	long	m;
206*da2e3ebdSchin 
207*da2e3ebdSchin 	if ((pp.state & (ADD|HIDDEN)))
208*da2e3ebdSchin 	{
209*da2e3ebdSchin 		if (pp.state & ADD)
210*da2e3ebdSchin 		{
211*da2e3ebdSchin 			pp.state &= ~ADD;
212*da2e3ebdSchin 			m = pp.addp - pp.addbuf;
213*da2e3ebdSchin 			pp.addp = pp.addbuf;
214*da2e3ebdSchin 			ppprintf("%-.*s", m, pp.addbuf);
215*da2e3ebdSchin 		}
216*da2e3ebdSchin 		if (pp.linesync)
217*da2e3ebdSchin 		{
218*da2e3ebdSchin 			if ((pp.state & SYNCLINE) || pp.hidden >= MAXHIDDEN)
219*da2e3ebdSchin 			{
220*da2e3ebdSchin 				pp.hidden = 0;
221*da2e3ebdSchin 				pp.state &= ~(HIDDEN|SYNCLINE);
222*da2e3ebdSchin 				if (error_info.line)
223*da2e3ebdSchin 					(*pp.linesync)(error_info.line, error_info.file);
224*da2e3ebdSchin 			}
225*da2e3ebdSchin 			else
226*da2e3ebdSchin 			{
227*da2e3ebdSchin 				m = pp.hidden;
228*da2e3ebdSchin 				pp.hidden = 0;
229*da2e3ebdSchin 				pp.state &= ~HIDDEN;
230*da2e3ebdSchin 				while (m-- > 0)
231*da2e3ebdSchin 					ppputchar('\n');
232*da2e3ebdSchin 			}
233*da2e3ebdSchin 		}
234*da2e3ebdSchin 		else
235*da2e3ebdSchin 		{
236*da2e3ebdSchin 			pp.hidden = 0;
237*da2e3ebdSchin 			pp.state &= ~HIDDEN;
238*da2e3ebdSchin 			ppputchar('\n');
239*da2e3ebdSchin 		}
240*da2e3ebdSchin 	}
241*da2e3ebdSchin 	return 0;
242*da2e3ebdSchin }
243