xref: /onnv-gate/usr/src/lib/libpp/common/pplib.h (revision 10898:1883b621b3ea)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*10898Sroland.mainz@nrubsig.org *          Copyright (c) 1986-2009 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                                                                      *
194887Schin ***********************************************************************/
204887Schin #pragma prototyped
214887Schin /*
224887Schin  * Glenn Fowler
234887Schin  * AT&T Research
244887Schin  *
254887Schin  * preprocessor library private definitions
264887Schin  */
274887Schin 
284887Schin #ifndef _PPLIB_H
294887Schin #define _PPLIB_H
304887Schin 
314887Schin /*
324887Schin  * the first definitions control optional code -- 0 disables
334887Schin  */
344887Schin 
354887Schin #ifndef ARCHIVE
364887Schin #define ARCHIVE		1	/* -I can specify header archives	*/
374887Schin #endif
384887Schin #ifndef CATSTRINGS
394887Schin #define CATSTRINGS	1	/* concatenate adjacent strings		*/
404887Schin #endif
414887Schin #ifndef CHECKPOINT
424887Schin #define CHECKPOINT	1	/* checkpoint preprocessed files	*/
434887Schin #endif
444887Schin #ifndef COMPATIBLE
454887Schin #define COMPATIBLE	1	/* enable COMPATIBILITY related code	*/
464887Schin #endif
474887Schin #ifndef MACKEYARGS
484887Schin #define MACKEYARGS 	_BLD_DEBUG /* name=value macro formals and actuals */
494887Schin #endif
504887Schin #ifndef POOL
514887Schin #define POOL		1	/* enable loop on input,output,error	*/
524887Schin #endif
534887Schin #ifndef PROTOTYPE
544887Schin #define PROTOTYPE	1	/* enable ppproto code			*/
554887Schin #endif
564887Schin 
574887Schin #define TRUNCLENGTH	8	/* default TRUNCATE length		*/
584887Schin 
594887Schin #if _BLD_DEBUG
604887Schin #undef	DEBUG
614887Schin #define DEBUG		(TRACE_message|TRACE_count|TRACE_debug)
624887Schin #else
634887Schin #ifndef DEBUG
644887Schin #define DEBUG		(TRACE_message)
654887Schin #endif
664887Schin #endif
674887Schin 
684887Schin /*
694887Schin  * the lower tests are transient
704887Schin  */
714887Schin 
724887Schin #define TEST_count		(1L<<24)
734887Schin #define TEST_hashcount		(1L<<25)
744887Schin #define TEST_hashdump		(1L<<26)
754887Schin #define TEST_hit		(1L<<27)
764887Schin #define TEST_noinit		(1L<<28)
774887Schin #define TEST_nonoise		(1L<<29)
784887Schin #define TEST_noproto		(1L<<30)
794887Schin 
804887Schin #define TEST_INVERT		(1L<<31)
814887Schin 
824887Schin #define PROTO_CLASSIC		(1<<0)	/* classic to prototyped	*/
834887Schin #define PROTO_DISABLE		(1<<1)	/* disable conversion		*/
844887Schin #define PROTO_EXTERNALIZE	(1<<2)	/* static fun() => extern fun()	*/
854887Schin #define PROTO_FORCE		(1<<3)	/* force even if no magic	*/
864887Schin #define PROTO_HEADER		(1<<4)	/* header defines too		*/
874887Schin #define PROTO_INCLUDE		(1<<5)	/* <prototyped.h> instead	*/
884887Schin #define PROTO_INITIALIZED	(1<<6)	/* internal initialization	*/
894887Schin #define PROTO_LINESYNC		(1<<7)	/* force standalone line syncs	*/
904887Schin #define PROTO_NOPRAGMA		(1<<8)	/* delete pragma prototyped	*/
914887Schin #define PROTO_PASS		(1<<9)	/* pass blocks if no magic	*/
924887Schin #define PROTO_PLUSPLUS		(1<<10)	/* extern () -> extern (...)	*/
934887Schin #define PROTO_RETAIN		(1<<11)	/* defines retained after close	*/
944887Schin #define PROTO_TEST		(1<<12)	/* enable test code		*/
954887Schin 
964887Schin #define PROTO_USER		(1<<13)	/* first user flag		*/
974887Schin 
984887Schin #define SEARCH_EXISTS		0	/* ppsearch for existence	*/
994887Schin #define SEARCH_HOSTED		(1<<0)	/* search hosted dirs only	*/
1004887Schin #define SEARCH_IGNORE		(1<<1)	/* ignore if not found		*/
1014887Schin #define SEARCH_INCLUDE		(1<<2)	/* ppsearch for include		*/
1024887Schin #define SEARCH_VENDOR		(1<<3)	/* search vendor dirs only	*/
1034887Schin #define SEARCH_USER		(1<<4)	/* first user flag		*/
1044887Schin 
1054887Schin #define STYLE_gnu		(1<<0)	/* gnu style args		*/
1064887Schin 
1074887Schin #define IN_c			(1<<0)	/* C language file		*/
1084887Schin #define IN_defguard		(1<<1)	/* did multiple include check	*/
1094887Schin #define IN_disable		(1<<2)	/* saved state&DISABLE		*/
1104887Schin #define IN_endguard		(1<<3)	/* did multiple include check	*/
1114887Schin #define IN_eof			(1<<4)	/* reached EOF			*/
1124887Schin #define IN_expand		(1<<5)	/* ppexpand buffer		*/
1134887Schin #define IN_flush		(1<<6)	/* flush stdout on file_refill()*/
1144887Schin #define IN_hosted		(1<<7)	/* saved mode&HOSTED		*/
1154887Schin #define IN_ignoreline		(1<<8)	/* ignore #line until file	*/
1164887Schin #define IN_newline		(1<<9)	/* newline at end of last fill	*/
1174887Schin #define IN_noguard		(1<<10)	/* no multiple include guard	*/
1184887Schin #define IN_prototype		(1<<11)	/* ppproto() input		*/
1194887Schin #define IN_regular		(1<<12)	/* regular input file		*/
1204887Schin #define IN_static		(1<<13)	/* static buffer - don't free	*/
1214887Schin #define IN_sync			(1<<14)	/* line sync required on pop	*/
1224887Schin #define IN_tokens		(1L<<15)/* non-space tokens encountered	*/
1234887Schin 
1244887Schin #define OPT_GLOBAL		(1<<0)	/* pp: pass optional		*/
1254887Schin #define OPT_PASS		(1<<1)	/* pass on			*/
1264887Schin 
1274887Schin struct ppsymbol;
1284887Schin struct ppindex;
1294887Schin 
1304887Schin typedef char*	(*PPBUILTIN)(char*, const char*, const char*);
1314887Schin typedef void	(*PPCOMMENT)(const char*, const char*, const char*, int);
1324887Schin typedef void	(*PPINCREF)(const char*, const char*, int, int);
1334887Schin typedef void	(*PPLINESYNC)(int, const char*);
1344887Schin typedef void	(*PPMACREF)(struct ppsymbol*, const char*, int, int, unsigned long);
1354887Schin typedef int	(*PPOPTARG)(int, int, const char*);
1364887Schin typedef void	(*PPPRAGMA)(const char*, const char*, const char*, const char*, int);
1374887Schin 
1384887Schin struct ppinstk				/* input stream stack frame	*/
1394887Schin {
1404887Schin 	char*		nextchr;	/* next input char (first elt)	*/
1414887Schin 	struct ppinstk*	next;		/* next frame (for allocation)	*/
1424887Schin 	struct ppinstk*	prev;		/* previous frame		*/
1434887Schin 	long*		control;	/* control block level		*/
1444887Schin 	char*		buffer;		/* buffer base pointer		*/
1454887Schin 	char*		file;		/* saved file name		*/
1464887Schin 	char*		prefix;		/* directory prefix		*/
1474887Schin 	struct ppsymbol* symbol;	/* macro info			*/
1484887Schin #if CHECKPOINT
1494887Schin 	struct ppindex*	index;		/* checkpoint include index	*/
1504887Schin 	int		buflen;		/* buffer count			*/
1514887Schin #endif
1524887Schin 	int		line;		/* saved line number		*/
1534887Schin 	int		vendor;		/* saved pp.vendor		*/
1544887Schin 	short		fd;		/* file descriptor		*/
1554887Schin 	short		hide;		/* hide index (from pp.hide)	*/
1564887Schin 	short		flags;		/* IN_[a-z]* flags		*/
1574887Schin 	char		type;		/* input type			*/
1584887Schin };
1594887Schin 
1604887Schin #if MACKEYARGS
1614887Schin struct ppkeyarg				/* pp macro keyword arg info	*/
1624887Schin {
1634887Schin 	char*		name;		/* keyword arg name		*/
1644887Schin 	char*		value;		/* keyword arg value		*/
1654887Schin };
1664887Schin #endif
1674887Schin 
1684887Schin struct pplist				/* string list			*/
1694887Schin {
1704887Schin 	char*		value;		/* string value			*/
1714887Schin 	struct pplist*	next;		/* next in list			*/
1724887Schin };
1734887Schin 
1744887Schin struct oplist				/* queue op until PP_INIT	*/
1754887Schin {
1764887Schin 	int		op;		/* PP_* op			*/
1774887Schin 	char*		value;		/* op value			*/
1784887Schin 	struct oplist*	next;		/* next op			*/
1794887Schin };
1804887Schin 
1814887Schin struct pphide				/* hidden symbol info		*/
1824887Schin {
1834887Schin 	struct ppmacro*	macro;		/* saved macro info		*/
1844887Schin 	unsigned long	flags;		/* saved symbol flags if macro	*/
1854887Schin 	int		level;		/* nesting level		*/
1864887Schin };
1874887Schin 
1884887Schin struct ppmacstk				/* macro invocation stack frame	*/
1894887Schin {
1904887Schin 	struct ppmacstk* next;		/* next frame (for allocation)	*/
1914887Schin 	struct ppmacstk* prev;		/* previous frame		*/
1924887Schin 	int		line;		/* line number of first arg	*/
1934887Schin 	char*		arg[1];		/* arg text pointers		*/
1944887Schin };
1954887Schin 
1964887Schin struct ppmember				/* archive member pun on ppfile	*/
1974887Schin {
1984887Schin 	struct ppdirs*	archive;	/* archive holding file		*/
1994887Schin 	unsigned long	offset;		/* data offset			*/
2004887Schin 	unsigned long	size;		/* data size			*/
2014887Schin };
2024887Schin 
2034887Schin struct counter				/* monitoring counters		*/
2044887Schin {
2054887Schin 	int		candidate;	/* macro candidates		*/
2064887Schin 	int		function;	/* function macros		*/
2074887Schin 	int		macro;		/* macro hits			*/
2084887Schin 	int		pplex;		/* pplex() calls		*/
2094887Schin 	int		push;		/* input stream pushes		*/
2104887Schin 	int		terminal;	/* terminal states		*/
2114887Schin 	int		token;		/* emitted tokens		*/
2124887Schin };
2134887Schin 
2144887Schin struct pptuple				/* tuple macro			*/
2154887Schin {
2164887Schin 	struct pptuple*	nomatch;	/* nomatch tuple		*/
2174887Schin 	struct pptuple*	match;		/* match tuple			*/
2184887Schin 	char		token[1];	/* matching token		*/
2194887Schin };
2204887Schin 
2214887Schin struct ppfileid				/* physical file id		*/
2224887Schin {
2234887Schin 	unsigned long	st_dev;		/* dev				*/
2244887Schin 	unsigned long	st_ino;		/* ino				*/
2254887Schin };
2264887Schin 
2274887Schin struct pathid				/* physical file name and id	*/
2284887Schin {
2294887Schin 	char*		path;		/* file path			*/
2304887Schin 	struct ppfileid	id;		/* file id			*/
2314887Schin };
2324887Schin 
2334887Schin #define SAMEID(a,b)	((a)->st_ino==(unsigned long)(b)->st_ino&&(a)->st_dev==(unsigned long)(b)->st_dev)
2344887Schin #define SAVEID(a,b)	((a)->st_ino=(unsigned long)(b)->st_ino,(a)->st_dev=(unsigned long)(b)->st_dev)
2354887Schin 
2364887Schin #define _PP_CONTEXT_PRIVATE_		/* ppglobals private context	*/ \
2374887Schin 	struct ppcontext* context;	/* current context		*/ \
2384887Schin 	long		state;		/* pp state flags		*/ \
2394887Schin 	long		mode;		/* uncoupled pp state flags	*/ \
2404887Schin 	long		option;		/* option flags			*/ \
2414887Schin 	long		test;		/* implementation tests		*/ \
2424887Schin 	struct								   \
2434887Schin 	{								   \
2444887Schin 	Sfio_t*		sp;		/* FILEDEPS output stream	*/ \
2454887Schin 	long		flags;		/* PP_FILEDEPS flags		*/ \
2464887Schin 	}		filedeps;	/* FILEDEPS info		*/ \
2474887Schin 	struct ppdirs*	firstdir;	/* first include dir		*/ \
2484887Schin 	struct ppdirs*	lastdir;	/* last include dir		*/ \
2494887Schin 	int		hide;		/* current include hide index	*/ \
2504887Schin 	int		column;		/* FILEDEPS column		*/ \
2514887Schin 	int		pending;	/* ppline() pending output	*/ \
2524887Schin 	char*		firstfile;	/* ppline() first file		*/ \
2534887Schin 	char*		lastfile;	/* ppline() most recent file	*/ \
2544887Schin 	char*		ignore;		/* include ignore list file	*/ \
2554887Schin 	char*		probe;		/* ppdefault probe key		*/ \
2564887Schin 	Hash_table_t*	filtab;		/* file name hash table		*/ \
2574887Schin 	Hash_table_t*	prdtab;		/* predicate hash table		*/ \
2584887Schin 	char*		date;		/* start date string		*/ \
2594887Schin 	char*		time;		/* start time string		*/ \
2604887Schin 	char*		maps;		/* directive maps		*/ \
2614887Schin 	long		ro_state;	/* readonly state		*/ \
2624887Schin 	long		ro_mode;	/* readonly mode		*/ \
2634887Schin 	long		ro_option;	/* readonly option		*/ \
2644887Schin 	struct pathid	cdir;		/* arg C dir			*/ \
2654887Schin 	struct pathid	hostdir;	/* arg host dir			*/ \
2664887Schin 	char*		ppdefault;	/* arg default info file	*/ \
2674887Schin 	struct ppindex*	firstindex;	/* first include index entry	*/ \
2684887Schin 	struct ppindex*	lastindex;	/* last include index entry	*/ \
2694887Schin 	struct oplist*	firstop;	/* first arg op			*/ \
2704887Schin 	struct oplist*	lastop;		/* last arg op			*/ \
2714887Schin 	struct oplist*	firsttx;	/* first text file		*/ \
2724887Schin 	struct oplist*	lasttx;		/* last text file		*/ \
2734887Schin 	unsigned char	arg_file;	/* arg file index		*/ \
2744887Schin 	unsigned char	arg_mode;	/* arg mode			*/ \
2754887Schin 	unsigned char	arg_style;	/* arg style			*/ \
2764887Schin 	unsigned char	c;		/* arg C state			*/ \
2774887Schin 	unsigned char	hosted;		/* arg hosted state		*/ \
2784887Schin 	unsigned char	ignoresrc;	/* arg ignore source state	*/ \
2794887Schin 	unsigned char	initialized;	/* arg initialized state	*/ \
2804887Schin 	unsigned char	standalone;	/* arg standalone state		*/ \
2814887Schin 	unsigned char	spare_1;	/* padding spare		*/
2824887Schin 
2834887Schin #define _PP_GLOBALS_PRIVATE_		/* ppglobals private additions	*/ \
2844887Schin 	char*		checkpoint;	/* checkpoint version		*/ \
2854887Schin 	int		constack;	/* pp.control size		*/ \
2864887Schin 	struct ppinstk*	in;		/* input stream stack pointer	*/ \
2874887Schin 	char*		addp;	    	/* addbuf pointer		*/ \
2884887Schin 	char*		args;		/* predicate args		*/ \
2894887Schin 	char*		addbuf;		/* ADD buffer			*/ \
2904887Schin 	char*		catbuf;		/* catenation buffer		*/ \
2914887Schin 	char*		hdrbuf;		/* HEADEREXPAND buffer		*/ \
2924887Schin 	char*		hidebuf;	/* pp:hide buffer		*/ \
2934887Schin 	char*		path;		/* full path of last #include	*/ \
2944887Schin 	char*		tmpbuf;		/* very temporary buffer	*/ \
2954887Schin 	char*		valbuf;		/* builtin macro value buffer	*/ \
2964887Schin 	char*		optflags;	/* OPT_* flags indexed by X_*	*/ \
2974887Schin 	int		lastout;	/* last output char		*/ \
2984887Schin 		/* the rest are implicitly initialized */ \
2994887Schin 	char*		include;	/* saved path of last #include	*/ \
3004887Schin 	char*		prefix;		/* current directory prefix	*/ \
3014887Schin 	struct ppmember* member;	/* include archive member data	*/ \
3024887Schin 	int		hidden;		/* hidden newline count		*/ \
3034887Schin 	int		hiding;		/* number of symbols in hiding	*/ \
3044887Schin 	int		level;		/* pplex() recursion level	*/ \
3054887Schin 	struct								   \
3064887Schin 	{								   \
3074887Schin 	int		input;		/* pool input			*/ \
3084887Schin 	int		output;		/* pool output			*/ \
3094887Schin 	}		pool;		/* loop on input,output,error	*/ \
3104887Schin 	struct								   \
3114887Schin 	{								   \
3124887Schin 	long		ro_state;	/* original pp.ro_state		*/ \
3134887Schin 	long		ro_mode;	/* original pp.ro_mode		*/ \
3144887Schin 	long		ro_option;	/* original pp.ro_option	*/ \
3154887Schin 	int		on;		/* PP_RESET enabled		*/ \
3164887Schin 	Hash_table_t*	symtab;		/* original pp.symtab scope	*/ \
3174887Schin 	}		reset;		/* PP_RESET state		*/ \
3184887Schin 	int		truncate;	/* identifier truncation length	*/ \
3194887Schin 	struct ppmacstk* macp;		/* top of macro actual stack	*/ \
3204887Schin 	char*		maxmac;		/* maximum size of macro stack	*/ \
3214887Schin 	char*		mactop;		/* top of current macro frame	*/ \
3224887Schin 	char*		toknxt;		/* '\0' of pp.token		*/ \
3234887Schin 	long*		control;	/* control block flags pointer	*/ \
3244887Schin 	long*		maxcon;		/* max control block frame	*/ \
3254887Schin 	struct oplist*	chop;		/* include prefix chop list	*/ \
3264887Schin 	struct ppfile*	insert;		/* inserted line sync file	*/ \
3274887Schin 	struct ppfile*	original;	/* original include name	*/ \
3284887Schin 	struct ppdirs*	found;		/* last successful ppsearch dir	*/ \
3294887Schin 	int		vendor;		/* vendor includes only		*/ \
3304887Schin 	Hash_table_t*	dirtab;		/* directive hash table		*/ \
3314887Schin 	Hash_table_t*	strtab;		/* string hash table		*/ \
3324887Schin 	PPBUILTIN	builtin;	/* builtin macro handler	*/ \
3334887Schin 	PPCOMMENT	comment;	/* pass along comments		*/ \
3344887Schin 	PPINCREF	incref;		/* include file push/return	*/ \
3354887Schin 	PPLINESYNC	linesync;	/* pass along line sync info	*/ \
3364887Schin 	PPLINESYNC	olinesync;	/* original linesync value	*/ \
3374887Schin 	PPMACREF	macref;		/* called on macro def/ref	*/ \
3384887Schin 	PPOPTARG	optarg;		/* unknown option arg handler	*/ \
3394887Schin 	PPPRAGMA	pragma;		/* pass along unknown pragmas	*/ \
3404887Schin 	struct counter	counter;	/* monitoring counters		*/ \
3414887Schin 	char		funbuf[256];	/* last __FUNCTION__		*/
3424887Schin 
3434887Schin #define _PP_SYMBOL_PRIVATE_		/* ppsymbol private additions	*/ \
3444887Schin 	struct pphide*	hidden;		/* hidden symbol info		*/
3454887Schin 
3464887Schin #if MACKEYARGS
3474887Schin #define _PP_MACRO_PRIVATE_		/* ppmacro private additions	*/ \
3484887Schin 	struct pptuple*	tuple;		/* tuple macro			*/ \
3494887Schin 	union								   \
3504887Schin 	{								   \
3514887Schin 	char*		formal;		/* normal formals list		*/ \
3524887Schin 	struct ppkeyarg* key;		/* keyword formals table	*/ \
3534887Schin 	}		args;		/* macro args info		*/ \
3544887Schin 	int		size;		/* body size			*/
3554887Schin #define formals		args.formal	/* formal argument list		*/
3564887Schin #define formkeys	args.key	/* formal keyword argument list	*/
3574887Schin #else
3584887Schin #define _PP_MACRO_PRIVATE_		/* ppmacro private additions	*/ \
3594887Schin 	struct pptuple*	tuple;		/* tuple macro			*/ \
3604887Schin 	char*		formals;	/* formal argument list		*/ \
3614887Schin 	int		size;		/* body size			*/
3624887Schin #endif
3634887Schin 
3644887Schin #define _PP_DIRS_PRIVATE_		/* ppdirs private additions	*/ \
3654887Schin 	unsigned char	c;		/* files here are C language	*/ \
3664887Schin 	unsigned char	index;		/* prefix,local,standard index	*/ \
3674887Schin 	unsigned char	type;		/* dir type			*/ \
3684887Schin 	union								   \
3694887Schin 	{								   \
3704887Schin 	char*		buffer;		/* TYPE_BUFFER buffer		*/ \
3714887Schin 	Sfio_t*		sp;		/* archive stream		*/ \
3724887Schin 	struct ppdirs*	subdir;		/* subdir list			*/ \
3734887Schin 	}		info;		/* type info			*/ \
3744887Schin 	struct ppfileid	id;		/* directory id			*/ \
3754887Schin 
3764887Schin #if !PROTOMAIN
3774887Schin #include <ast.h>
3784887Schin #include <error.h>
3794887Schin #endif
3804887Schin 
3814887Schin #undef	newof
3824887Schin #define newof(p,t,n,x)	((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
3834887Schin 
3844887Schin #include "pp.h"
3854887Schin #include "ppdef.h"
3864887Schin #include "ppkey.h"
3874887Schin 
3884887Schin #undef	setstate			/* random clash!		*/
3894887Schin 
3904887Schin /*
3914887Schin  * DEBUG is encoded with the following bits
3924887Schin  */
3934887Schin 
3944887Schin #define TRACE_message		01
3954887Schin #define TRACE_count		02
3964887Schin #define TRACE_debug		04
3974887Schin 
3984887Schin #if DEBUG && !lint
3994887Schin #define	PANIC		(ERROR_PANIC|ERROR_SOURCE|ERROR_SYSTEM),__FILE__,__LINE__
4004887Schin #else
4014887Schin #define	PANIC		ERROR_PANIC
4024887Schin #endif
4034887Schin 
4044887Schin #if DEBUG & TRACE_count
4054887Schin #define count(x)	pp.counter.x++
4064887Schin #else
4074887Schin #define count(x)
4084887Schin #endif
4094887Schin 
4104887Schin #if DEBUG & TRACE_message
4114887Schin #define message(x)	do { if (tracing) error x; } while (0)
4124887Schin #else
4134887Schin #define message(x)
4144887Schin #endif
4154887Schin 
4164887Schin #if DEBUG & TRACE_debug
4174887Schin #define debug(x)	do { if (tracing) error x; } while (0)
4184887Schin #else
4194887Schin #define debug(x)
4204887Schin #endif
4214887Schin 
4224887Schin /*
4234887Schin  * note that MEMCPY advances the associated pointers
4244887Schin  */
4254887Schin 
4264887Schin #define MEMCPY(to,fr,n) \
4274887Schin 	do switch(n) \
4284887Schin 	{ default : memcpy(to,fr,n); to += n; fr += n; break; \
4294887Schin 	  case  7 : *to++ = *fr++; \
4304887Schin 	  case  6 : *to++ = *fr++; \
4314887Schin 	  case  5 : *to++ = *fr++; \
4324887Schin 	  case  4 : *to++ = *fr++; \
4334887Schin 	  case  3 : *to++ = *fr++; \
4344887Schin 	  case  2 : *to++ = *fr++; \
4354887Schin 	  case  1 : *to++ = *fr++; \
4364887Schin 	  case  0 : break; \
4374887Schin 	} while (0)
4384887Schin 
4394887Schin #define NEWDIRECTIVE	(-1)
4404887Schin 
4414887Schin #undef	dirname
4424887Schin #undef	error
4434887Schin 
4444887Schin #define dirname(x)	ppkeyname(x,1)
4454887Schin #define error		pperror
4464887Schin #define keyname(x)	ppkeyname(x,0)
4474887Schin #define nextframe(m,p)	(m->next=m+(p-(char*)m+sizeof(struct ppmacstk)-1)/sizeof(struct ppmacstk)+1)
4484887Schin #define popframe(m)	(m=m->prev)
4494887Schin #define pptokchr(c)	pptokstr(NiL,(c))
4504887Schin #define pushcontrol()	do { if (pp.control++ >= pp.maxcon) ppnest(); } while (0)
4514887Schin #define pushframe(m)	(m->next->prev=m,m=m->next)
4524887Schin #define setmode(m,v)	((v)?(pp.mode|=(m)):(pp.mode&=~(m)))
4534887Schin #define setoption(m,v)	((v)?(pp.option|=(m)):(pp.option&=~(m)))
4544887Schin #define setstate(s,v)	((v)?(pp.state|=(s)):(pp.state&=~(s)))
4554887Schin #define tracing		(error_info.trace<0)
4564887Schin 
4574887Schin #define ppgetfile(x)	((struct ppfile*)hashlook(pp.filtab,x,HASH_LOOKUP,NiL))
4584887Schin #define ppsetfile(x)	((struct ppfile*)hashlook(pp.filtab,x,HASH_CREATE|HASH_SIZE(sizeof(struct ppfile)),NiL))
4594887Schin 
4604887Schin #define ppkeyget(t,n)	(struct ppsymkey*)hashlook(t,n,HASH_LOOKUP,NiL)
4614887Schin #define ppkeyref(t,n)	(struct ppsymkey*)hashlook(t,n,HASH_LOOKUP|HASH_INTERNAL,NiL)
4624887Schin #define ppkeyset(t,n)	(struct ppsymkey*)hashlook(t,n,HASH_CREATE|HASH_SIZE(sizeof(struct ppsymkey)),NiL)
4634887Schin 
4644887Schin #define MARK		'@'		/* internal mark		*/
4654887Schin #define ARGOFFSET	'1'		/* macro arg mark offset	*/
4664887Schin 
4674887Schin #define STRAPP(p,v,r)	do{r=(v);while((*p++)=(*r++));}while(0)
4684887Schin #define STRCOPY(p,v,r)	do{r=(v);while((*p++)=(*r++));p--;}while(0)
4694887Schin #define STRCOPY2(p,r)	do{while((*p++)=(*r++));p--;}while(0)
4704887Schin 
4714887Schin #define SETFILE(p,v)	(p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'F',(long)v,MARK))
4724887Schin #define SETLINE(p,v)	(p+=sfsprintf(p,16,"%c%c%lx%c",MARK,'L',(long)v,MARK))
4734887Schin 
4744887Schin #define peekchr()	(*pp.in->nextchr)
4754887Schin #define ungetchr(c)	(*--pp.in->nextchr=(c))
4764887Schin 
4774887Schin #define MAXID		255		/* maximum identifier size	*/
4784887Schin #define MAXTOKEN	PPTOKSIZ	/* maximum token size		*/
4794887Schin #define MAXFORMALS	64		/* maximum number macro formals	*/
4804887Schin #define MAXHIDDEN	8		/* ppline if hidden>=MAXHIDDEN	*/
4814887Schin #define DEFMACSTACK	(MAXFORMALS*32*32)/* default macstack size	*/
4824887Schin 
4834887Schin #define FSM_COMPATIBILITY	1	/* compatibility mode		*/
4844887Schin #define FSM_IDADD	2		/* add to identifer set		*/
4854887Schin #define FSM_IDDEL	3		/* delete from identifer set	*/
4864887Schin #define FSM_INIT	4		/* initilize			*/
4874887Schin #define FSM_MACRO	5		/* add new macro		*/
4884887Schin #define FSM_OPSPACE	6		/* handle <binop><space>=	*/
4894887Schin #define FSM_PLUSPLUS	7		/* C++ lexical analysis		*/
4904887Schin #define FSM_QUOTADD	8		/* add to quote set		*/
4914887Schin #define FSM_QUOTDEL	9		/* delete from quote set	*/
4924887Schin 
4934887Schin #define IN_TOP		01		/* top level -- directives ok	*/
4944887Schin 
4954887Schin #define IN_BUFFER	(2|IN_TOP)	/* buffer of lines		*/
4964887Schin #define IN_COPY		2		/* macro arg (copied)		*/
4974887Schin #define IN_EXPAND	4		/* macro arg (expanded)		*/
4984887Schin #define IN_FILE		(4|IN_TOP)	/* file				*/
4994887Schin #define IN_INIT		(6|IN_TOP)	/* initialization IN_BUFFER	*/
5004887Schin #define IN_MACRO	8		/* macro text			*/
5014887Schin #define IN_MULTILINE	(8|IN_TOP)	/* multi-line macro text	*/
5024887Schin #define IN_QUOTE	10		/* "..." macro arg (copied)	*/
5034887Schin #define IN_RESCAN	(10|IN_TOP)	/* directive rescan buffer	*/
5044887Schin #define IN_SQUOTE	12		/* '...' macro arg (copied)	*/
5054887Schin #define IN_STRING	14		/* string			*/
5064887Schin 
5074887Schin #define INC_CLEAR	((struct ppsymbol*)0)
5084887Schin #define INC_IGNORE	((struct ppsymbol*)pp.addbuf)
5094887Schin #define INC_TEST	((struct ppsymbol*)pp.catbuf)
5104887Schin 
5114887Schin #define INC_BOUND(n)	(1<<(n))
5124887Schin #define INC_MEMBER(n)	(1<<((n)+INC_MAX))
5134887Schin #define INC_PREFIX	0
5144887Schin #define INC_LOCAL	1
5154887Schin #define INC_STANDARD	2
5164887Schin #define INC_VENDOR	3
5174887Schin #define INC_MAX		4
5184887Schin #define INC_SELF	(1<<(2*INC_MAX+0))
5194887Schin #define INC_EXISTS	(1<<(2*INC_MAX+1))
5204887Schin #define INC_LISTED	(1<<(2*INC_MAX+2))
5214887Schin #define INC_MAPALL	(1<<(2*INC_MAX+3))
5224887Schin #define INC_MAPHOSTED	(1<<(2*INC_MAX+4))
5234887Schin #define INC_MAPNOHOSTED	(1<<(2*INC_MAX+5))
5244887Schin #define INC_MAPNOLOCAL	(1<<(2*INC_MAX+6))
5254887Schin #define INC_HOSTED	(1<<(2*INC_MAX+7))
5264887Schin 
5274887Schin #define TYPE_ARCHIVE	(1<<0)
5284887Schin #define TYPE_BUFFER	(1<<1)
5294887Schin #define TYPE_CHECKPOINT	(1<<2)
5304887Schin #define TYPE_DIRECTORY	(1<<3)
5314887Schin #define TYPE_HOSTED	(1<<4)
5324887Schin #define TYPE_INCLUDE	(1<<5)
5334887Schin #define TYPE_VENDOR	(1<<6)
5344887Schin 
5354887Schin #define TOK_BUILTIN	(1<<0)		/* last token was #(		*/
5364887Schin #define TOK_FORMAL	(1<<1)		/* last token was arg formal id	*/
5374887Schin #define TOK_ID		(1<<2)		/* last token was identifier	*/
5384887Schin #define TOK_TOKCAT	(1<<3)		/* last token was ##		*/
5394887Schin 
5404887Schin #define HADELSE		(1<<0)		/* already had else part	*/
5414887Schin #define KEPT		(1<<1)		/* already kept part of block	*/
5424887Schin #define SKIP		(1<<2)		/* skip this block		*/
5434887Schin #define BLOCKBITS	3		/* block flag bits		*/
5444887Schin 
5454887Schin #define SETIFBLOCK(p)	(*(p)=(*((p)-1)&SKIP)|((long)error_info.line<<BLOCKBITS))
5464887Schin #define GETIFLINE(p)	((*(p)>>BLOCKBITS)&((1L<<(sizeof(long)*CHAR_BIT-BLOCKBITS))-1))
5474887Schin 
5484887Schin #define PUSH(t,p)		\
5494887Schin 	do \
5504887Schin 	{ \
5514887Schin 		count(push); \
5524887Schin 		if (!pp.in->next) \
5534887Schin 		{ \
5544887Schin 			pp.in->next = newof(0, struct ppinstk, 1, 0); \
5554887Schin 			pp.in->next->prev = pp.in; \
5564887Schin 		} \
5574887Schin 		p = pp.in = pp.in->next; \
5584887Schin 		p->type = t; \
5594887Schin 		p->flags = 0; \
5604887Schin 	} while (0)
5614887Schin 
5624887Schin #define PUSH_BUFFER(f,p,n)		\
5634887Schin 	pppush(IN_BUFFER,f,p,n)
5644887Schin 
5654887Schin #define PUSH_COPY(p,n)		\
5664887Schin 	do \
5674887Schin 	{ \
5684887Schin 		register struct ppinstk*	cur; \
5694887Schin 		PUSH(IN_COPY, cur); \
5704887Schin 		cur->line = error_info.line; \
5714887Schin 		error_info.line = n; \
5724887Schin 		cur->nextchr = p; \
5734887Schin 		cur->prev->symbol->flags &= ~SYM_DISABLED; \
5744887Schin 		debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
5754887Schin 	} while (0)
5764887Schin 
5774887Schin #define PUSH_EXPAND(p,n)	\
5784887Schin 	do \
5794887Schin 	{ \
5804887Schin 		register struct ppinstk*	cur; \
5814887Schin 		PUSH(IN_EXPAND, cur); \
5824887Schin 		cur->line = error_info.line; \
5834887Schin 		error_info.line = n; \
5844887Schin 		cur->prev->symbol->flags &= ~SYM_DISABLED; \
5854887Schin 		cur->buffer = cur->nextchr = ppexpand(p); \
5864887Schin 		if (!(cur->prev->symbol->flags & SYM_MULTILINE)) \
5874887Schin 			cur->prev->symbol->flags |= SYM_DISABLED; \
5884887Schin 		debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
5894887Schin 	} while (0)
5904887Schin 
5914887Schin #define PUSH_FILE(f,d)	\
5924887Schin 	pppush(IN_FILE,f,NiL,d)
5934887Schin 
5944887Schin #define PUSH_INIT(f,p)	\
5954887Schin 	pppush(IN_INIT,f,p,1)
5964887Schin 
5974887Schin #define PUSH_MACRO(p)		\
5984887Schin 	do \
5994887Schin 	{ \
6004887Schin 		register struct ppinstk*	cur; \
6014887Schin 		PUSH(IN_MACRO, cur); \
6024887Schin 		cur->symbol = p; \
6034887Schin 		cur->nextchr = p->macro->value; \
6044887Schin 		p->flags |= SYM_DISABLED; \
6054887Schin 		if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \
6064887Schin 		pp.state &= ~NEWLINE; \
6074887Schin 		debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
6084887Schin 	} while (0)
6094887Schin 
6104887Schin #define PUSH_TUPLE(p,v)		\
6114887Schin 	do \
6124887Schin 	{ \
6134887Schin 		register struct ppinstk*	cur; \
6144887Schin 		PUSH(IN_MACRO, cur); \
6154887Schin 		cur->symbol = p; \
6164887Schin 		cur->nextchr = v; \
6174887Schin 		p->flags |= SYM_DISABLED; \
6184887Schin 		pp.state &= ~NEWLINE; \
6194887Schin 		debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
6204887Schin 	} while (0)
6214887Schin 
6224887Schin #define PUSH_MULTILINE(p)		\
6234887Schin 	do \
6244887Schin 	{ \
6254887Schin 		register struct ppinstk*	cur; \
6264887Schin 		register int			n; \
6274887Schin 		PUSH(IN_MULTILINE, cur); \
6284887Schin 		cur->symbol = p; \
6294887Schin 		cur->flags |= IN_defguard|IN_endguard|IN_noguard; \
6304887Schin 		pushcontrol(); \
6314887Schin 		cur->control = pp.control; \
6324887Schin 		*pp.control = 0; \
6334887Schin 		cur->file = error_info.file; \
6344887Schin 		n = strlen(error_info.file) + strlen(((struct ppsymbol*)p)->name) + 24; \
6354887Schin 		error_info.file = cur->buffer = newof(0, char, n, 0); \
6364887Schin 		sfsprintf(error_info.file, n, "%s:%s,%d", cur->file, p->name, error_info.line); \
6374887Schin 		cur->line = error_info.line; \
6384887Schin 		error_info.line = 1; \
6394887Schin 		cur->nextchr = p->macro->value; \
6404887Schin 		if (p->flags & SYM_FUNCTION) pushframe(pp.macp); \
6414887Schin 		pp.state &= ~NEWLINE; \
6424887Schin 		debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
6434887Schin 	} while (0)
6444887Schin 
6454887Schin #define PUSH_QUOTE(p,n)		\
6464887Schin 	do \
6474887Schin 	{ \
6484887Schin 		register struct ppinstk*	cur; \
6494887Schin 		PUSH(IN_QUOTE, cur); \
6504887Schin 		cur->nextchr = p; \
6514887Schin 		pp.state |= QUOTE; \
6524887Schin 		cur->line = error_info.line; \
6534887Schin 		error_info.line = n; \
6544887Schin 		debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
6554887Schin 	} while (0)
6564887Schin 
6574887Schin #define PUSH_RESCAN(p)	\
6584887Schin 	pppush(IN_RESCAN,NiL,p,0)
6594887Schin 
6604887Schin #define PUSH_SQUOTE(p,n)	\
6614887Schin 	do \
6624887Schin 	{ \
6634887Schin 		register struct ppinstk*	cur; \
6644887Schin 		PUSH(IN_SQUOTE, cur); \
6654887Schin 		cur->nextchr = p; \
6664887Schin 		pp.state |= SQUOTE; \
6674887Schin 		cur->line = error_info.line; \
6684887Schin 		error_info.line = n; \
6694887Schin 		debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
6704887Schin 	} while (0)
6714887Schin 
6724887Schin #define PUSH_STRING(p)		\
6734887Schin 	do \
6744887Schin 	{ \
6754887Schin 		register struct ppinstk*	cur; \
6764887Schin 		PUSH(IN_STRING, cur); \
6774887Schin 		cur->nextchr = p; \
6784887Schin 		if (pp.state & DISABLE) cur->flags |= IN_disable; \
6794887Schin 		debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
6804887Schin 	} while (0)
6814887Schin 
6824887Schin #define PUSH_LINE(p)		\
6834887Schin 	do \
6844887Schin 	{ \
6854887Schin 		register struct ppinstk*	cur; \
6864887Schin 		PUSH(IN_STRING, cur); \
6874887Schin 		cur->nextchr = p; \
6884887Schin 		pp.state |= DISABLE|NOSPACE|PASSEOF|STRIP; \
6894887Schin 		debug((-7, "PUSH in=%s next=%s", ppinstr(pp.in), pptokchr(*pp.in->nextchr))); \
6904887Schin 	} while (0)
6914887Schin 
6924887Schin #define POP_LINE()		\
6934887Schin 	do \
6944887Schin 	{ \
6954887Schin 		debug((-7, "POP  in=%s", ppinstr(pp.in))); \
6964887Schin 		pp.in = pp.in->prev; \
6974887Schin 		pp.state &= ~(DISABLE|NOSPACE|PASSEOF|STRIP); \
6984887Schin 	} while (0)
6994887Schin 
7004887Schin struct ppcontext			/* pp context			*/
7014887Schin {
7024887Schin 	_PP_CONTEXT_PUBLIC_
7034887Schin 	_PP_CONTEXT_PRIVATE_
7044887Schin };
7054887Schin 
7064887Schin struct ppfile				/* include file info		*/
7074887Schin {
7084887Schin 	HASH_HEADER;			/* this is a hash bucket too	*/
7094887Schin 	struct ppsymbol* guard;		/* guard symbol			*/
7104887Schin 	struct ppfile*	bound[INC_MAX];	/* include bindings		*/
7114887Schin 	int		flags;		/* INC_* flags			*/
7124887Schin };
7134887Schin 
7144887Schin #if CHECKPOINT
7154887Schin 
7164887Schin struct ppindex				/* checkpoint include index	*/
7174887Schin {
7184887Schin 	struct ppindex*	next;		/* next in list			*/
7194887Schin 	struct ppfile*	file;		/* include file			*/
7204887Schin 	unsigned long	begin;		/* beginning output offset	*/
7214887Schin 	unsigned long	end;		/* ending output offset		*/
7224887Schin };
7234887Schin 
7244887Schin #endif
7254887Schin 
7264887Schin struct ppsymkey				/* pun for SYM_KEYWORD lex val	*/
7274887Schin {
7284887Schin 	struct ppsymbol	sym;		/* symbol as usual		*/
7294887Schin 	int		lex;		/* lex value for SYM_KEYWORD	*/
7304887Schin };
7314887Schin 
7324887Schin #if PROTOMAIN && PROTO_STANDALONE
7334887Schin 
7344887Schin #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
7354887Schin #define NiL		0
7364887Schin #define NoP(x)		(&x,1)
7374887Schin #else
7384887Schin #define NiL		((char*)0)
7394887Schin #define NoP(x)
7404887Schin #endif
7414887Schin 
7424887Schin #define newof(p,t,n,x)	((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
7434887Schin 
7444887Schin #define _PP_DELAY_	#
7454887Schin 
7464887Schin _PP_DELAY_ ifdef __STDC__
7474887Schin 
7484887Schin _PP_DELAY_ include <stdlib.h>
7494887Schin _PP_DELAY_ include <unistd.h>
7504887Schin _PP_DELAY_ include <time.h>
7514887Schin _PP_DELAY_ include <string.h>
7524887Schin 
7534887Schin _PP_DELAY_ else
7544887Schin 
7554887Schin _PP_DELAY_ define size_t		int
7564887Schin 
7574887Schin extern void*		realloc(void*, size_t);
7584887Schin extern void*		calloc(size_t, size_t);
7594887Schin extern char*		ctime(time_t*);
7604887Schin extern void		free(void*);
7614887Schin 
7624887Schin _PP_DELAY_ ifndef O_RDONLY
7634887Schin 
7644887Schin extern int		access(const char*, int);
7654887Schin extern int		close(int);
7664887Schin extern int		creat(const char*, int);
7674887Schin extern void		exit(int);
7684887Schin extern int		link(const char*, const char*);
7694887Schin extern int		open(const char*, int, ...);
7704887Schin extern int		read(int, void*, int);
7714887Schin extern time_t		time(time_t*);
7724887Schin extern int		unlink(const char*);
7734887Schin extern int		write(int, const void*, int);
7744887Schin 
7754887Schin _PP_DELAY_ endif
7764887Schin 
7774887Schin _PP_DELAY_ endif
7784887Schin 
7794887Schin #else
7804887Schin 
7814887Schin /*
7824887Schin  * library implementation globals
7834887Schin  */
7844887Schin 
7854887Schin #define ppassert	_pp_assert
7864887Schin #define ppbuiltin	_pp_builtin
7874887Schin #define ppcall		_pp_call
7884887Schin #define ppcontrol	_pp_control
7894887Schin #define ppdump		_pp_dump
7904887Schin #define ppexpand	_pp_expand
7914887Schin #define ppexpr		_pp_expr
7924887Schin #define ppfsm		_pp_fsm
7934887Schin #define ppinmap		_pp_inmap
7944887Schin #define ppinstr		_pp_instr
7954887Schin #define ppkeyname	_pp_keyname
7964887Schin #define pplexmap	_pp_lexmap
7974887Schin #define pplexstr	_pp_lexstr
7984887Schin #define ppload		_pp_load
7994887Schin #define ppmodestr	_pp_modestr
8004887Schin #define ppmultiple	_pp_multiple
8014887Schin #define ppnest		_pp_nest
8024887Schin #define ppoption	_pp_option
8034887Schin #define ppoptionstr	_pp_optionstr
8044887Schin #define pppclose	_pp_pclose
8054887Schin #define pppdrop		_pp_pdrop
8064887Schin #define pppopen		_pp_popen
8074887Schin #define pppread		_pp_pread
8084887Schin #define pppredargs	_pp_predargs
8094887Schin #define pppush		_pp_push
8104887Schin #define pprefmac	_pp_refmac
8114887Schin #define ppsearch	_pp_search
8124887Schin #define ppstatestr	_pp_statestr
8134887Schin #define pptokstr	_pp_tokstr
8144887Schin #define pptrace		_pp_trace
8154887Schin 
8164887Schin #endif
8174887Schin 
8184887Schin extern void		ppassert(int, char*, char*);
8194887Schin extern void		ppbuiltin(void);
8204887Schin extern int		ppcall(struct ppsymbol*, int);
8214887Schin extern int		ppcontrol(void);
8224887Schin extern void		ppdump(void);
8234887Schin extern char*		ppexpand(char*);
8244887Schin extern long		ppexpr(int*);
8254887Schin extern void		ppfsm(int, char*);
8264887Schin extern char*		ppinstr(struct ppinstk*);
8274887Schin extern char*		ppkeyname(int, int);
8284887Schin extern char*		pplexstr(int);
8294887Schin extern void		ppload(char*);
8304887Schin extern void		ppmapinclude(char*, char*);
8314887Schin extern char*		ppmodestr(long);
8324887Schin extern int		ppmultiple(struct ppfile*, struct ppsymbol*);
8334887Schin extern void		ppnest(void);
8344887Schin extern int		ppoption(char*);
8354887Schin extern char*		ppoptionstr(long);
8364887Schin extern void		pppclose(char*);
8374887Schin extern int		pppdrop(char*);
8384887Schin extern char*		pppopen(char*, int, char*, char*, char*, char*, int);
8394887Schin extern int		pppread(char*);
8404887Schin extern int		pppredargs(void);
8414887Schin extern void		pppush(int, char*, char*, int);
8424887Schin extern struct ppsymbol*	pprefmac(char*, int);
8434887Schin extern int		ppsearch(char*, int, int);
8444887Schin extern char*		ppstatestr(long);
8454887Schin extern char*		pptokstr(char*, int);
8464887Schin extern void		pptrace(int);
8474887Schin 
8484887Schin #if _std_malloc
8494887Schin 
8504887Schin #include <vmalloc.h>
8514887Schin 
8524887Schin #undef	free
8534887Schin #define free(p)	 	vmfree(Vmregion,(void*)p)
8544887Schin #undef	newof
8554887Schin #define newof(p,t,n,x)	vmnewof(Vmregion,p,t,n,x)
8564887Schin #undef	oldof
8574887Schin #define oldof(p,t,n,x)	vmoldof(Vmregion,p,t,n,x)
8584887Schin #undef	strdup
8594887Schin #define strdup(s)	vmstrdup(Vmregion,s)
8604887Schin 
8614887Schin #endif
8624887Schin 
8634887Schin #endif
864