#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

#ifndef NULL
#define NULL 0
#endif
#define NULL_STRING (char *)NULL

/* the atomic type definitions assume that yacc does not generate these values
	as token types.  See y.tab.h */

#define LGL 1
#define INT 2
#define REAL 3
#define DOUBLE 4
#define CHAR 5
#define LIST 6
#define COMPLEX 7
#define ANY 11
#define STRUCTURE 21
#define MAX_ATOMIC 20
extern int atomic_types[];
#define atomic_type(t) ((t)<=MAX_ATOMIC ? atomic_types[t] : FALSE)
	/* this depends slightly on the implementation of yacc; viz, that
	   yacc generates token types in increasing numerical value */

/*error code for S_debug, long jumps */
#define SIGSERROR 1000
#define SIGSWARN 1001

/*extended alpha list */
#define ISALPHA(p) (isalpha(p) || (p)=='.')

extern char *S_alloc(), *S_realloc();

/* codes used by access(2) -- see for example, search() */
#define READ_ACCESS 4
#define WRITE_ACCESS 2
#define EXECUTE_ACCESS 1

/* pointers to C routines */

typedef int (*fun_ptr) ();

#ifdef PI
#undef PI
#endif
#define PI 3.1415926535897932384626433832795028841971693993751
#define DEG2RD .01745329251994329576923690768488612713442871888541

#include "machine.h"	/* machine arith constants */
#include "system.h"	/* operating system, compiler stuff */


typedef struct {
	double re, im;
} complex;

typedef union {
	long *Long;
	float *Float;
	char **Char;
	double *Double;
	complex *Complex;
	char *name;
	unsigned long offset;		/* disk offset */
	struct s_vector *(*sys)();	/* type for an internal system function */
	struct s_vector **tree;		/* point to a list of vector pointers */
} pointer;

typedef union {
	struct s_vector *frame;
	struct s_vector *next;		/*for lists */
} s_x;

typedef struct s_vector {
	int Type;
	char *name;
	int mode;
	long length;
	pointer value;
	s_x x;
	long nalloc;
	long status; 
} vector;

typedef struct s_vector *(*vfun_ptr)();

/* stucture for hash tables */
typedef struct s_x_h {
	char *name;
	long index;
	struct s_x_h *next;
} x_h;

#ifndef NULL
#define NULL			0
#endif

#define NULL_ENTRY		((vector *)NULL)
#define NULL_ENTRYP		((vector **)NULL)
#define NA_STRING		""

#define Child1(p)		(*((p)->value.tree))
#define Child2(p)		(*((p)->value.tree+1))
#define Child3(p)		(*((p)->value.tree+2))

/* status flags for ent->x.status */
#define PRECIOUS(p)		(p->x.frame != NULL_ENTRY)
#define CHECK_IT		63
#define IS_NULL_STRING(p)	((p)==NULL_STRING || *(p)=='\0')

/* defines for function calls */
#define Args(ent)		(((ent)->value.tree)+1)
#define Nargs(ent)		((ent)->length-1)
#define Arg1(p)			(*((p)->value.tree+1))
#define Arg2(p)			(*((p)->value.tree+2))
#define VOID(p)			((p)==NULL_ENTRY||(p)==S_void||(p)->mode==MISSING)
#define data_mode(p)		((atomic_type(p->mode))?p->mode : Data_mode(p))
#define data_length(p)		((atomic_type(p->mode))?p->length : Data_length(p))

#define SHORT_LIST_LENGTH	10

/* cases for rec_check */
#define REC_INIT		0
#define REC_ADD			1
#define REC_DELETE		2
#define REC_CHECK		3

/*
 * markers for the range of token types:
 * must have y.tab.h included to use;
 * just not ENTRY_TYPE
 */
#define FIRST_TOKEN		NAME
#define LAST_TOKEN		LVALUE
#define FREED_TYPE		UNKNOWN
#define LANGUAGE_TYPE(mode)	(mode>=FIRST_TOKEN &&\
				 mode<=LAST_TOKEN &&\
				(token_info[mode-FIRST_TOKEN]&1))
#define NOT_RECURSIVE(mode)	(mode<FIRST_TOKEN\
				?(mode!=LIST && mode!=STRUCTURE)\
				:(mode<=LAST_TOKEN && (token_info[mode-FIRST_TOKEN]&2)))

#define EXTRA_FRAMES		2L
#define PERM_FRAME		-2L
#define CACHE_FRAME		-1L
#define FRAME0			0L

