/* $Header: stab.h,v 3.0.1.4 90/10/16 10:33:08 lwall Locked $
 *
 *    Copyright (c) 1989, Larry Wall
 *
 *    You may distribute under the terms of the GNU General Public License
 *    as specified in the README file that comes with the perl 3.0 kit.
 *
 * $Log:	stab.h,v $
 * Revision 3.0.1.4  90/10/16  10:33:08  lwall
 * patch29: *foo now prints as *package'foo
 * patch29: package behavior is now more consistent
 * 
 * Revision 3.0.1.3  90/08/09  05:18:42  lwall
 * patch19: Added support for linked-in C subroutines
 * 
 * Revision 3.0.1.2  90/03/12  17:00:43  lwall
 * patch13: did some ndir straightening up for Xenix
 * 
 * Revision 3.0.1.1  89/12/21  20:19:53  lwall
 * patch7: in stab.h, added some CRIPPLED_CC support for Microport
 * 
 * Revision 3.0  89/10/18  15:23:30  lwall
 * 3.0 baseline
 * 
 */

struct stabptrs {
    char        stbp_magic[4];
    STR		*stbp_val;	/* scalar value */
    struct stio *stbp_io;	/* filehandle value */
    FCMD	*stbp_form;	/* format value */
    ARRAY	*stbp_array;	/* array value */
    HASH	*stbp_hash;	/* associative array value */
    HASH	*stbp_stash;	/* symbol table for this stab */
    SUBR	*stbp_sub;	/* subroutine value */
    int		stbp_lastexpr;	/* used by nothing_in_common() */
    line_t	stbp_line;	/* line first declared at (for -w) */
    char	stbp_flags;
};

#if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))
#define MICROPORT
#endif

#define stab_magic(stab)	(((STBP*)(stab->str_ptr))->stbp_magic)
#define stab_val(stab)		(((STBP*)(stab->str_ptr))->stbp_val)
#define stab_io(stab)		(((STBP*)(stab->str_ptr))->stbp_io)
#define stab_form(stab)		(((STBP*)(stab->str_ptr))->stbp_form)
#define stab_xarray(stab)	(((STBP*)(stab->str_ptr))->stbp_array)
#ifdef	MICROPORT	/* Microport 2.4 hack */
ARRAY *stab_array();
#else
#define stab_array(stab)	(((STBP*)(stab->str_ptr))->stbp_array ? \
				 ((STBP*)(stab->str_ptr))->stbp_array : \
				 ((STBP*)(aadd(stab)->str_ptr))->stbp_array)
#endif
#define stab_xhash(stab)	(((STBP*)(stab->str_ptr))->stbp_hash)
#ifdef	MICROPORT	/* Microport 2.4 hack */
HASH *stab_hash();
#else
#define stab_hash(stab)		(((STBP*)(stab->str_ptr))->stbp_hash ? \
				 ((STBP*)(stab->str_ptr))->stbp_hash : \
				 ((STBP*)(hadd(stab)->str_ptr))->stbp_hash)
#endif			/* Microport 2.4 hack */
#define stab_stash(stab)	(((STBP*)(stab->str_ptr))->stbp_stash)
#define stab_sub(stab)		(((STBP*)(stab->str_ptr))->stbp_sub)
#define stab_lastexpr(stab)	(((STBP*)(stab->str_ptr))->stbp_lastexpr)
#define stab_line(stab)		(((STBP*)(stab->str_ptr))->stbp_line)
#define stab_flags(stab)	(((STBP*)(stab->str_ptr))->stbp_flags)
#define stab_name(stab)		(stab->str_magic->str_ptr)

#define SF_VMAGIC 1		/* call routine to dereference STR val */
#define SF_MULTI 2		/* seen more than once */

struct stio {
    FILE	*ifp;		/* ifp and ofp are normally the same */
    FILE	*ofp;		/* but sockets need separate streams */
#ifdef READDIR
    DIR		*dirp;		/* for opendir, readdir, etc */
#endif
    long	lines;		/* $. */
    long	page;		/* $% */
    long	page_len;	/* $= */
    long	lines_left;	/* $- */
    char	*top_name;	/* $^ */
    STAB	*top_stab;	/* $^ */
    char	*fmt_name;	/* $~ */
    STAB	*fmt_stab;	/* $~ */
    short	subprocess;	/* -| or |- */
    char	type;
    char	flags;
#ifdef ARM
    int		statval;	/* Return value from stat */
    struct stat	statcache;	/* File stat values */
    char	*name;		/* File name */
#endif
};

#define IOF_ARGV 1	/* this fp iterates over ARGV */
#define IOF_START 2	/* check for null ARGV and substitute '-' */
#define IOF_FLUSH 4	/* this fp wants a flush after write op */

struct sub {
    CMD		*cmd;
    int		(*usersub)();
    int		userindex;
    STAB	*filestab;
    long	depth;	/* >= 2 indicates recursive call */
    ARRAY	*tosave;
};

#define Nullstab Null(STAB*)

#define STAB_STR(s) (tmpstab = (s), stab_flags(tmpstab) & SF_VMAGIC ? stab_str(stab_val(tmpstab)->str_magic) : stab_val(tmpstab))
#define STAB_GET(s) (tmpstab = (s), str_get(stab_flags(tmpstab) & SF_VMAGIC ? stab_str(tmpstab->str_magic) : stab_val(tmpstab)))
#define STAB_GNUM(s) (tmpstab = (s), str_gnum(stab_flags(tmpstab) & SF_VMAGIC ? stab_str(tmpstab->str_magic) : stab_val(tmpstab)))

EXT STAB *tmpstab;

EXT STAB *stab_index[128];

EXT int statusvalue;

EXT int delaymagic INIT(0);
#define DM_DELAY 1
#define DM_REUID 2
#define DM_REGID 4

extern STAB *aadd PROTO((STAB *));
extern STAB *hadd PROTO((STAB *));
extern STAB *fstab PROTO((char *));
extern void stabset PROTO((STR *, STR *));
extern int whichsig PROTO((char *));
extern void stab_check PROTO((int, int));
extern void stab_fullname PROTO((STR *, STAB *));
