xref: /titanic_52/usr/src/contrib/ast/src/lib/libpp/ppbuiltin.c (revision 906afcb89d0412cc073b95c2d701a804a8cdb62c)
1*906afcb8SAndy Fiddaman /***********************************************************************
2*906afcb8SAndy Fiddaman *                                                                      *
3*906afcb8SAndy Fiddaman *               This software is part of the ast package               *
4*906afcb8SAndy Fiddaman *          Copyright (c) 1986-2011 AT&T Intellectual Property          *
5*906afcb8SAndy Fiddaman *                      and is licensed under the                       *
6*906afcb8SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*906afcb8SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*906afcb8SAndy Fiddaman *                                                                      *
9*906afcb8SAndy Fiddaman *                A copy of the License is available at                 *
10*906afcb8SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*906afcb8SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*906afcb8SAndy Fiddaman *                                                                      *
13*906afcb8SAndy Fiddaman *              Information and Software Systems Research               *
14*906afcb8SAndy Fiddaman *                            AT&T Research                             *
15*906afcb8SAndy Fiddaman *                           Florham Park NJ                            *
16*906afcb8SAndy Fiddaman *                                                                      *
17*906afcb8SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*906afcb8SAndy Fiddaman *                                                                      *
19*906afcb8SAndy Fiddaman ***********************************************************************/
20*906afcb8SAndy Fiddaman #pragma prototyped
21*906afcb8SAndy Fiddaman /*
22*906afcb8SAndy Fiddaman  * Glenn Fowler
23*906afcb8SAndy Fiddaman  * AT&T Research
24*906afcb8SAndy Fiddaman  *
25*906afcb8SAndy Fiddaman  * preprocessor builtin macro support
26*906afcb8SAndy Fiddaman  */
27*906afcb8SAndy Fiddaman 
28*906afcb8SAndy Fiddaman #include "pplib.h"
29*906afcb8SAndy Fiddaman 
30*906afcb8SAndy Fiddaman #include <times.h>
31*906afcb8SAndy Fiddaman 
32*906afcb8SAndy Fiddaman /*
33*906afcb8SAndy Fiddaman  * process a #(...) builtin macro call
34*906afcb8SAndy Fiddaman  * `#(' has already been seen
35*906afcb8SAndy Fiddaman  */
36*906afcb8SAndy Fiddaman 
37*906afcb8SAndy Fiddaman void
38*906afcb8SAndy Fiddaman ppbuiltin(void)
39*906afcb8SAndy Fiddaman {
40*906afcb8SAndy Fiddaman 	register int		c;
41*906afcb8SAndy Fiddaman 	register char*		p;
42*906afcb8SAndy Fiddaman 	register char*		a;
43*906afcb8SAndy Fiddaman 
44*906afcb8SAndy Fiddaman 	int			n;
45*906afcb8SAndy Fiddaman 	int			op;
46*906afcb8SAndy Fiddaman 	char*			token;
47*906afcb8SAndy Fiddaman 	char*			t;
48*906afcb8SAndy Fiddaman 	long			number;
49*906afcb8SAndy Fiddaman 	long			onumber;
50*906afcb8SAndy Fiddaman 	struct ppinstk*		in;
51*906afcb8SAndy Fiddaman 	struct pplist*		list;
52*906afcb8SAndy Fiddaman 	struct ppsymbol*	sym;
53*906afcb8SAndy Fiddaman 	Sfio_t*			sp;
54*906afcb8SAndy Fiddaman 
55*906afcb8SAndy Fiddaman 	number = pp.state;
56*906afcb8SAndy Fiddaman 	pp.state |= DISABLE|FILEPOP|NOSPACE;
57*906afcb8SAndy Fiddaman 	token = pp.token;
58*906afcb8SAndy Fiddaman 	p = pp.token = pp.tmpbuf;
59*906afcb8SAndy Fiddaman 	*(a = pp.args) = 0;
60*906afcb8SAndy Fiddaman 	if ((c = pplex()) != T_ID)
61*906afcb8SAndy Fiddaman 	{
62*906afcb8SAndy Fiddaman 		error(2, "%s: #(<identifier>...) expected", p);
63*906afcb8SAndy Fiddaman 		*p = 0;
64*906afcb8SAndy Fiddaman 	}
65*906afcb8SAndy Fiddaman 	switch (op = (int)hashget(pp.strtab, p))
66*906afcb8SAndy Fiddaman 	{
67*906afcb8SAndy Fiddaman 	case V_DEFAULT:
68*906afcb8SAndy Fiddaman 		n = 0;
69*906afcb8SAndy Fiddaman 		p = pp.token = pp.valbuf;
70*906afcb8SAndy Fiddaman 		if ((c = pplex()) == ',')
71*906afcb8SAndy Fiddaman 		{
72*906afcb8SAndy Fiddaman 			op = -1;
73*906afcb8SAndy Fiddaman 			c = pplex();
74*906afcb8SAndy Fiddaman 		}
75*906afcb8SAndy Fiddaman 		pp.state &= ~NOSPACE;
76*906afcb8SAndy Fiddaman 		for (;;)
77*906afcb8SAndy Fiddaman 		{
78*906afcb8SAndy Fiddaman 			if (!c)
79*906afcb8SAndy Fiddaman 			{
80*906afcb8SAndy Fiddaman 				error(2, "%s in #(...) argument", pptokchr(c));
81*906afcb8SAndy Fiddaman 				break;
82*906afcb8SAndy Fiddaman 			}
83*906afcb8SAndy Fiddaman 			if (c == '(') n++;
84*906afcb8SAndy Fiddaman 			else if (c == ')' && !n--) break;
85*906afcb8SAndy Fiddaman 			else if (c == ',' && !n && op > 0) op = 0;
86*906afcb8SAndy Fiddaman 			if (op) pp.token = pp.toknxt;
87*906afcb8SAndy Fiddaman 			c = pplex();
88*906afcb8SAndy Fiddaman 		}
89*906afcb8SAndy Fiddaman 		*pp.token = 0;
90*906afcb8SAndy Fiddaman 		pp.token = token;
91*906afcb8SAndy Fiddaman 		pp.state = number;
92*906afcb8SAndy Fiddaman 		break;
93*906afcb8SAndy Fiddaman 	case V_EMPTY:
94*906afcb8SAndy Fiddaman 		p = pp.valbuf;
95*906afcb8SAndy Fiddaman 		if ((c = pplex()) == ')') *p = '1';
96*906afcb8SAndy Fiddaman 		else
97*906afcb8SAndy Fiddaman 		{
98*906afcb8SAndy Fiddaman 			*p = '0';
99*906afcb8SAndy Fiddaman 			n = 0;
100*906afcb8SAndy Fiddaman 			for (;;)
101*906afcb8SAndy Fiddaman 			{
102*906afcb8SAndy Fiddaman 				if (!c)
103*906afcb8SAndy Fiddaman 				{
104*906afcb8SAndy Fiddaman 					error(2, "%s in #(...) argument", pptokchr(c));
105*906afcb8SAndy Fiddaman 					break;
106*906afcb8SAndy Fiddaman 				}
107*906afcb8SAndy Fiddaman 				if (c == '(') n++;
108*906afcb8SAndy Fiddaman 				else if (c == ')' && !n--) break;
109*906afcb8SAndy Fiddaman 				c = pplex();
110*906afcb8SAndy Fiddaman 			}
111*906afcb8SAndy Fiddaman 		}
112*906afcb8SAndy Fiddaman 		*(p + 1) = 0;
113*906afcb8SAndy Fiddaman 		pp.token = token;
114*906afcb8SAndy Fiddaman 		pp.state = number;
115*906afcb8SAndy Fiddaman 		break;
116*906afcb8SAndy Fiddaman 	case V_ITERATE:
117*906afcb8SAndy Fiddaman 		n = 0;
118*906afcb8SAndy Fiddaman 		pp.token = pp.valbuf;
119*906afcb8SAndy Fiddaman 		if ((c = pplex()) != T_ID || !(sym = ppsymref(pp.symtab, pp.token)) || !sym->macro || sym->macro->arity != 1 || (c = pplex()) != ',')
120*906afcb8SAndy Fiddaman 		{
121*906afcb8SAndy Fiddaman 			error(2, "#(%s <macro(x)>, ...) expected", p);
122*906afcb8SAndy Fiddaman 			for (;;)
123*906afcb8SAndy Fiddaman 			{
124*906afcb8SAndy Fiddaman 				if (!c)
125*906afcb8SAndy Fiddaman 				{
126*906afcb8SAndy Fiddaman 					error(2, "%s in #(...) argument", pptokchr(c));
127*906afcb8SAndy Fiddaman 					break;
128*906afcb8SAndy Fiddaman 				}
129*906afcb8SAndy Fiddaman 				if (c == '(') n++;
130*906afcb8SAndy Fiddaman 				else if (c == ')' && !n--) break;
131*906afcb8SAndy Fiddaman 				c = pplex();
132*906afcb8SAndy Fiddaman 			}
133*906afcb8SAndy Fiddaman 			*pp.valbuf = 0;
134*906afcb8SAndy Fiddaman 		}
135*906afcb8SAndy Fiddaman 		else while (c != ')')
136*906afcb8SAndy Fiddaman 		{
137*906afcb8SAndy Fiddaman 			p = pp.token;
138*906afcb8SAndy Fiddaman 			if (pp.token > pp.valbuf) *pp.token++ = ' ';
139*906afcb8SAndy Fiddaman 			STRCOPY(pp.token, sym->name, a);
140*906afcb8SAndy Fiddaman 			*pp.token++ = '(';
141*906afcb8SAndy Fiddaman 			if (!c || !(c = pplex()))
142*906afcb8SAndy Fiddaman 			{
143*906afcb8SAndy Fiddaman 				pp.token = p;
144*906afcb8SAndy Fiddaman 				error(2, "%s in #(...) argument", pptokchr(c));
145*906afcb8SAndy Fiddaman 				break;
146*906afcb8SAndy Fiddaman 			}
147*906afcb8SAndy Fiddaman 			pp.state &= ~NOSPACE;
148*906afcb8SAndy Fiddaman 			while (c)
149*906afcb8SAndy Fiddaman 			{
150*906afcb8SAndy Fiddaman 				if (c == '(') n++;
151*906afcb8SAndy Fiddaman 				else if (c == ')' && !n--) break;
152*906afcb8SAndy Fiddaman 				else if (c == ',' && !n) break;
153*906afcb8SAndy Fiddaman 				pp.token = pp.toknxt;
154*906afcb8SAndy Fiddaman 				c = pplex();
155*906afcb8SAndy Fiddaman 			}
156*906afcb8SAndy Fiddaman 			*pp.token++ = ')';
157*906afcb8SAndy Fiddaman 			pp.state |= NOSPACE;
158*906afcb8SAndy Fiddaman 		}
159*906afcb8SAndy Fiddaman 		p = pp.valbuf;
160*906afcb8SAndy Fiddaman 		pp.token = token;
161*906afcb8SAndy Fiddaman 		pp.state = number;
162*906afcb8SAndy Fiddaman 		break;
163*906afcb8SAndy Fiddaman 	default:
164*906afcb8SAndy Fiddaman 		pp.token = token;
165*906afcb8SAndy Fiddaman 		while (c != ')')
166*906afcb8SAndy Fiddaman 		{
167*906afcb8SAndy Fiddaman 			if (!c)
168*906afcb8SAndy Fiddaman 			{
169*906afcb8SAndy Fiddaman 				error(2, "%s in #(...) argument", pptokchr(c));
170*906afcb8SAndy Fiddaman 				break;
171*906afcb8SAndy Fiddaman 			}
172*906afcb8SAndy Fiddaman 			if ((c = pplex()) == T_ID && !*a)
173*906afcb8SAndy Fiddaman 				strcpy(a, pp.token);
174*906afcb8SAndy Fiddaman 		}
175*906afcb8SAndy Fiddaman 		pp.state = number;
176*906afcb8SAndy Fiddaman 		switch (op)
177*906afcb8SAndy Fiddaman 		{
178*906afcb8SAndy Fiddaman 		case V_ARGC:
179*906afcb8SAndy Fiddaman 			c = -1;
180*906afcb8SAndy Fiddaman 			for (in = pp.in; in; in = in->prev)
181*906afcb8SAndy Fiddaman 				if ((in->type == IN_MACRO || in->type == IN_MULTILINE) && (in->symbol->flags & SYM_FUNCTION))
182*906afcb8SAndy Fiddaman 				{
183*906afcb8SAndy Fiddaman 					c = *((unsigned char*)(pp.macp->arg[0] - 2));
184*906afcb8SAndy Fiddaman 					break;
185*906afcb8SAndy Fiddaman 				}
186*906afcb8SAndy Fiddaman 			sfsprintf(p = pp.valbuf, MAXTOKEN, "%d", c);
187*906afcb8SAndy Fiddaman 			break;
188*906afcb8SAndy Fiddaman 		case V_BASE:
189*906afcb8SAndy Fiddaman 			p = (a = strrchr(error_info.file, '/')) ? a + 1 : error_info.file;
190*906afcb8SAndy Fiddaman 			break;
191*906afcb8SAndy Fiddaman 		case V_DATE:
192*906afcb8SAndy Fiddaman 			if (!(p = pp.date))
193*906afcb8SAndy Fiddaman 			{
194*906afcb8SAndy Fiddaman 				time_t	tm;
195*906afcb8SAndy Fiddaman 
196*906afcb8SAndy Fiddaman 				time(&tm);
197*906afcb8SAndy Fiddaman 				a = p = ctime(&tm) + 4;
198*906afcb8SAndy Fiddaman 				*(p + 20) = 0;
199*906afcb8SAndy Fiddaman 				for (p += 7; *p = *(p + 9); p++);
200*906afcb8SAndy Fiddaman 				pp.date = p = strdup(a);
201*906afcb8SAndy Fiddaman 			}
202*906afcb8SAndy Fiddaman 			break;
203*906afcb8SAndy Fiddaman 		case V_FILE:
204*906afcb8SAndy Fiddaman 			p = error_info.file;
205*906afcb8SAndy Fiddaman 			break;
206*906afcb8SAndy Fiddaman 		case V_LINE:
207*906afcb8SAndy Fiddaman 			sfsprintf(p = pp.valbuf, MAXTOKEN, "%d", error_info.line);
208*906afcb8SAndy Fiddaman 			break;
209*906afcb8SAndy Fiddaman 		case V_PATH:
210*906afcb8SAndy Fiddaman 			p = pp.path;
211*906afcb8SAndy Fiddaman 			break;
212*906afcb8SAndy Fiddaman 		case V_SOURCE:
213*906afcb8SAndy Fiddaman 			p = error_info.file;
214*906afcb8SAndy Fiddaman 			for (in = pp.in; in->prev; in = in->prev)
215*906afcb8SAndy Fiddaman 				if (in->prev->type == IN_FILE && in->file)
216*906afcb8SAndy Fiddaman 					p = in->file;
217*906afcb8SAndy Fiddaman 			break;
218*906afcb8SAndy Fiddaman 		case V_STDC:
219*906afcb8SAndy Fiddaman 			p = pp.valbuf;
220*906afcb8SAndy Fiddaman 			p[0] = ((pp.state & (COMPATIBILITY|TRANSITION)) || (pp.mode & (HOSTED|HOSTEDTRANSITION)) == (HOSTED|HOSTEDTRANSITION)) ? '0' : '1';
221*906afcb8SAndy Fiddaman 			p[1] = 0;
222*906afcb8SAndy Fiddaman 			break;
223*906afcb8SAndy Fiddaman 		case V_TIME:
224*906afcb8SAndy Fiddaman 			if (!(p = pp.time))
225*906afcb8SAndy Fiddaman 			{
226*906afcb8SAndy Fiddaman 				time_t	tm;
227*906afcb8SAndy Fiddaman 
228*906afcb8SAndy Fiddaman 				time(&tm);
229*906afcb8SAndy Fiddaman 				p = ctime(&tm) + 11;
230*906afcb8SAndy Fiddaman 				*(p + 8) = 0;
231*906afcb8SAndy Fiddaman 				pp.time = p = strdup(p);
232*906afcb8SAndy Fiddaman 			}
233*906afcb8SAndy Fiddaman 			break;
234*906afcb8SAndy Fiddaman 		case V_VERSION:
235*906afcb8SAndy Fiddaman 			p = (char*)pp.version;
236*906afcb8SAndy Fiddaman 			break;
237*906afcb8SAndy Fiddaman 		case V_DIRECTIVE:
238*906afcb8SAndy Fiddaman 			pp.state |= NEWLINE;
239*906afcb8SAndy Fiddaman 			pp.mode |= RELAX;
240*906afcb8SAndy Fiddaman 			strcpy(p = pp.valbuf, "#");
241*906afcb8SAndy Fiddaman 			break;
242*906afcb8SAndy Fiddaman 		case V_GETENV:
243*906afcb8SAndy Fiddaman 			if (!(p = getenv(a))) p = "";
244*906afcb8SAndy Fiddaman 			break;
245*906afcb8SAndy Fiddaman 		case V_GETMAC:
246*906afcb8SAndy Fiddaman 			p = (sym = pprefmac(a, REF_NORMAL)) ? sym->macro->value : "";
247*906afcb8SAndy Fiddaman 			break;
248*906afcb8SAndy Fiddaman 		case V_GETOPT:
249*906afcb8SAndy Fiddaman 			sfsprintf(p = pp.valbuf, MAXTOKEN, "%ld", ppoption(a));
250*906afcb8SAndy Fiddaman 			break;
251*906afcb8SAndy Fiddaman 		case V_GETPRD:
252*906afcb8SAndy Fiddaman 			p = (list = (struct pplist*)hashget(pp.prdtab, a)) ? list->value : "";
253*906afcb8SAndy Fiddaman 			break;
254*906afcb8SAndy Fiddaman 		case V__PRAGMA:
255*906afcb8SAndy Fiddaman 			if ((c = pplex()) == '(')
256*906afcb8SAndy Fiddaman 			{
257*906afcb8SAndy Fiddaman 				number = pp.state;
258*906afcb8SAndy Fiddaman 				pp.state |= NOSPACE|STRIP;
259*906afcb8SAndy Fiddaman 				c = pplex();
260*906afcb8SAndy Fiddaman 				pp.state = number;
261*906afcb8SAndy Fiddaman 				if (c == T_STRING || c == T_WSTRING)
262*906afcb8SAndy Fiddaman 				{
263*906afcb8SAndy Fiddaman 					if (!(sp = sfstropen()))
264*906afcb8SAndy Fiddaman 						error(3, "temporary buffer allocation error");
265*906afcb8SAndy Fiddaman 					sfprintf(sp, "#%s %s\n", dirname(PRAGMA), pp.token);
266*906afcb8SAndy Fiddaman 					a = sfstruse(sp);
267*906afcb8SAndy Fiddaman 					if ((c = pplex()) == ')')
268*906afcb8SAndy Fiddaman 					{
269*906afcb8SAndy Fiddaman 						pp.state |= NEWLINE;
270*906afcb8SAndy Fiddaman 						PUSH_BUFFER(p, a, 1);
271*906afcb8SAndy Fiddaman 					}
272*906afcb8SAndy Fiddaman 					sfstrclose(sp);
273*906afcb8SAndy Fiddaman 				}
274*906afcb8SAndy Fiddaman 			}
275*906afcb8SAndy Fiddaman 			if (c != ')')
276*906afcb8SAndy Fiddaman 				error(2, "%s: (\"...\") expected", p);
277*906afcb8SAndy Fiddaman 			return;
278*906afcb8SAndy Fiddaman 		case V_FUNCTION:
279*906afcb8SAndy Fiddaman 
280*906afcb8SAndy Fiddaman #define BACK(a,p)	((a>p)?*--a:(number++?0:((p=pp.outbuf+PPBUFSIZ),(a=pp.outbuf+2*PPBUFSIZ),*--a)))
281*906afcb8SAndy Fiddaman #define PEEK(a,p)	((a>p)?*(a-1):(number?0:*(pp.outbuf+2*PPBUFSIZ-1)))
282*906afcb8SAndy Fiddaman 
283*906afcb8SAndy Fiddaman 			number = pp.outbuf != pp.outb;
284*906afcb8SAndy Fiddaman 			a = pp.outp;
285*906afcb8SAndy Fiddaman 			p = pp.outb;
286*906afcb8SAndy Fiddaman 			op = 0;
287*906afcb8SAndy Fiddaman 			while (c = BACK(a, p))
288*906afcb8SAndy Fiddaman 			{
289*906afcb8SAndy Fiddaman 				if (c == '"' || c == '\'')
290*906afcb8SAndy Fiddaman 				{
291*906afcb8SAndy Fiddaman 					op = 0;
292*906afcb8SAndy Fiddaman 					while ((n = BACK(a, p)) && n != c || PEEK(a, p) == '\\');
293*906afcb8SAndy Fiddaman 				}
294*906afcb8SAndy Fiddaman 				else if (c == '\n')
295*906afcb8SAndy Fiddaman 				{
296*906afcb8SAndy Fiddaman 					token = a;
297*906afcb8SAndy Fiddaman 					while (c = BACK(a, p))
298*906afcb8SAndy Fiddaman 						if (c == '\n')
299*906afcb8SAndy Fiddaman 						{
300*906afcb8SAndy Fiddaman 							a = token;
301*906afcb8SAndy Fiddaman 							break;
302*906afcb8SAndy Fiddaman 						}
303*906afcb8SAndy Fiddaman 						else if (c == '#' && PEEK(a, p) == '\n')
304*906afcb8SAndy Fiddaman 							break;
305*906afcb8SAndy Fiddaman 				}
306*906afcb8SAndy Fiddaman 				else if (c == ' ')
307*906afcb8SAndy Fiddaman 					/*ignore*/;
308*906afcb8SAndy Fiddaman 				else if (c == '{') /* '}' */
309*906afcb8SAndy Fiddaman 					op = 1;
310*906afcb8SAndy Fiddaman 				else if (op == 1)
311*906afcb8SAndy Fiddaman 				{
312*906afcb8SAndy Fiddaman 					if (c == ')')
313*906afcb8SAndy Fiddaman 					{
314*906afcb8SAndy Fiddaman 						op = 2;
315*906afcb8SAndy Fiddaman 						n = 1;
316*906afcb8SAndy Fiddaman 					}
317*906afcb8SAndy Fiddaman 					else
318*906afcb8SAndy Fiddaman 						op = 0;
319*906afcb8SAndy Fiddaman 				}
320*906afcb8SAndy Fiddaman 				else if (op == 2)
321*906afcb8SAndy Fiddaman 				{
322*906afcb8SAndy Fiddaman 					if (c == ')')
323*906afcb8SAndy Fiddaman 						n++;
324*906afcb8SAndy Fiddaman 					else if (c == '(' && !--n)
325*906afcb8SAndy Fiddaman 						op = 3;
326*906afcb8SAndy Fiddaman 				}
327*906afcb8SAndy Fiddaman 				else if (op == 3)
328*906afcb8SAndy Fiddaman 				{
329*906afcb8SAndy Fiddaman 					if (ppisidig(c))
330*906afcb8SAndy Fiddaman 					{
331*906afcb8SAndy Fiddaman 						for (t = p, token = a, onumber = number; ppisidig(PEEK(a, p)) && a >= p; BACK(a, p));
332*906afcb8SAndy Fiddaman 						p = pp.valbuf + 1;
333*906afcb8SAndy Fiddaman 						if (a > token)
334*906afcb8SAndy Fiddaman 						{
335*906afcb8SAndy Fiddaman 							for (; a < pp.outbuf+2*PPBUFSIZ; *p++ = *a++);
336*906afcb8SAndy Fiddaman 							a = pp.outbuf;
337*906afcb8SAndy Fiddaman 						}
338*906afcb8SAndy Fiddaman 						for (; a <= token; *p++ = *a++);
339*906afcb8SAndy Fiddaman 						*p = 0;
340*906afcb8SAndy Fiddaman 						p = pp.valbuf + 1;
341*906afcb8SAndy Fiddaman 						if (streq(p, "for") || streq(p, "if") || streq(p, "switch") || streq(p, "while"))
342*906afcb8SAndy Fiddaman 						{
343*906afcb8SAndy Fiddaman 							op = 0;
344*906afcb8SAndy Fiddaman 							p = t;
345*906afcb8SAndy Fiddaman 							number = onumber;
346*906afcb8SAndy Fiddaman 							continue;
347*906afcb8SAndy Fiddaman 						}
348*906afcb8SAndy Fiddaman 					}
349*906afcb8SAndy Fiddaman 					else
350*906afcb8SAndy Fiddaman 						op = 0;
351*906afcb8SAndy Fiddaman 					break;
352*906afcb8SAndy Fiddaman 				}
353*906afcb8SAndy Fiddaman 			}
354*906afcb8SAndy Fiddaman 			if (op == 3)
355*906afcb8SAndy Fiddaman 				p = strncpy(pp.funbuf, p, sizeof(pp.funbuf) - 1);
356*906afcb8SAndy Fiddaman 			else if (*pp.funbuf)
357*906afcb8SAndy Fiddaman 				p = pp.funbuf;
358*906afcb8SAndy Fiddaman 			else
359*906afcb8SAndy Fiddaman 				p = "__FUNCTION__";
360*906afcb8SAndy Fiddaman 			break;
361*906afcb8SAndy Fiddaman 		default:
362*906afcb8SAndy Fiddaman 			if (pp.builtin && (a = (*pp.builtin)(pp.valbuf, p, a)))
363*906afcb8SAndy Fiddaman 				p = a;
364*906afcb8SAndy Fiddaman 			break;
365*906afcb8SAndy Fiddaman 		}
366*906afcb8SAndy Fiddaman 		break;
367*906afcb8SAndy Fiddaman 	}
368*906afcb8SAndy Fiddaman 	if (strchr(p, MARK))
369*906afcb8SAndy Fiddaman 	{
370*906afcb8SAndy Fiddaman 		a = pp.tmpbuf;
371*906afcb8SAndy Fiddaman 		strcpy(a, p);
372*906afcb8SAndy Fiddaman 		c = p != pp.valbuf;
373*906afcb8SAndy Fiddaman 		p = pp.valbuf + c;
374*906afcb8SAndy Fiddaman 		for (;;)
375*906afcb8SAndy Fiddaman 		{
376*906afcb8SAndy Fiddaman 			if (p < pp.valbuf + MAXTOKEN - 2)
377*906afcb8SAndy Fiddaman 				switch (*p++ = *a++)
378*906afcb8SAndy Fiddaman 				{
379*906afcb8SAndy Fiddaman 				case 0:
380*906afcb8SAndy Fiddaman 					break;
381*906afcb8SAndy Fiddaman 				case MARK:
382*906afcb8SAndy Fiddaman 					*p++ = MARK;
383*906afcb8SAndy Fiddaman 					/*FALLTHROUGH*/
384*906afcb8SAndy Fiddaman 				default:
385*906afcb8SAndy Fiddaman 					continue;
386*906afcb8SAndy Fiddaman 				}
387*906afcb8SAndy Fiddaman 			break;
388*906afcb8SAndy Fiddaman 		}
389*906afcb8SAndy Fiddaman 		p = pp.valbuf + c;
390*906afcb8SAndy Fiddaman 	}
391*906afcb8SAndy Fiddaman 	if (p == pp.valbuf)
392*906afcb8SAndy Fiddaman 		PUSH_STRING(p);
393*906afcb8SAndy Fiddaman 	else
394*906afcb8SAndy Fiddaman 	{
395*906afcb8SAndy Fiddaman 		if (p == pp.valbuf + 1)
396*906afcb8SAndy Fiddaman 			*pp.valbuf = '"';
397*906afcb8SAndy Fiddaman 		else
398*906afcb8SAndy Fiddaman 		{
399*906afcb8SAndy Fiddaman 			if (strlen(p) > MAXTOKEN - 2)
400*906afcb8SAndy Fiddaman 				error(1, "%-.16s: builtin value truncated", p);
401*906afcb8SAndy Fiddaman 			sfsprintf(pp.valbuf, MAXTOKEN, "\"%-.*s", MAXTOKEN - 2, p);
402*906afcb8SAndy Fiddaman 		}
403*906afcb8SAndy Fiddaman 		PUSH_QUOTE(pp.valbuf, 1);
404*906afcb8SAndy Fiddaman 	}
405*906afcb8SAndy Fiddaman }
406