/* some codes used by which_frame and its callers */
#define TO_FRAME0		-3L
#define NO_FRAME		-4L
#define UNKNOWN_FRAME		-5L
#ifdef	lint
#define	UNUSED(c)	NONEXISTENT((char *)c)
#define MEANINGFUL(c)	c = 0; UNUSED(c)
#else
#define	UNUSED(c)
#define MEANINGFUL(c)
#endif

#define PROBLEM		sprintf(error_buf,
#define WARNING(x)	), Warning(error_buf, x)
#define RECOVER(x)	), Recover(error_buf, x)

extern char error_buf[];

extern vector *do_op(), *do_math(), *do_summary();
extern vector *S_extract(), *S_replace(), *Sfun(), *S_unprotect(), *S_switch();
extern vector *As_vector(), *Is_vector(), *S_dtype(), *S_list(), *S_unlist();
extern vector *New_vector(), *alcvec(), *alc_name(), *alctss(), *alcf();
extern vector *alc1(), *alc2(), *alc3(), *alclist(), *alcuny(), *alcchar();
extern vector *cmpx_op(), *add_comment(), *mk_comment(), *comment_out();
extern vector *coevec(), *coeves(), *coestr(), *coedata(), *class_fun(), *class_op();
extern vector *do_lexlist(), *do_assign(), *do_return(), *do_fcall();
extern vector *do_op_list(), *do_lbrace(), *internal_symbol();
extern vector *eval(), *deparse(), *enc_data(), *parent_data(), *fnd_data();
extern vector *get_data(), *set_data(), *append_data(), *copy_data();
extern vector *find_comp(), *find_data(), *append_el(), *do_na_out(), *combine();
extern vector *get_S_entry(), *S_to_QPE(), *S_na_funs(), *S_deparse();
extern vector *S_sh_dp(), *S_method();
extern vector *assign_obj(), *fun_args(), *compact_keep(), *deparse(), *rec_check();
extern vector *get_hash(), *get_local(), *set_names(), *get_names(), *xact_comp();
extern vector *blt_in_NA, *blt_in_TRUE, *blt_in_FALSE, *blt_in_NULL, *blt_in_empty;
extern vector *Trace, *Frames, *Local_data, *S_data, *S_ptree, *assign_data, *cons_frame;
extern vector *Warn_list, *C_on_stop, *Program, **C_specials;
extern vector *S_void, *Search_list, *frame0, *h_S_data, *hash_data;
extern char *Integer_format, *Single_format, *Double_format, *Complex_format;
extern long  Integer_length,  Single_length,  Double_length,  Complex_length;

extern char *encs1(), *encs2(), *enci1(), *enci2(), *short_dp();
extern char *string_value(), *sanity(), *c_symbol(), *ftn_symbol();
extern char *token_name(), *do_unlex(), *sanity(), *sgets(), *c_s_cpy();
extern char *S_alloc(), *S_realloc(), *S_calloc();
extern char *fun_name(), *cur_fun_name();
extern char *min_alloc, *max_alloc, *shome, *user_home, *prog_name;
extern char *Working_data;
extern char load_time[];

extern long Data_length(), long_value(), unlex_len();
extern long x_which_comp(), which_frame(), which_comp();
extern long min_length(), menu(), file_mtime(), set_alloc();
extern long cur_frame, Nframe;

extern int mode_lookup(), coerce_to(), seedin(), seedot(), check_assign();
extern int cmpx_cmp(), expr_cmp(), clean_list(), do_parse(), op_action();
extern int Data_mode(), del_comp(), intern_in_l(), hash(), bad_name();
extern int push_source(), pop_source(), catchall(), has_names(), re_assign();
extern int running_S, sys_index, eval_open, cur_interact, db_level;
extern int last_signal, doing_list, runit_pid, mainpid, S_lex_debug;
extern int Eval_Profile, Initialized, Restart, Random_flag, sinkpipe;
extern int atomic_types[], token_info[];

extern unsigned charmash();

extern double double_value();
extern double *data_header, *dict_header;

extern void init_load(), clear_alloc(), mem_size(), window_size(), make_formats();
extern void un_hash(), hash_enter(), nprime(), names_unlex(), Warning(), comp_init();
extern void echo_on(), echo_off(), flush_input(), S_terminate(), Recover();
extern void add_error(), add_exit(), del_error(), do_C_stop(), clock_init();
extern void S_init(), data_init(), Slexinit(), put_data(), save_restart();
extern void do_rm(), flush_data(), frame0_assign(), interactive(), perm_assign();
extern void pratom(), do_S(), frames_init(), warn_message(), do_C_wrap();
extern void do_compact(), alloc_ptr(), do_stop(), set_stdout(), set_precious();
extern void try_to_free(), clear_cache(), check_frame0(), install_search();

