/**************************************************************
 *
 *	CRISP - Custom Reduced Instruction Set Programmers Editor
 *
 *	(C) Paul Fox, 1989
 *
 *    Please See COPYLEFT notice.
 *
 **************************************************************/
# include	"def.h"
# include	"cm.h"
# include	"refstr.h"

# if	defined(l_next)
#	undef	l_next
# endif

#ifndef _U
# include	<ctype.h>
#endif
# include	"regexp.h"
typedef	short	int16;
typedef	unsigned char	LIST;

# define	MAX_ARGC	12
# define	MAX_MACROS	256
# define	MAX_NESTING	128
# define	SYMLEN		32

# define	vm_lock_line(line)	linep(line)
# define	vm_unlock(line)		
/*---------------------------------------
 *   Registered macro types.
 *---------------------------------------*/
# define	REG_TYPED	0	/* Character typed.		*/
# define	REG_EDIT	1	/* Different file edited.	*/
# define	REG_ALT_H	2	/* ALT-H pressed in response	*/
					/* to a prompt.			*/
# define	REG_UNASSIGNED	3	/* Unassigned key pressed.	*/
# define	REG_IDLE	4	/* Idle time expired.		*/
# define	REG_EXIT	5	/* About to exit.		*/
# define	REG_NEW		6	/* New file edited and readin. 	*/
# define	REG_CTRLC	7	/* CTRL-C (SIGINT) pressed 	*/
					/* during macro execution.	*/
# define	REG_INVALID	8	/* Invalid key pressed during	*/
					/* response input.		*/
# define	REG_INTERNAL	9	/* Internal error.		*/
# define	REG_MOUSE	10	/* Mouse callback.		*/
# define	REG_PROC_INPUT	11	/* Process input available.	*/
# define	REG_KEYBOARD	12	/* Keyboard buffer empty.	*/
# define	REG_MAX		12

/**********************************************************************/
/*   Search and translate flags.				      */
/**********************************************************************/
# define	SF_BACKWARDS	0x01	/* Search in backwards direction. */
# define	SF_IGNORE_CASE	0x02	/* Ignore case 			  */
# define	SF_BLOCK	0x04	/* Restrict search to current block*/
# define	SF_UNIX		0x08	/* Use Unix regular expressions.  */
# define	SF_LENGTH	0x10	/* Return length of match.	  */
# define	SF_NOT_REGEXP	0x20	/* Dont treat as a regular expr.  */
# define	SF_GLOBAL	0x40	/* Global translate.		  */
# define	SF_PROMPT	0x80	/* Prompt for translate changes.  */
# define	SF_MAXIMAL	0x100	/* Maximal search mode.		  */
/**********************************************************************/
/*   Following  passed  to  the  com_op()  and com_equ() routines to  */
/*   distinguish the arithmetic operator.			      */
/**********************************************************************/
# define	NOOP		0
# define	PLUS		1
# define	MINUS		2
# define	MULTIPLY	3
# define	DIVIDE		4
# define	MODULO		5
# define	EQ		6
# define	NE		7
# define	LT		8
# define	LE		9
# define	GT		10
# define	GE		11
# define	ABOVE		12
# define	ABOVE_EQ	13
# define	BELOW		14
# define	BELOW_EQ	15
# define	BNOT		16
# define	BAND		17
# define	BOR		18
# define	BXOR		19
# define	LSHIFT		20
# define	RSHIFT		21

extern	int	sizeof_atoms[];

# define	SF_POLY		0x01	/* Symbol is polymorphic.	*/
# define	SF_RO		0x02	/* Symbol is read-only.		*/
typedef	struct SYMBOL {
	char	s_name[SYMLEN];
	OPCODE	s_type;
	u_char	s_flag;
	union	{
		ref_t	*obj;
		long	l;
		double	real;
		} s_v;
	} SYMBOL;
# define	s_int	s_v.l
# define	s_obj	s_v.obj
# define	s_float	s_v.real

typedef	struct define {
	char	*name;
	char	*value;
	struct define	*next;
	} DEFINE;


/*---------------------------------------
 *   List-macro definitions.
 *---------------------------------------*/
/* Following typedef for argv's benefit only. */
typedef	struct LISTV {
	OPCODE	l_flags;
	union {
		ref_t	*ref_str;
		char	*string;
		long	integer;
		SYMBOL	*symbol;
		double	real;
		LIST	*list;
		} u;
	} LISTV;
