1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1986-2011 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                                                                      *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman /*
22*b30d1939SAndy Fiddaman  * Glenn Fowler
23*b30d1939SAndy Fiddaman  * AT&T Research
24*b30d1939SAndy Fiddaman  *
25*b30d1939SAndy Fiddaman  * preprocessor stacked input stream support
26*b30d1939SAndy Fiddaman  */
27*b30d1939SAndy Fiddaman 
28*b30d1939SAndy Fiddaman #include "pplib.h"
29*b30d1939SAndy Fiddaman 
30*b30d1939SAndy Fiddaman 
31*b30d1939SAndy Fiddaman /*
32*b30d1939SAndy Fiddaman  * convert path to native representation
33*b30d1939SAndy Fiddaman  */
34*b30d1939SAndy Fiddaman 
35*b30d1939SAndy Fiddaman #include "../../lib/libast/path/pathnative.c" /* drop in 2002 */
36*b30d1939SAndy Fiddaman 
37*b30d1939SAndy Fiddaman static char*
native(register const char * s)38*b30d1939SAndy Fiddaman native(register const char* s)
39*b30d1939SAndy Fiddaman {
40*b30d1939SAndy Fiddaman 	register int		c;
41*b30d1939SAndy Fiddaman 	register struct ppfile* xp;
42*b30d1939SAndy Fiddaman 	int			m;
43*b30d1939SAndy Fiddaman 	int			n;
44*b30d1939SAndy Fiddaman 
45*b30d1939SAndy Fiddaman 	static Sfio_t*		np;
46*b30d1939SAndy Fiddaman 	static Sfio_t*		qp;
47*b30d1939SAndy Fiddaman 
48*b30d1939SAndy Fiddaman 	if (!s)
49*b30d1939SAndy Fiddaman 		return 0;
50*b30d1939SAndy Fiddaman 	if (!np && !(np = sfstropen()) || !qp && !(qp = sfstropen()))
51*b30d1939SAndy Fiddaman 		return (char*)s;
52*b30d1939SAndy Fiddaman 	n = PATH_MAX;
53*b30d1939SAndy Fiddaman 	do
54*b30d1939SAndy Fiddaman 	{
55*b30d1939SAndy Fiddaman 		m = n;
56*b30d1939SAndy Fiddaman 		n = pathnative(s, sfstrrsrv(np, m), m);
57*b30d1939SAndy Fiddaman 	} while (n > m);
58*b30d1939SAndy Fiddaman 	sfstrseek(np, n, SEEK_CUR);
59*b30d1939SAndy Fiddaman 	s = (const char*)sfstruse(np);
60*b30d1939SAndy Fiddaman 	for (;;)
61*b30d1939SAndy Fiddaman 	{
62*b30d1939SAndy Fiddaman 		switch (c = *s++)
63*b30d1939SAndy Fiddaman 		{
64*b30d1939SAndy Fiddaman 		case 0:
65*b30d1939SAndy Fiddaman 			break;
66*b30d1939SAndy Fiddaman 		case '\\':
67*b30d1939SAndy Fiddaman 		case '"':
68*b30d1939SAndy Fiddaman 			sfputc(qp, '\\');
69*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
70*b30d1939SAndy Fiddaman 		default:
71*b30d1939SAndy Fiddaman 			sfputc(qp, c);
72*b30d1939SAndy Fiddaman 			continue;
73*b30d1939SAndy Fiddaman 		}
74*b30d1939SAndy Fiddaman 		break;
75*b30d1939SAndy Fiddaman 	}
76*b30d1939SAndy Fiddaman 	if (!(xp = ppsetfile(sfstruse(qp))))
77*b30d1939SAndy Fiddaman 		return (char*)s;
78*b30d1939SAndy Fiddaman 	return xp->name;
79*b30d1939SAndy Fiddaman }
80*b30d1939SAndy Fiddaman 
81*b30d1939SAndy Fiddaman /*
82*b30d1939SAndy Fiddaman  * push stream onto input stack
83*b30d1939SAndy Fiddaman  * used by the PUSH_type macros
84*b30d1939SAndy Fiddaman  */
85*b30d1939SAndy Fiddaman 
86*b30d1939SAndy Fiddaman void
pppush(register int t,register char * s,register char * p,int n)87*b30d1939SAndy Fiddaman pppush(register int t, register char* s, register char* p, int n)
88*b30d1939SAndy Fiddaman {
89*b30d1939SAndy Fiddaman 	register struct ppinstk*	cur;
90*b30d1939SAndy Fiddaman 
91*b30d1939SAndy Fiddaman 	PUSH(t, cur);
92*b30d1939SAndy Fiddaman 	cur->line = error_info.line;
93*b30d1939SAndy Fiddaman 	cur->file = error_info.file;
94*b30d1939SAndy Fiddaman 	switch (t)
95*b30d1939SAndy Fiddaman 	{
96*b30d1939SAndy Fiddaman 	case IN_FILE:
97*b30d1939SAndy Fiddaman 		if (pp.option & NATIVE)
98*b30d1939SAndy Fiddaman 			s = native(s);
99*b30d1939SAndy Fiddaman 		cur->flags |= IN_newline;
100*b30d1939SAndy Fiddaman 		cur->fd = n;
101*b30d1939SAndy Fiddaman 		cur->hide = ++pp.hide;
102*b30d1939SAndy Fiddaman 		cur->symbol = 0;
103*b30d1939SAndy Fiddaman #if CHECKPOINT
104*b30d1939SAndy Fiddaman 		if ((pp.mode & (DUMP|INIT)) == DUMP)
105*b30d1939SAndy Fiddaman 		{
106*b30d1939SAndy Fiddaman 			cur->index = newof(0, struct ppindex, 1, 0);
107*b30d1939SAndy Fiddaman 			if (pp.lastindex) pp.lastindex->next = cur->index;
108*b30d1939SAndy Fiddaman 			else pp.firstindex = cur->index;
109*b30d1939SAndy Fiddaman 			pp.lastindex = cur->index;
110*b30d1939SAndy Fiddaman 			cur->index->file = pp.original;
111*b30d1939SAndy Fiddaman 			cur->index->begin = ppoffset();
112*b30d1939SAndy Fiddaman 		}
113*b30d1939SAndy Fiddaman #endif
114*b30d1939SAndy Fiddaman 		n = 1;
115*b30d1939SAndy Fiddaman #if CHECKPOINT
116*b30d1939SAndy Fiddaman 		if (!(pp.mode & DUMP))
117*b30d1939SAndy Fiddaman #endif
118*b30d1939SAndy Fiddaman 		if (!cur->prev->prev && !(pp.state & COMPILE) && isatty(0))
119*b30d1939SAndy Fiddaman 			cur->flags |= IN_flush;
120*b30d1939SAndy Fiddaman #if ARCHIVE
121*b30d1939SAndy Fiddaman 		if (pp.member)
122*b30d1939SAndy Fiddaman 		{
123*b30d1939SAndy Fiddaman 			switch (pp.member->archive->type & (TYPE_BUFFER|TYPE_CHECKPOINT))
124*b30d1939SAndy Fiddaman 			{
125*b30d1939SAndy Fiddaman 			case 0:
126*b30d1939SAndy Fiddaman #if CHECKPOINT
127*b30d1939SAndy Fiddaman 				cur->buflen = pp.member->size;
128*b30d1939SAndy Fiddaman #endif
129*b30d1939SAndy Fiddaman 				p = (cur->buffer = oldof(0, char, 0, pp.member->size + PPBAKSIZ + 1)) + PPBAKSIZ;
130*b30d1939SAndy Fiddaman 				if (sfseek(pp.member->archive->info.sp, pp.member->offset, SEEK_SET) != pp.member->offset)
131*b30d1939SAndy Fiddaman 					error(3, "%s: archive seek error", pp.member->archive->name);
132*b30d1939SAndy Fiddaman 				if (sfread(pp.member->archive->info.sp, p, pp.member->size) != pp.member->size)
133*b30d1939SAndy Fiddaman 					error(3, "%s: archive read error", pp.member->archive->name);
134*b30d1939SAndy Fiddaman 				pp.member = 0;
135*b30d1939SAndy Fiddaman 				break;
136*b30d1939SAndy Fiddaman 			case TYPE_BUFFER:
137*b30d1939SAndy Fiddaman #if CHECKPOINT
138*b30d1939SAndy Fiddaman 			case TYPE_CHECKPOINT|TYPE_BUFFER:
139*b30d1939SAndy Fiddaman 				cur->buflen = pp.member->size;
140*b30d1939SAndy Fiddaman #endif
141*b30d1939SAndy Fiddaman 				p = cur->buffer = pp.member->archive->info.buffer + pp.member->offset;
142*b30d1939SAndy Fiddaman 				cur->flags |= IN_static;
143*b30d1939SAndy Fiddaman 				pp.member = 0;
144*b30d1939SAndy Fiddaman 				break;
145*b30d1939SAndy Fiddaman #if CHECKPOINT
146*b30d1939SAndy Fiddaman 			case TYPE_CHECKPOINT:
147*b30d1939SAndy Fiddaman 				p = cur->buffer = "";
148*b30d1939SAndy Fiddaman 				cur->flags |= IN_static;
149*b30d1939SAndy Fiddaman 				break;
150*b30d1939SAndy Fiddaman #endif
151*b30d1939SAndy Fiddaman 			}
152*b30d1939SAndy Fiddaman 			cur->flags |= IN_eof|IN_newline;
153*b30d1939SAndy Fiddaman 			cur->fd = -1;
154*b30d1939SAndy Fiddaman 		}
155*b30d1939SAndy Fiddaman 		else
156*b30d1939SAndy Fiddaman #endif
157*b30d1939SAndy Fiddaman 		{
158*b30d1939SAndy Fiddaman 			if (lseek(cur->fd, 0L, SEEK_END) > 0 && !lseek(cur->fd, 0L, SEEK_SET))
159*b30d1939SAndy Fiddaman 				cur->flags |= IN_regular;
160*b30d1939SAndy Fiddaman 			errno = 0;
161*b30d1939SAndy Fiddaman #if PROTOTYPE
162*b30d1939SAndy Fiddaman 			if (!(pp.option & NOPROTO) && !(pp.test & TEST_noproto) && ((pp.state & (COMPATIBILITY|TRANSITION)) == COMPATIBILITY || (pp.option & PLUSPLUS) || (pp.mode & EXTERNALIZE)) && (cur->buffer = pppopen(NiL, cur->fd, NiL, NiL, NiL, NiL, (PROTO_HEADER|PROTO_RETAIN)|(((pp.mode & EXTERNALIZE) || (pp.option & PROTOTYPED)) ? PROTO_FORCE : PROTO_PASS)|((pp.mode & EXTERNALIZE) ? PROTO_EXTERNALIZE : 0)|((pp.mode & MARKC) ? PROTO_PLUSPLUS : 0))))
163*b30d1939SAndy Fiddaman 			{
164*b30d1939SAndy Fiddaman 				*(p = cur->buffer - 1) = 0;
165*b30d1939SAndy Fiddaman 				cur->buffer -= PPBAKSIZ;
166*b30d1939SAndy Fiddaman 				cur->flags |= IN_prototype;
167*b30d1939SAndy Fiddaman 				cur->fd = -1;
168*b30d1939SAndy Fiddaman 			}
169*b30d1939SAndy Fiddaman 			else
170*b30d1939SAndy Fiddaman #endif
171*b30d1939SAndy Fiddaman 			*(p = (cur->buffer = oldof(0, char, 0, PPBUFSIZ + PPBAKSIZ + 1)) + PPBAKSIZ) = 0;
172*b30d1939SAndy Fiddaman 		}
173*b30d1939SAndy Fiddaman 		if (pp.incref && !(pp.mode & INIT))
174*b30d1939SAndy Fiddaman 			(*pp.incref)(error_info.file, s, error_info.line - 1, PP_SYNC_PUSH);
175*b30d1939SAndy Fiddaman 		if (pp.macref || (pp.option & IGNORELINE))
176*b30d1939SAndy Fiddaman 			cur->flags |= IN_ignoreline;
177*b30d1939SAndy Fiddaman 		cur->prefix = pp.prefix;
178*b30d1939SAndy Fiddaman 		/*FALLTHROUGH*/
179*b30d1939SAndy Fiddaman 	case IN_BUFFER:
180*b30d1939SAndy Fiddaman 	case IN_INIT:
181*b30d1939SAndy Fiddaman 	case IN_RESCAN:
182*b30d1939SAndy Fiddaman 		pushcontrol();
183*b30d1939SAndy Fiddaman 		cur->control = pp.control;
184*b30d1939SAndy Fiddaman 		*pp.control = 0;
185*b30d1939SAndy Fiddaman 		cur->vendor = pp.vendor;
186*b30d1939SAndy Fiddaman 		if (cur->type != IN_RESCAN)
187*b30d1939SAndy Fiddaman 		{
188*b30d1939SAndy Fiddaman 			if (cur->type == IN_INIT)
189*b30d1939SAndy Fiddaman 				pp.mode |= MARKHOSTED;
190*b30d1939SAndy Fiddaman 			error_info.file = s;
191*b30d1939SAndy Fiddaman 			error_info.line = n;
192*b30d1939SAndy Fiddaman 		}
193*b30d1939SAndy Fiddaman 		if (pp.state & HIDDEN)
194*b30d1939SAndy Fiddaman 		{
195*b30d1939SAndy Fiddaman 			pp.state &= ~HIDDEN;
196*b30d1939SAndy Fiddaman 			pp.hidden = 0;
197*b30d1939SAndy Fiddaman 			if (!(pp.state & NOTEXT) && pplastout() != '\n')
198*b30d1939SAndy Fiddaman 				ppputchar('\n');
199*b30d1939SAndy Fiddaman 		}
200*b30d1939SAndy Fiddaman 		pp.state |= NEWLINE;
201*b30d1939SAndy Fiddaman 		if (pp.mode & HOSTED) cur->flags |= IN_hosted;
202*b30d1939SAndy Fiddaman 		else cur->flags &= ~IN_hosted;
203*b30d1939SAndy Fiddaman 		if (pp.mode & (INIT|MARKHOSTED))
204*b30d1939SAndy Fiddaman 		{
205*b30d1939SAndy Fiddaman 			pp.mode |= HOSTED;
206*b30d1939SAndy Fiddaman 			pp.flags |= PP_hosted;
207*b30d1939SAndy Fiddaman 		}
208*b30d1939SAndy Fiddaman 		switch (cur->type)
209*b30d1939SAndy Fiddaman 		{
210*b30d1939SAndy Fiddaman 		case IN_FILE:
211*b30d1939SAndy Fiddaman 			if (!(pp.mode & (INIT|MARKHOSTED)))
212*b30d1939SAndy Fiddaman 			{
213*b30d1939SAndy Fiddaman 				pp.mode &= ~HOSTED;
214*b30d1939SAndy Fiddaman 				pp.flags &= ~PP_hosted;
215*b30d1939SAndy Fiddaman 			}
216*b30d1939SAndy Fiddaman #if CATSTRINGS
217*b30d1939SAndy Fiddaman 			if (pp.state & JOINING) pp.state |= HIDDEN|SYNCLINE;
218*b30d1939SAndy Fiddaman 			else
219*b30d1939SAndy Fiddaman #endif
220*b30d1939SAndy Fiddaman 			if (pp.linesync)
221*b30d1939SAndy Fiddaman 				(*pp.linesync)(error_info.line, error_info.file);
222*b30d1939SAndy Fiddaman #if ARCHIVE && CHECKPOINT
223*b30d1939SAndy Fiddaman 			if (pp.member)
224*b30d1939SAndy Fiddaman 				ppload(NiL);
225*b30d1939SAndy Fiddaman #endif
226*b30d1939SAndy Fiddaman 			if (pp.mode & MARKC)
227*b30d1939SAndy Fiddaman 			{
228*b30d1939SAndy Fiddaman 				cur->flags |= IN_c;
229*b30d1939SAndy Fiddaman 				pp.mode &= ~MARKC;
230*b30d1939SAndy Fiddaman 				if (!(cur->prev->flags & IN_c))
231*b30d1939SAndy Fiddaman 				{
232*b30d1939SAndy Fiddaman 					debug((-7, "PUSH in=%s next=%s [%s]", ppinstr(pp.in), pptokchr(*pp.in->nextchr), pp.in->nextchr));
233*b30d1939SAndy Fiddaman 					PUSH_BUFFER("C", "extern \"C\" {\n", 1);
234*b30d1939SAndy Fiddaman 					return;
235*b30d1939SAndy Fiddaman 				}
236*b30d1939SAndy Fiddaman 			}
237*b30d1939SAndy Fiddaman 			else if (cur->prev->flags & IN_c)
238*b30d1939SAndy Fiddaman 			{
239*b30d1939SAndy Fiddaman 				debug((-7, "PUSH in=%s next=%s [%s]", ppinstr(pp.in), pptokchr(*pp.in->nextchr), pp.in->nextchr));
240*b30d1939SAndy Fiddaman 				PUSH_BUFFER("C", "extern \"C++\" {\n", 1);
241*b30d1939SAndy Fiddaman 				return;
242*b30d1939SAndy Fiddaman 			}
243*b30d1939SAndy Fiddaman 			break;
244*b30d1939SAndy Fiddaman 		case IN_BUFFER:
245*b30d1939SAndy Fiddaman 			cur->buffer = p = strdup(p);
246*b30d1939SAndy Fiddaman 			break;
247*b30d1939SAndy Fiddaman 		default:
248*b30d1939SAndy Fiddaman 			cur->buffer = p;
249*b30d1939SAndy Fiddaman 			break;
250*b30d1939SAndy Fiddaman 		}
251*b30d1939SAndy Fiddaman 		cur->nextchr = p;
252*b30d1939SAndy Fiddaman 		break;
253*b30d1939SAndy Fiddaman #if DEBUG
254*b30d1939SAndy Fiddaman 	default:
255*b30d1939SAndy Fiddaman 		error(PANIC, "use PUSH_<%d>(...) instead of pppush(IN_<%d>, ...)", cur->type, cur->type);
256*b30d1939SAndy Fiddaman 		break;
257*b30d1939SAndy Fiddaman #endif
258*b30d1939SAndy Fiddaman 	}
259*b30d1939SAndy Fiddaman 	debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr)));
260*b30d1939SAndy Fiddaman }
261*b30d1939SAndy Fiddaman 
262*b30d1939SAndy Fiddaman /*
263*b30d1939SAndy Fiddaman  * external buffer push
264*b30d1939SAndy Fiddaman  */
265*b30d1939SAndy Fiddaman 
266*b30d1939SAndy Fiddaman void
ppinput(char * b,char * f,int n)267*b30d1939SAndy Fiddaman ppinput(char* b, char* f, int n)
268*b30d1939SAndy Fiddaman {
269*b30d1939SAndy Fiddaman 	PUSH_BUFFER(f, b, n);
270*b30d1939SAndy Fiddaman }
271*b30d1939SAndy Fiddaman 
272*b30d1939SAndy Fiddaman /*
273*b30d1939SAndy Fiddaman  * return expanded value of buffer p
274*b30d1939SAndy Fiddaman  */
275*b30d1939SAndy Fiddaman 
276*b30d1939SAndy Fiddaman char*
ppexpand(register char * p)277*b30d1939SAndy Fiddaman ppexpand(register char* p)
278*b30d1939SAndy Fiddaman {
279*b30d1939SAndy Fiddaman 	register char*		m;
280*b30d1939SAndy Fiddaman 	register int		n;
281*b30d1939SAndy Fiddaman 	register int		c;
282*b30d1939SAndy Fiddaman 	long			restore;
283*b30d1939SAndy Fiddaman 	char*			pptoken;
284*b30d1939SAndy Fiddaman 	char*			ppmactop;
285*b30d1939SAndy Fiddaman 	struct ppmacstk*	nextmacp;
286*b30d1939SAndy Fiddaman 	struct ppinstk*		cur;
287*b30d1939SAndy Fiddaman 
288*b30d1939SAndy Fiddaman 	debug((-7, "before expand: %s", p));
289*b30d1939SAndy Fiddaman 	if (ppmactop = pp.mactop)
290*b30d1939SAndy Fiddaman 	{
291*b30d1939SAndy Fiddaman 		nextmacp = pp.macp->next;
292*b30d1939SAndy Fiddaman 		nextframe(pp.macp, pp.mactop);
293*b30d1939SAndy Fiddaman 	}
294*b30d1939SAndy Fiddaman 	restore = pp.state & (COLLECTING|DISABLE|STRIP);
295*b30d1939SAndy Fiddaman 	pp.state &= ~restore;
296*b30d1939SAndy Fiddaman 	pp.mode &= ~MARKMACRO;
297*b30d1939SAndy Fiddaman 	PUSH_STRING(p);
298*b30d1939SAndy Fiddaman 	cur = pp.in;
299*b30d1939SAndy Fiddaman 	pp.in->flags |= IN_expand;
300*b30d1939SAndy Fiddaman 	pptoken = pp.token;
301*b30d1939SAndy Fiddaman 	n = 2 * MAXTOKEN;
302*b30d1939SAndy Fiddaman 	pp.token = p = oldof(0, char, 0, n);
303*b30d1939SAndy Fiddaman 	m = p + MAXTOKEN;
304*b30d1939SAndy Fiddaman 	for (;;)
305*b30d1939SAndy Fiddaman 	{
306*b30d1939SAndy Fiddaman 		if (pplex())
307*b30d1939SAndy Fiddaman 		{
308*b30d1939SAndy Fiddaman 			if ((pp.token = pp.toknxt) > m)
309*b30d1939SAndy Fiddaman 			{
310*b30d1939SAndy Fiddaman 				c = pp.token - p;
311*b30d1939SAndy Fiddaman 				p = newof(p, char, n += MAXTOKEN, 0);
312*b30d1939SAndy Fiddaman 				m = p + n - MAXTOKEN;
313*b30d1939SAndy Fiddaman 				pp.token = p + c;
314*b30d1939SAndy Fiddaman 			}
315*b30d1939SAndy Fiddaman 			if (pp.mode & MARKMACRO)
316*b30d1939SAndy Fiddaman 			{
317*b30d1939SAndy Fiddaman 				pp.mode &= ~MARKMACRO;
318*b30d1939SAndy Fiddaman 				*pp.token++ = MARK;
319*b30d1939SAndy Fiddaman 				*pp.token++ = 'X';
320*b30d1939SAndy Fiddaman 			}
321*b30d1939SAndy Fiddaman 		}
322*b30d1939SAndy Fiddaman 		else if (pp.in == cur)
323*b30d1939SAndy Fiddaman 			break;
324*b30d1939SAndy Fiddaman 	}
325*b30d1939SAndy Fiddaman 	*pp.token = 0;
326*b30d1939SAndy Fiddaman 	if (ppmactop)
327*b30d1939SAndy Fiddaman 		pp.macp->next = nextmacp;
328*b30d1939SAndy Fiddaman 	debug((-7, "after expand: %s", p));
329*b30d1939SAndy Fiddaman 	pp.token = pptoken;
330*b30d1939SAndy Fiddaman 	pp.state |= restore;
331*b30d1939SAndy Fiddaman 	pp.in = pp.in->prev;
332*b30d1939SAndy Fiddaman 	return p;
333*b30d1939SAndy Fiddaman }
334*b30d1939SAndy Fiddaman 
335*b30d1939SAndy Fiddaman #if CHECKPOINT
336*b30d1939SAndy Fiddaman 
337*b30d1939SAndy Fiddaman #define LOAD_FUNCTION	(1<<0)
338*b30d1939SAndy Fiddaman #define LOAD_MULTILINE	(1<<1)
339*b30d1939SAndy Fiddaman #define LOAD_NOEXPAND	(1<<2)
340*b30d1939SAndy Fiddaman #define LOAD_PREDICATE	(1<<3)
341*b30d1939SAndy Fiddaman #define LOAD_READONLY	(1<<4)
342*b30d1939SAndy Fiddaman #define LOAD_VARIADIC	(1<<5)
343*b30d1939SAndy Fiddaman 
344*b30d1939SAndy Fiddaman /*
345*b30d1939SAndy Fiddaman  * macro definition dump
346*b30d1939SAndy Fiddaman  */
347*b30d1939SAndy Fiddaman 
348*b30d1939SAndy Fiddaman static int
dump(const char * name,char * v,void * handle)349*b30d1939SAndy Fiddaman dump(const char* name, char* v, void* handle)
350*b30d1939SAndy Fiddaman {
351*b30d1939SAndy Fiddaman 	register struct ppmacro*	mac;
352*b30d1939SAndy Fiddaman 	register struct ppsymbol*	sym = (struct ppsymbol*)v;
353*b30d1939SAndy Fiddaman 	register int			flags;
354*b30d1939SAndy Fiddaman 
355*b30d1939SAndy Fiddaman 	NoP(name);
356*b30d1939SAndy Fiddaman 	NoP(handle);
357*b30d1939SAndy Fiddaman 	if ((mac = sym->macro) && !(sym->flags & (SYM_BUILTIN|SYM_PREDEFINED)))
358*b30d1939SAndy Fiddaman 	{
359*b30d1939SAndy Fiddaman 		ppprintf("%s", sym->name);
360*b30d1939SAndy Fiddaman 		ppputchar(0);
361*b30d1939SAndy Fiddaman 		flags = 0;
362*b30d1939SAndy Fiddaman 		if (sym->flags & SYM_FUNCTION) flags |= LOAD_FUNCTION;
363*b30d1939SAndy Fiddaman 		if (sym->flags & SYM_MULTILINE) flags |= LOAD_MULTILINE;
364*b30d1939SAndy Fiddaman 		if (sym->flags & SYM_NOEXPAND) flags |= LOAD_NOEXPAND;
365*b30d1939SAndy Fiddaman 		if (sym->flags & SYM_PREDICATE) flags |= LOAD_PREDICATE;
366*b30d1939SAndy Fiddaman 		if (sym->flags & SYM_READONLY) flags |= LOAD_READONLY;
367*b30d1939SAndy Fiddaman 		if (sym->flags & SYM_VARIADIC) flags |= LOAD_VARIADIC;
368*b30d1939SAndy Fiddaman 		ppputchar(flags);
369*b30d1939SAndy Fiddaman 		if (sym->flags & SYM_FUNCTION)
370*b30d1939SAndy Fiddaman 		{
371*b30d1939SAndy Fiddaman 			ppprintf("%d", mac->arity);
372*b30d1939SAndy Fiddaman 			ppputchar(0);
373*b30d1939SAndy Fiddaman 			if (mac->arity)
374*b30d1939SAndy Fiddaman 			{
375*b30d1939SAndy Fiddaman 				ppprintf("%s", mac->formals);
376*b30d1939SAndy Fiddaman 				ppputchar(0);
377*b30d1939SAndy Fiddaman 			}
378*b30d1939SAndy Fiddaman 		}
379*b30d1939SAndy Fiddaman 		ppprintf("%s", mac->value);
380*b30d1939SAndy Fiddaman 		ppputchar(0);
381*b30d1939SAndy Fiddaman 	}
382*b30d1939SAndy Fiddaman 	return(0);
383*b30d1939SAndy Fiddaman }
384*b30d1939SAndy Fiddaman 
385*b30d1939SAndy Fiddaman /*
386*b30d1939SAndy Fiddaman  * dump macro definitions for quick loading via ppload()
387*b30d1939SAndy Fiddaman  */
388*b30d1939SAndy Fiddaman 
389*b30d1939SAndy Fiddaman void
ppdump(void)390*b30d1939SAndy Fiddaman ppdump(void)
391*b30d1939SAndy Fiddaman {
392*b30d1939SAndy Fiddaman 	register struct ppindex*	ip;
393*b30d1939SAndy Fiddaman 	unsigned long			macro_offset;
394*b30d1939SAndy Fiddaman 	unsigned long			index_offset;
395*b30d1939SAndy Fiddaman 
396*b30d1939SAndy Fiddaman 	/*
397*b30d1939SAndy Fiddaman 	 * NOTE: we assume '\0' does not occur in valid preprocessed output
398*b30d1939SAndy Fiddaman 	 */
399*b30d1939SAndy Fiddaman 
400*b30d1939SAndy Fiddaman 	ppputchar(0);
401*b30d1939SAndy Fiddaman 
402*b30d1939SAndy Fiddaman 	/*
403*b30d1939SAndy Fiddaman 	 * output global flags
404*b30d1939SAndy Fiddaman 	 */
405*b30d1939SAndy Fiddaman 
406*b30d1939SAndy Fiddaman 	macro_offset = ppoffset();
407*b30d1939SAndy Fiddaman 	ppputchar(0);
408*b30d1939SAndy Fiddaman 
409*b30d1939SAndy Fiddaman 	/*
410*b30d1939SAndy Fiddaman 	 * output macro definitions
411*b30d1939SAndy Fiddaman 	 */
412*b30d1939SAndy Fiddaman 
413*b30d1939SAndy Fiddaman 	hashwalk(pp.symtab, 0, dump, NiL);
414*b30d1939SAndy Fiddaman 	ppputchar(0);
415*b30d1939SAndy Fiddaman 
416*b30d1939SAndy Fiddaman 	/*
417*b30d1939SAndy Fiddaman 	 * output include file index
418*b30d1939SAndy Fiddaman 	 */
419*b30d1939SAndy Fiddaman 
420*b30d1939SAndy Fiddaman 	index_offset = ppoffset();
421*b30d1939SAndy Fiddaman 	ip = pp.firstindex;
422*b30d1939SAndy Fiddaman 	while (ip)
423*b30d1939SAndy Fiddaman 	{
424*b30d1939SAndy Fiddaman 		ppprintf("%s", ip->file->name);
425*b30d1939SAndy Fiddaman 		ppputchar(0);
426*b30d1939SAndy Fiddaman 		if (ip->file->guard != INC_CLEAR && ip->file->guard != INC_IGNORE && ip->file->guard != INC_TEST)
427*b30d1939SAndy Fiddaman 			ppprintf("%s", ip->file->guard->name);
428*b30d1939SAndy Fiddaman 		ppputchar(0);
429*b30d1939SAndy Fiddaman 		ppprintf("%lu", ip->begin);
430*b30d1939SAndy Fiddaman 		ppputchar(0);
431*b30d1939SAndy Fiddaman 		ppprintf("%lu", ip->end);
432*b30d1939SAndy Fiddaman 		ppputchar(0);
433*b30d1939SAndy Fiddaman 		ip = ip->next;
434*b30d1939SAndy Fiddaman 	}
435*b30d1939SAndy Fiddaman 	ppputchar(0);
436*b30d1939SAndy Fiddaman 
437*b30d1939SAndy Fiddaman 	/*
438*b30d1939SAndy Fiddaman 	 * output offset directory
439*b30d1939SAndy Fiddaman 	 */
440*b30d1939SAndy Fiddaman 
441*b30d1939SAndy Fiddaman 	ppprintf("%010lu", macro_offset);
442*b30d1939SAndy Fiddaman 	ppputchar(0);
443*b30d1939SAndy Fiddaman 	ppprintf("%010lu", index_offset);
444*b30d1939SAndy Fiddaman 	ppputchar(0);
445*b30d1939SAndy Fiddaman 	ppflushout();
446*b30d1939SAndy Fiddaman }
447*b30d1939SAndy Fiddaman 
448*b30d1939SAndy Fiddaman /*
449*b30d1939SAndy Fiddaman  * load text and macro definitions from a previous ppdump()
450*b30d1939SAndy Fiddaman  * s is the string argument from the pragma (including quotes)
451*b30d1939SAndy Fiddaman  */
452*b30d1939SAndy Fiddaman 
453*b30d1939SAndy Fiddaman void
ppload(register char * s)454*b30d1939SAndy Fiddaman ppload(register char* s)
455*b30d1939SAndy Fiddaman {
456*b30d1939SAndy Fiddaman 	register char*		b;
457*b30d1939SAndy Fiddaman 	register Sfio_t*	sp;
458*b30d1939SAndy Fiddaman 	int			m;
459*b30d1939SAndy Fiddaman 	char*			g;
460*b30d1939SAndy Fiddaman 	char*			t;
461*b30d1939SAndy Fiddaman 	unsigned long		n;
462*b30d1939SAndy Fiddaman 	unsigned long		p;
463*b30d1939SAndy Fiddaman 	unsigned long		macro_offset;
464*b30d1939SAndy Fiddaman 	unsigned long		index_offset;
465*b30d1939SAndy Fiddaman 	unsigned long		file_offset;
466*b30d1939SAndy Fiddaman 	unsigned long		file_size;
467*b30d1939SAndy Fiddaman 	unsigned long		keep_begin;
468*b30d1939SAndy Fiddaman 	unsigned long		keep_end;
469*b30d1939SAndy Fiddaman 	unsigned long		skip_end;
470*b30d1939SAndy Fiddaman 	unsigned long		next_begin;
471*b30d1939SAndy Fiddaman 	unsigned long		next_end;
472*b30d1939SAndy Fiddaman 	struct ppfile*		fp;
473*b30d1939SAndy Fiddaman 	struct ppsymbol*	sym;
474*b30d1939SAndy Fiddaman 	struct ppmacro*		mac;
475*b30d1939SAndy Fiddaman 
476*b30d1939SAndy Fiddaman 	char*			ip = 0;
477*b30d1939SAndy Fiddaman 
478*b30d1939SAndy Fiddaman 	pp.mode |= LOADING;
479*b30d1939SAndy Fiddaman 	if (!(pp.state & STANDALONE))
480*b30d1939SAndy Fiddaman 		error(3, "checkpoint load in standalone mode only");
481*b30d1939SAndy Fiddaman #if ARCHIVE
482*b30d1939SAndy Fiddaman 	if (pp.member)
483*b30d1939SAndy Fiddaman 	{
484*b30d1939SAndy Fiddaman 		sp = pp.member->archive->info.sp;
485*b30d1939SAndy Fiddaman 		file_offset = pp.member->offset;
486*b30d1939SAndy Fiddaman 		file_size = pp.member->size;
487*b30d1939SAndy Fiddaman 		if (sfseek(sp, file_offset + 22, SEEK_SET) != file_offset + 22 || !(s = sfgetr(sp, '\n', 1)))
488*b30d1939SAndy Fiddaman 			error(3, "checkpoint magic error");
489*b30d1939SAndy Fiddaman 	}
490*b30d1939SAndy Fiddaman 	else
491*b30d1939SAndy Fiddaman #endif
492*b30d1939SAndy Fiddaman 	{
493*b30d1939SAndy Fiddaman 		if (pp.in->type != IN_FILE)
494*b30d1939SAndy Fiddaman 			error(3, "checkpoint load from files only");
495*b30d1939SAndy Fiddaman 		if (pp.in->flags & IN_prototype)
496*b30d1939SAndy Fiddaman 			pp.in->fd = pppdrop(pp.in->buffer + PPBAKSIZ);
497*b30d1939SAndy Fiddaman 		file_offset = 0;
498*b30d1939SAndy Fiddaman 		if (pp.in->fd >= 0)
499*b30d1939SAndy Fiddaman 		{
500*b30d1939SAndy Fiddaman 			if (!(sp = sfnew(NiL, NiL, SF_UNBOUND, pp.in->fd, SF_READ)))
501*b30d1939SAndy Fiddaman 				error(3, "checkpoint read error");
502*b30d1939SAndy Fiddaman 			file_size = sfseek(sp, 0L, SEEK_END);
503*b30d1939SAndy Fiddaman 		}
504*b30d1939SAndy Fiddaman 		else
505*b30d1939SAndy Fiddaman 		{
506*b30d1939SAndy Fiddaman 			file_size = pp.in->buflen;
507*b30d1939SAndy Fiddaman 			if (!(sp = sfnew(NiL, pp.in->buffer + ((pp.in->flags & IN_static) ? 0 : PPBAKSIZ), file_size, -1, SF_READ|SF_STRING)))
508*b30d1939SAndy Fiddaman 				error(3, "checkpoint read error");
509*b30d1939SAndy Fiddaman 		}
510*b30d1939SAndy Fiddaman 	}
511*b30d1939SAndy Fiddaman 	if (!streq(s, pp.checkpoint))
512*b30d1939SAndy Fiddaman 		error(3, "checkpoint version %s does not match %s", s, pp.checkpoint);
513*b30d1939SAndy Fiddaman 
514*b30d1939SAndy Fiddaman 	/*
515*b30d1939SAndy Fiddaman 	 * get the macro and index offsets
516*b30d1939SAndy Fiddaman 	 */
517*b30d1939SAndy Fiddaman 
518*b30d1939SAndy Fiddaman 	p = file_offset + file_size - 22;
519*b30d1939SAndy Fiddaman 	if ((n = sfseek(sp, p, SEEK_SET)) != p)
520*b30d1939SAndy Fiddaman 		error(3, "checkpoint directory seek error");
521*b30d1939SAndy Fiddaman 	if (!(t = sfreserve(sp, 22, 0)))
522*b30d1939SAndy Fiddaman 		error(3, "checkpoint directory read error");
523*b30d1939SAndy Fiddaman 	macro_offset = file_offset + strtol(t, &t, 10);
524*b30d1939SAndy Fiddaman 	index_offset = file_offset + strtol(t + 1, NiL, 10);
525*b30d1939SAndy Fiddaman 
526*b30d1939SAndy Fiddaman 	/*
527*b30d1939SAndy Fiddaman 	 * read the include index
528*b30d1939SAndy Fiddaman 	 */
529*b30d1939SAndy Fiddaman 
530*b30d1939SAndy Fiddaman 	if (sfseek(sp, index_offset, SEEK_SET) != index_offset)
531*b30d1939SAndy Fiddaman 		error(3, "checkpoint index seek error");
532*b30d1939SAndy Fiddaman 	if (!(s = sfreserve(sp, n - index_offset, 0)))
533*b30d1939SAndy Fiddaman 		error(3, "checkpoint index read error");
534*b30d1939SAndy Fiddaman 	if (sfset(sp, 0, 0) & SF_STRING)
535*b30d1939SAndy Fiddaman 		b = s;
536*b30d1939SAndy Fiddaman 	else if (!(b = ip = memdup(s, n - index_offset)))
537*b30d1939SAndy Fiddaman 		error(3, "checkpoint index alloc error");
538*b30d1939SAndy Fiddaman 
539*b30d1939SAndy Fiddaman 	/*
540*b30d1939SAndy Fiddaman 	 * loop on the index and copy the non-ignored chunks to the output
541*b30d1939SAndy Fiddaman 	 */
542*b30d1939SAndy Fiddaman 
543*b30d1939SAndy Fiddaman 	ppcheckout();
544*b30d1939SAndy Fiddaman 	p = PPBUFSIZ - (pp.outp - pp.outbuf);
545*b30d1939SAndy Fiddaman 	keep_begin = 0;
546*b30d1939SAndy Fiddaman 	keep_end = 0;
547*b30d1939SAndy Fiddaman 	skip_end = 0;
548*b30d1939SAndy Fiddaman 	while (*b)
549*b30d1939SAndy Fiddaman 	{
550*b30d1939SAndy Fiddaman 		fp = ppsetfile(b);
551*b30d1939SAndy Fiddaman 		while (*b++);
552*b30d1939SAndy Fiddaman 		g = b;
553*b30d1939SAndy Fiddaman 		while (*b++);
554*b30d1939SAndy Fiddaman 		next_begin = strtol(b, &t, 10);
555*b30d1939SAndy Fiddaman 		next_end = strtol(t + 1, &t, 10);
556*b30d1939SAndy Fiddaman if (pp.test & 0x0200) error(2, "%s: %s p=%lu next=<%lu,%lu> keep=<%lu,%lu> skip=<-,%lu> guard=%s", keyname(X_CHECKPOINT), fp->name, p, next_begin, next_end, keep_begin, keep_end, skip_end, fp->guard == INC_CLEAR ? "[CLEAR]" : fp->guard == INC_TEST ? "[TEST]" : fp->guard == INC_IGNORE ? "[IGNORE]" : fp->guard->name);
557*b30d1939SAndy Fiddaman 		b = t + 1;
558*b30d1939SAndy Fiddaman 		if (next_begin >= skip_end)
559*b30d1939SAndy Fiddaman 		{
560*b30d1939SAndy Fiddaman 			if (!ppmultiple(fp, INC_TEST))
561*b30d1939SAndy Fiddaman 			{
562*b30d1939SAndy Fiddaman if (pp.test & 0x0100) error(2, "%s: %s IGNORE", keyname(X_CHECKPOINT), fp->name);
563*b30d1939SAndy Fiddaman 				if (!keep_begin && skip_end < next_begin)
564*b30d1939SAndy Fiddaman 					keep_begin = skip_end;
565*b30d1939SAndy Fiddaman 				if (keep_begin)
566*b30d1939SAndy Fiddaman 				{
567*b30d1939SAndy Fiddaman 				flush:
568*b30d1939SAndy Fiddaman 					if (sfseek(sp, file_offset + keep_begin, SEEK_SET) != file_offset + keep_begin)
569*b30d1939SAndy Fiddaman 						error(3, "checkpoint data seek error");
570*b30d1939SAndy Fiddaman 					n = next_begin - keep_begin;
571*b30d1939SAndy Fiddaman if (pp.test & 0x0100) error(2, "%s: copy <%lu,%lu> n=%lu p=%lu", keyname(X_CHECKPOINT), keep_begin, next_begin - 1, n, p);
572*b30d1939SAndy Fiddaman 					while (n > p)
573*b30d1939SAndy Fiddaman 					{
574*b30d1939SAndy Fiddaman 						if (sfread(sp, pp.outp, p) != p)
575*b30d1939SAndy Fiddaman 							error(3, "checkpoint data read error");
576*b30d1939SAndy Fiddaman 						PPWRITE(PPBUFSIZ);
577*b30d1939SAndy Fiddaman 						pp.outp = pp.outbuf;
578*b30d1939SAndy Fiddaman 						n -= p;
579*b30d1939SAndy Fiddaman 						p = PPBUFSIZ;
580*b30d1939SAndy Fiddaman 					}
581*b30d1939SAndy Fiddaman 					if (n)
582*b30d1939SAndy Fiddaman 					{
583*b30d1939SAndy Fiddaman 						if (sfread(sp, pp.outp, n) != n)
584*b30d1939SAndy Fiddaman 							error(3, "checkpoint data read error");
585*b30d1939SAndy Fiddaman 						pp.outp += n;
586*b30d1939SAndy Fiddaman 						p -= n;
587*b30d1939SAndy Fiddaman 					}
588*b30d1939SAndy Fiddaman 					keep_begin = 0;
589*b30d1939SAndy Fiddaman 					if (keep_end <= next_end)
590*b30d1939SAndy Fiddaman 						keep_end = 0;
591*b30d1939SAndy Fiddaman 				}
592*b30d1939SAndy Fiddaman 				skip_end = next_end;
593*b30d1939SAndy Fiddaman 			}
594*b30d1939SAndy Fiddaman 			else if (!keep_begin)
595*b30d1939SAndy Fiddaman 			{
596*b30d1939SAndy Fiddaman 				if (skip_end)
597*b30d1939SAndy Fiddaman 				{
598*b30d1939SAndy Fiddaman 					keep_begin = skip_end;
599*b30d1939SAndy Fiddaman 					skip_end = 0;
600*b30d1939SAndy Fiddaman 				}
601*b30d1939SAndy Fiddaman 				else keep_begin = next_begin;
602*b30d1939SAndy Fiddaman 				if (keep_end < next_end)
603*b30d1939SAndy Fiddaman 					keep_end = next_end;
604*b30d1939SAndy Fiddaman 			}
605*b30d1939SAndy Fiddaman 		}
606*b30d1939SAndy Fiddaman 		if (*g && fp->guard != INC_IGNORE)
607*b30d1939SAndy Fiddaman 			fp->guard = ppsymset(pp.symtab, g);
608*b30d1939SAndy Fiddaman 	}
609*b30d1939SAndy Fiddaman 	if (keep_end)
610*b30d1939SAndy Fiddaman 	{
611*b30d1939SAndy Fiddaman 		if (!keep_begin)
612*b30d1939SAndy Fiddaman 			keep_begin = skip_end > next_end ? skip_end : next_end;
613*b30d1939SAndy Fiddaman 		next_begin = next_end = keep_end;
614*b30d1939SAndy Fiddaman 		g = b;
615*b30d1939SAndy Fiddaman 		goto flush;
616*b30d1939SAndy Fiddaman 	}
617*b30d1939SAndy Fiddaman if (pp.test & 0x0100) error(2, "%s: loop", keyname(X_CHECKPOINT));
618*b30d1939SAndy Fiddaman 
619*b30d1939SAndy Fiddaman 	/*
620*b30d1939SAndy Fiddaman 	 * read the compacted definitions
621*b30d1939SAndy Fiddaman 	 */
622*b30d1939SAndy Fiddaman 
623*b30d1939SAndy Fiddaman 	if (sfseek(sp, macro_offset, SEEK_SET) != macro_offset)
624*b30d1939SAndy Fiddaman 		error(3, "checkpoint macro seek error");
625*b30d1939SAndy Fiddaman 	if (!(s = sfreserve(sp, index_offset - macro_offset, 0)))
626*b30d1939SAndy Fiddaman 		error(3, "checkpoint macro read error");
627*b30d1939SAndy Fiddaman 
628*b30d1939SAndy Fiddaman 	/*
629*b30d1939SAndy Fiddaman 	 * read the flags
630*b30d1939SAndy Fiddaman 	 */
631*b30d1939SAndy Fiddaman 
632*b30d1939SAndy Fiddaman 	while (*s)
633*b30d1939SAndy Fiddaman 	{
634*b30d1939SAndy Fiddaman #if _options_dumped_
635*b30d1939SAndy Fiddaman 		if (streq(s, "OPTION")) /* ... */;
636*b30d1939SAndy Fiddaman 		else
637*b30d1939SAndy Fiddaman #endif
638*b30d1939SAndy Fiddaman 		error(3, "%-.48s: unknown flags in checkpoint file", s);
639*b30d1939SAndy Fiddaman 	}
640*b30d1939SAndy Fiddaman 	s++;
641*b30d1939SAndy Fiddaman 
642*b30d1939SAndy Fiddaman 	/*
643*b30d1939SAndy Fiddaman 	 * unpack and enter the definitions
644*b30d1939SAndy Fiddaman 	 */
645*b30d1939SAndy Fiddaman 
646*b30d1939SAndy Fiddaman 	while (*s)
647*b30d1939SAndy Fiddaman 	{
648*b30d1939SAndy Fiddaman 		b = s;
649*b30d1939SAndy Fiddaman 		while (*s++);
650*b30d1939SAndy Fiddaman 		m = *s++;
651*b30d1939SAndy Fiddaman 		sym = ppsymset(pp.symtab, b);
652*b30d1939SAndy Fiddaman 		if (sym->macro)
653*b30d1939SAndy Fiddaman 		{
654*b30d1939SAndy Fiddaman 			if (m & LOAD_FUNCTION)
655*b30d1939SAndy Fiddaman 			{
656*b30d1939SAndy Fiddaman 				if (*s++ != '0')
657*b30d1939SAndy Fiddaman 					while (*s++);
658*b30d1939SAndy Fiddaman 				while (*s++);
659*b30d1939SAndy Fiddaman 			}
660*b30d1939SAndy Fiddaman if (pp.test & 0x1000) error(2, "checkpoint SKIP %s=%s [%s]", sym->name, s, sym->macro->value);
661*b30d1939SAndy Fiddaman 			while (*s++);
662*b30d1939SAndy Fiddaman 		}
663*b30d1939SAndy Fiddaman 		else
664*b30d1939SAndy Fiddaman 		{
665*b30d1939SAndy Fiddaman 			ppfsm(FSM_MACRO, b);
666*b30d1939SAndy Fiddaman 			sym->flags = 0;
667*b30d1939SAndy Fiddaman 			if (m & LOAD_FUNCTION) sym->flags |= SYM_FUNCTION;
668*b30d1939SAndy Fiddaman 			if (m & LOAD_MULTILINE) sym->flags |= SYM_MULTILINE;
669*b30d1939SAndy Fiddaman 			if (m & LOAD_NOEXPAND) sym->flags |= SYM_NOEXPAND;
670*b30d1939SAndy Fiddaman 			if (m & LOAD_PREDICATE) sym->flags |= SYM_PREDICATE;
671*b30d1939SAndy Fiddaman 			if (m & LOAD_READONLY) sym->flags |= SYM_READONLY;
672*b30d1939SAndy Fiddaman 			if (m & LOAD_VARIADIC) sym->flags |= SYM_VARIADIC;
673*b30d1939SAndy Fiddaman 			mac = sym->macro = newof(0, struct ppmacro, 1, 0);
674*b30d1939SAndy Fiddaman 			if (sym->flags & SYM_FUNCTION)
675*b30d1939SAndy Fiddaman 			{
676*b30d1939SAndy Fiddaman 				for (n = 0; *s >= '0' && *s <= '9'; n = n * 10 + *s++ - '0');
677*b30d1939SAndy Fiddaman 				if (*s++) error(3, "%-.48: checkpoint macro arity botched", sym->name);
678*b30d1939SAndy Fiddaman 				if (mac->arity = n)
679*b30d1939SAndy Fiddaman 				{
680*b30d1939SAndy Fiddaman 					b = s;
681*b30d1939SAndy Fiddaman 					while (*s++);
682*b30d1939SAndy Fiddaman 					mac->formals = (char*)memcpy(oldof(0, char, 0, s - b), b, s - b);
683*b30d1939SAndy Fiddaman 				}
684*b30d1939SAndy Fiddaman 			}
685*b30d1939SAndy Fiddaman 			b = s;
686*b30d1939SAndy Fiddaman 			while (*s++);
687*b30d1939SAndy Fiddaman 			mac->size = s - b - 1;
688*b30d1939SAndy Fiddaman 			mac->value = (char*)memcpy(oldof(0, char, 0, mac->size + 1), b, mac->size + 1);
689*b30d1939SAndy Fiddaman if (pp.test & 0x1000) error(2, "checkpoint LOAD %s=%s", sym->name, mac->value);
690*b30d1939SAndy Fiddaman 		}
691*b30d1939SAndy Fiddaman 	}
692*b30d1939SAndy Fiddaman 
693*b30d1939SAndy Fiddaman 	/*
694*b30d1939SAndy Fiddaman 	 * we are now at EOF
695*b30d1939SAndy Fiddaman 	 */
696*b30d1939SAndy Fiddaman 
697*b30d1939SAndy Fiddaman 	if (ip)
698*b30d1939SAndy Fiddaman 	{
699*b30d1939SAndy Fiddaman 		pp.in->fd = -1;
700*b30d1939SAndy Fiddaman 		free(ip);
701*b30d1939SAndy Fiddaman 	}
702*b30d1939SAndy Fiddaman #if ARCHIVE
703*b30d1939SAndy Fiddaman 	if (pp.member) pp.member = 0;
704*b30d1939SAndy Fiddaman 	else
705*b30d1939SAndy Fiddaman #endif
706*b30d1939SAndy Fiddaman 	{
707*b30d1939SAndy Fiddaman 		sfclose(sp);
708*b30d1939SAndy Fiddaman 		pp.in->flags |= IN_eof|IN_newline;
709*b30d1939SAndy Fiddaman 		pp.in->nextchr = pp.in->buffer + PPBAKSIZ;
710*b30d1939SAndy Fiddaman 		*pp.in->nextchr++ = 0;
711*b30d1939SAndy Fiddaman 		*pp.in->nextchr = 0;
712*b30d1939SAndy Fiddaman 	}
713*b30d1939SAndy Fiddaman 	pp.mode &= ~LOADING;
714*b30d1939SAndy Fiddaman }
715*b30d1939SAndy Fiddaman 
716*b30d1939SAndy Fiddaman #endif
717