extern FILE *yyin, *audit_file;

#ifdef MALLOC
#define Perm_alloc(n,s) perm_alloc((unsigned)(n),(unsigned)(s))
#define Perm_realloc(n,s) perm_realloc((char *)(n),(unsigned)(s))
#define Perm_free(n) perm_free((char *)(n))
#define Perm_open(f) perm_open((FILE *)(f))
#define Perm_close(f) perm_close((FILE *)(f))
extern char *perm_alloc(), perm_realloc(); extern int perm_free();
#else
#define Perm_alloc(n,s) calloc((unsigned)(n),(unsigned)(s))
#define Perm_realloc(n,s) realloc((char *)(n),(unsigned)(s))
#define Perm_free(n) free((char *)(n))
#define Perm_open(f) {}
#define Perm_close(f) {}
#endif

#define ALLOC(n,s) (s *)(cur_frame? Calloc(n,sizeof(s)) : Perm_alloc(n,sizeof(s)))
#define PERMALLOC(n,s) (s *)Perm_alloc(n,sizeof(s))


#ifdef __STDC__
#include <stddef.h>
extern char *strncpy(char *s1, const char *s2, size_t n);
extern char *strcpy(char *s1, const char *s2);
extern char *strcat(char *s1, const char *s2);
extern char *mktemp(char *template);
extern char *gcvt(double value, int ndigit, char *buf);
extern void *memcpy(void *s1, const void *s2, size_t n);
extern void *sbcopy(void *s1, const void *s2, size_t n);
extern int brk(char *addr);
extern char *sbrk(int incr);
extern void *malloc(size_t size);
extern void *calloc(size_t nmemb, size_t size);
extern void *realloc(void *ptr, size_t size);
extern void free(void *ptr);
extern char *getenv(const char *name);
extern char *getlogin();
extern char *ctime(long *clock);
extern long lseek(int d, long offset, int whence);
extern long time(long *timer);
extern void exit(int status);
extern int errno;
#else
extern char *strncpy(), *strcpy(), *strcat(), *mktemp(), *gcvt();
extern char *memcpy(), *sbcopy();
extern char *brk(), *sbrk(), *malloc(), *calloc(), *realloc();
extern char *getenv(), *getlogin(), *ctime();
extern long lseek(), time();
extern void exit(), _exit();
extern int errno;
#endif

/* definitions for automatic casting of types */
#define MEMCPY(p,q,n)	Memcpy((char *)(p),(char *)(q),n*sizeof(*(p)))
#define CALLOC(n,t)	(t *)Calloc(n,sizeof(t))
#define FREAD(p,n,f)	Fread((char *)p,sizeof(*(p)),n,f)
#define FWRITE(p,n,f)	Fwrite((char *)p,sizeof(*(p)),n,f)
#define QSORT(p,n,c)	Qsort((char *)p,n,sizeof(*(p)),c)


/*
 * Automatic casting of sizes to int or unsigned int,
 * for the C libraries.  These should be redefined
 * or even written as functions if an int is smaller
 * than a long, and if vector lengths might be longer
 * than what can be held in an int; for example, if
 * ints are 16 bits and longs are 32 bits.
 */
#define Memcpy(p,q,n)	memcpy(p,q,(int)(n))
#define Malloc(n)	malloc((unsigned int)(n))
#define Calloc(n,s)	S_calloc((unsigned int)(n),s)
#define Realloc(p,n)	realloc(p,(unsigned int)(n))
#define Fread(p,s,n,f)	(f ? fread(p,s,(int)(n),f) : \
	(Recover("System error: null file for reading",NULL_ENTRY),0))
#define Fwrite(p,s,n,f)	(f ? fwrite(p,s,(int)(n),f) : \
	(Recover("System error: null file for writing",NULL_ENTRY),0))
#define Qsort(p,n,s,c)	qsort(p,(int)(n),s,c)

#ifdef Berkeley
#define memcpy(a,b,n) bcopy(b,a,n)
#endif
#ifdef ATT_UNIX
#define memcpy(a,b,n) sbcopy(b,a,n)
#endif