# define	l_list	u.list
# define	l_str	u.string
# define	l_ref	u.ref_str
# define	l_int	u.integer
# define	l_sym	u.symbol
# define	l_float	u.real
# define	lnext(lp)	((lp)->l_next ? (lp) + (lp)->l_next : 0)
# define	lnull(lp)	(lp->l_next == 0)
# define	llist(lp)	((lp)->l_int ? (lp) + (lp)->l_int : 0)

# define	M_AUTOLOAD	0x01	/* Macro needs to be autoloaded */
					/* on reference.		*/
typedef	struct MACRO {
	char	*m_name;
	short	m_flags;
	short	m_ftime;
	LIST	*m_list;
	int	m_size;			/* Size of macro in atoms.	   */
	struct MACRO	*m_next;	/* Next macro in list for this file.*/
	} MACRO;

/*------------------------------------
 *    Typedef for list of macro files.
 *    All this info is needed in case we
 *    delete the macro.
 *------------------------------------*/
typedef struct MACROF {
	char	*mf_name;
	char	*mf_list;
	MACRO	*mf_macro;
	} MACROF;
/*--------------------------------
 *   Define debug flags.
 *--------------------------------*/
# define	DB_REGEXP	0x0002	/* Regular expression debug output*/
# define	DB_UNDO		0x0004	/* Undo trace.			  */
# define	DB_FLUSH	0x0008	/* Flush output.		  */
# define	DB_PROMPT	0x4000	/* Debug prompting code.	  */

# define	MAX_FILES	10

# define	TERMINAL	0x01
struct	f {
	char	*bufp;
	char	*buf;
	char	*bufend;
	int	fd;
	int	line_no;
	int	flags;
	off_t	size;
	char	name[64];
	};

/*******************************************************************/
/*   The  following  flag  definitions  are  used  to  define the  */
/*   argument types to the builtin primitives.			   */
/*******************************************************************/
# define	ARG_INT		0x01
# define	ARG_FLOAT	0x02
# define	ARG_STRING	0x04
# define	ARG_LIST	0x08
# define	ARG_COND	0x10

# define	ARG_REST	0x20
# define	ARG_OPT		0x40
# define	ARG_LVAL	0x80
# define	ARG_NUM		(ARG_INT | ARG_FLOAT)
# define	ARG_ANY		(ARG_NUM | ARG_STRING | ARG_LIST)

# define	MAX_BUILTIN_ARGS	8

# define	B_REDEFINE	0x0001	/* Builtin macro has been	*/
					/* redefined.			*/
# define	B_NOVALUE	0x0002	/* Dont print accumulator result*/
					/* in debug mode.		*/
# define	B_SAFE		0x0004	/* Macro doesn't and cannot modify */
					/* parameters, i.e. its safe to */
					/* not take a copy of arguments. */
typedef struct BUILTIN	{
	char		*name;
	void		(*func)();
	unsigned char	flags;
	unsigned char	arg;
	short		argc;
	unsigned char	arg_types[MAX_BUILTIN_ARGS];
	LIST		*argv;
	MACRO		*first_macro;
	MACRO		*macro;	/* Current macro being executed in 	*/
				/* recursive keyword execution.		*/
	long	reference;	/* No. of times keyword referenced.	*/
	} BUILTIN;

struct mac_stack {
	char	*name;
	LIST	*argv;
	int	nesting_level;	/* Level where symbols are defined for 	*/
				/* debugger.				*/
	};

/*-----------------------------------------*/
/*   Following information defines the	   */
/*   format of characters passed to the	   */
/*   low level ttputc() function.	   */
/*					   */
/*   _____________________________________ */
/*   | fg-col | bg-col |  character      | */
/*   ------------------------------------- */
/*    15       12       7		0  */
/*-----------------------------------------*/	
typedef unsigned short vbyte_t;

# define	FG_COLOR	0xf000
# define	BG_COLOR	0x0f00
# define	COLOR_MASK	(FG_COLOR | BG_COLOR)

# define	FG_SHIFT	12
# define	BG_SHIFT	8 
# define	FG(x)		((x) << FG_SHIFT)
# define	BG(x)		((x) << BG_SHIFT)

# define	WHITE		7
/*
 * Display colors.
 */
# define	CMESSAGE	4
# define	CERROR		5
typedef struct color {
	u_int16		c_background;
	u_int16		c_normal;
	u_int16		c_select;
	u_int16		c_messages;
	u_int16		c_error;
	u_int16		c_bg;
	u_int16		c_fg;
	} color_t;

/**********************************************************************/
/*   Following flags are used for the display_ctrl variable.	      */
/**********************************************************************/
# define	DC_WINDOW	0x0001	/* Running under a windowing system. */
# define	DC_SHADOW	0x0002	/* Display shadow around popups.    */
# define	DC_SHADOW_SHOWTHRU 0x0004
					/* When displaying shadow, use reverse */
					/* of whats underneath the shadow.	*/
/***********************************************/
/*   Information needed by the pty code.       */
/***********************************************/
# define	MAX_ESCAPE	40	/* Size of escape sequences.	*/

# define	P_ECHO		0x0001	/* Local echo on.		*/
# define	P_NOINSERT	0x0002	/* If on, dont insert to process*/
# define	P_OVERWRITE	0x4000	/* Set if to overwrite process input. */
# define	P_WAITING	0x8000	/* Waiting for text.		*/


typedef	struct DISPLAY	{
		short		d_x,	/* Current cursor position.	*/
				d_y;
		short		d_cols,	/* Physical size.		*/
				d_rows;
		char		d_escape[MAX_ESCAPE];
					/* Buffer to assemble escape sequence*/
		char		*d_escptr;/* Pointer to next byte in 	*/
					/* d_escape.			*/
		vbyte_t		d_color;/* Color mask to be OR'ed in.	*/
		vbyte_t		d_attr;	/* Mask telling us whether its  */
					/* reverse/bold.		*/
		u_int16		d_flags;
		int		d_pipe_in;/* Pipe to read from.		*/
		int		d_pipe_out;/* Pipe to write to.		*/
		int		d_pid;	/* Process ID of child.		*/
		int		d_pgrp;	/* Process group of child.	*/
		u_int16		d_wlen;	/* Number of characters in waitfor*/
					/* buffer.			*/
		char		*d_waitfor;/* Queue of characters inserted */
					/* into buffer from pty.	*/
		int		d_line_marker;/* Place to insert output. */
		int		d_col_marker;
# if	CR_DOS
# define	PTY_BUFSIZ	512
# define	PTY_STACK	512
		unsigned long	d_sema;		/* Semaphore to wait on.	*/
		unsigned long	d_wait;		/* Semaphore for thread to wait on. */
		unsigned short	d_err;		/* Error return			*/
		short		d_dead;		/* Thread died.			*/
		unsigned short	d_rcvlen;	/* Number of bytes read.	*/
		char		d_buf[PTY_BUFSIZ];/* Buffer for reading into.	*/
		char		d_stack[PTY_STACK];/* Stack for PTY thread.	*/
# endif
		} DISPLAY;

# if	!defined(STANDALONE)
extern struct f fps[MAX_FILES];
extern	struct	f	*fp_ptr;
extern DEFINE	*def_head,
		*def_ptr;
extern	SPTREE	*gsym_tbl;
extern	SPTREE	*lsym_tbl[MAX_NESTING];
extern	struct mac_stack	mac_stack[MAX_NESTING];
extern	int	nest_level;
extern	int	ms_cnt;
extern	int	argc;
extern	LISTV	*argv;
extern	int	*cur_line;
extern	int	*cur_col;
extern	u_int16	ncol,
		nrow,
		ttcol,
		ttrow;
extern  int	tceeol,
		tcinsl,
		tcdell,
		msg_level,
		screen_garbled;
extern  BUFFER  *curbp,
		*bheadp;

extern  WINDOW  *curwp;
extern  WINDOW  *wheadp;
extern	color_t	col_table;
extern	PHYS_TERM	pt;
extern 	BUILTIN	builtin[];
extern	int	sizeof_builtin;
extern	int	msg_level;
# endif
/**********************************************************************/
/*   Handle  case  where  we  don't  have  select but we've used the  */
/*   select macros for bit manipulation.			      */
/**********************************************************************/
# define	TTY_FD	0
# define	BIT(x)	(1 << (x))

# if !defined(SELECT)
typedef long fd_set;
# define	FD_SET(n, p)	*p |= BIT(n)
# define	FD_CLR(n, p)	*p &= ~BIT(n)
# define	FD_ISSET(n, p)	*p & BIT(n)
# else
# 	if CR_AIX_3
#		include	<sys/select.h>
#	endif
# endif
# include	"decls.h"
