/*
 * $Id: zsh.h,v 1.43 1995/05/30 02:47:41 coleman Exp coleman $
 *
 * zsh.h - standard header file
 *
 * This file is part of zsh, the Z shell.
 *
 *
 * Copyright (c) 1992-1995 Paul Falstad
 * All rights reserved.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * In no event shall Paul Falstad or the Zsh Development Group be liable
 * to any party for direct, indirect, special, incidental, or consequential
 * damages arising out of the use of this software and its documentation,
 * even if Paul Falstad and the Zsh Development Group have been advised of
 * the possibility of such damage.
 *
 * Paul Falstad and the Zsh Development Group specifically disclaim any
 * warranties, including, but not limited to, the implied warranties of
 * merchantability and fitness for a particular purpose.  The software
 * provided hereunder is on an "as is" basis, and Paul Falstad and the
 * Zsh Development Group have no obligation to provide maintenance,
 * support, updates, enhancements, or modifications.
 */

#ifdef HAVE_CONFIG_H
# if defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation        *
 * using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h *
 * (which it would do because it found this file in $srcdir).           */
#  include <config.h>
#  include <system.h>
# else
#  include "config.h"
#  include "system.h"
# endif
#endif

/* math.c */
typedef int LV;

#include "zle.h"

/* Character tokens are sometimes casted to (unsigned char)'s.         * 
 * Unfortunately, some compilers don't correctly cast signed to        * 
 * unsigned promotions; i.e. (int)(unsigned char)((char) -1) evaluates * 
 * to -1, instead of 255 like it should.  We circumvent the troubles   * 
 * of such shameful delinquency by casting to a larger unsigned type   * 
 * then back down to unsigned char.                                    */

#ifdef BROKEN_SIGNED_TO_UNSIGNED_CASTING
# define STOUC(X)	((unsigned char)(unsigned short)(X))
#else
# define STOUC(X)	((unsigned char)(X))
#endif

/* The source was full of implicit casts between signed and unsigned      *
 * character pointers.  To get a clean compile, I've made these casts     *
 * explicit, but the potential for error is still there.  If your machine *
 * needs special treatment, just define your own macros here.             *
 * 	--jim <jmattson@ucsd.edu>                                         */

#define STOUCP(X)	((unsigned char *)(X))
#define UTOSCP(X)	((char *)(X))

/* size of job list */

#define MAXJOB 50

/* character tokens */

#define ALPOP		((char) 0x81)
#define HISTSPACE	((char) 0x83)
#define Pound		((char) 0x84)
#define String		((char) 0x85)
#define Hat		((char) 0x86)
#define Star		((char) 0x87)
#define Inpar		((char) 0x88)
#define Outpar		((char) 0x89)
#define Qstring	        ((char) 0x8a)
#define Equals		((char) 0x8b)
#define Bar	      	((char) 0x8c)
#define Inbrace	        ((char) 0x8d)
#define Outbrace	((char) 0x8e)
#define Inbrack	        ((char) 0x8f)
#define Outbrack	((char) 0x90)
#define Tick		((char) 0x91)
#define Inang		((char) 0x92)
#define Outang		((char) 0x93)
#define Quest		((char) 0x94)
#define Tilde		((char) 0x95)
#define Qtick		((char) 0x96)
#define Comma		((char) 0x97)
#define Snull		((char) 0x98)
#define Dnull		((char) 0x99)
#define Bnull		((char) 0x9a)
#define Nularg		((char) 0x9b)

#define INULL(x)	(((x) & 0xf8) == 0x98)

/* chars that need to be quoted if meant literally */

#define SPECCHARS "#$^*()=|{}[]`<>?~;&!\n\t \\\'\""

/* ALPOP in the form of a string */

#define ALPOPS " \201"
#define HISTMARK "\201"

#define SEPER           1
#define NEWLIN          2
#define LEXERR          3
#define SEMI            4
#define DSEMI           5
#define AMPER           6
#define INPAR           7
#define INBRACE         8
#define OUTPAR          9
#define DBAR           10
#define DAMPER         11
#define BANG           12
#define OUTBRACE       13
#define OUTANG         14
#define OUTANGBANG     15
#define DOUTANG        16
#define DOUTANGBANG    17
#define INANG          18
#define DINANG         19
#define DINANGDASH     20
#define INANGAMP       21
#define OUTANGAMP      22
#define OUTANGAMPBANG  23
#define DOUTANGAMP     24
#define DOUTANGAMPBANG 25
#define TRINANG        26
#define BAR            27
#define BARAMP         28
#define DINBRACK       29
#define DOUTBRACK      30
#define STRING         31
#define ENVSTRING      32
#define ENVARRAY       33
#define ENDINPUT       34
#define INOUTPAR       35
#define DO             36
#define DONE           37
#define ESAC           38
#define THEN           39
#define ELIF           40
#define ELSE           41
#define FI             42
#define FOR            43
#define CASE           44
#define IF             45
#define WHILE          46
#define FUNC           47
#define REPEAT         48
#define TIME           49
#define UNTIL          50
#define EXEC           51
#define COMMAND        52
#define SELECT         53
#define COPROC         54
#define NOGLOB         55
#define DASH           56
#define NOCORRECT      57
#define FOREACH        58
#define ZEND           59
#define DINPAR         60
#define DOUTPAR        61

#define WRITE           0
#define WRITENOW        1
#define APP             2
#define APPNOW          3
#define MERGEOUT        4
#define MERGEOUTNOW     5
#define ERRAPP          6
#define ERRAPPNOW       7
#define READ            8
#define HEREDOC         9
#define HEREDOCDASH    10
#define HERESTR        11
#define MERGE          12
#define CLOSE          13
#define INPIPE         14
#define OUTPIPE        15
#define NONE           16

#define IS_READFD(X)      ((X)>=READ && (X)<=MERGE)
#define IS_REDIROP(X)     ((X)>=OUTANG && (X)<=TRINANG)
#define IS_ERROR_REDIR(X) ((X)>=MERGEOUT && (X)<=ERRAPPNOW)
#define UN_ERROR_REDIR(X) ((X)-MERGEOUT+WRITE)

#define FD_WORD   -1
#define FD_COPROC -2
#define FD_CLOSE  -3

/* linked list abstract data type */

struct lknode {
    struct lknode *next, *last;
    void *dat;
};
struct lklist {
    struct lknode *first, *last;
};

typedef struct hashtab  *Hashtab;
typedef struct hashnode *Hashnode;
typedef struct schedcmd *Schedcmd;
typedef struct alias    *Alias;
typedef struct process  *Process;
typedef struct job      *Job;
typedef struct value    *Value;
typedef struct arrind   *Arrind;
typedef struct varasg   *Varasg;
typedef struct param    *Param;
typedef struct cmdnam   *Cmdnam;
typedef struct cond     *Cond;
typedef struct cmd      *Cmd;
typedef struct pline    *Pline;
typedef struct sublist  *Sublist;
typedef struct list     *List;
typedef struct lklist   *Lklist;
typedef struct lknode   *Lknode;
typedef struct comp     *Comp;
typedef struct redir    *Redir;
typedef struct complist *Complist;
typedef struct heap     *Heap;
typedef struct heappos  *Heappos;
typedef struct histent  *Histent;
typedef struct compctlp *Compctlp;
typedef struct compctl  *Compctl;
typedef struct compcond *Compcond;
typedef struct forcmd   *Forcmd;

typedef void (*FFunc)   _((void *));
typedef void *(*VFunc)  _((void *));
typedef void (*HFunc)   _((char *, char *));

#define addnode(X,Y) insnode(X,(X)->last,Y)
#define full(X)      ((X)->first != NULL)
#define empty(X)     ((X)->first == NULL)
#define firstnode(X) ((X)->first)
#define getaddrdata(X) (&((X)->dat))
#define getdata(X)   ((X)->dat)
#define setdata(X,Y) ((X)->dat = (Y))
#define lastnode(X)  ((X)->last)
#define nextnode(X)  ((X)->next)
#define prevnode(X)  ((X)->last)
#define peekfirst(X) ((X)->first->dat)
#define pushnode(X,Y) insnode(X,(Lknode) X,Y)
#define incnode(X) (X = nextnode(X))
#define gethistent(X) (histentarr+((X)%histentct))

/* node structure for syntax trees */

/* struct list, struct sublist, struct pline, etc.  all fit the form */
/* of this structure and are used interchangably. The ptrs may hold  */
/* integers or pointers, depending on the type of the node.          */

struct node {
    int type;			/* node type */
};

#define N_LIST    0
#define N_SUBLIST 1
#define N_PLINE   2
#define N_CMD     3
#define N_REDIR   4
#define N_COND    5
#define N_FOR     6
#define N_CASE    7
#define N_IF      8
#define N_WHILE   9
#define N_VARASG 10
#define N_COUNT  11

/* values for types[4] */

#define NT_EMPTY 0
#define NT_NODE  1
#define NT_STR   2
#define NT_LIST  4
#define NT_ARR   8

#define NT_TYPE(T) ((T) & 0xff)
#define NT_N(T, N) (((T) >> (8 + (N) * 4)) & 0xf)
#define NT_SET(T0, N, T1, T2, T3, T4) \
    ((T0) | ((N) << 24) | \
     ((T1) << 8) | ((T2) << 12) | ((T3) << 16) | ((T4) << 20))
#define NT_NUM(T) (((T) >> 24) & 7)
#define NT_HEAP   (1 << 30)

/* tree element for lists */

struct list {
    int ntype;
    int type;
    Sublist left;
    List right;
};

#define Z_SYNC  0		/* ; */
#define Z_ASYNC 1		/* & */
#define Z_TIMED 2

/* tree element for sublists */

struct sublist {
    int ntype;
    int type;
    int flags;			/* see PFLAGs below */
    Pline left;
    Sublist right;
};

#define ORNEXT  10		/* || */
#define ANDNEXT 11		/* && */

#define PFLAG_NOT     1		/* ! ... */
#define PFLAG_COPROC 32		/* coproc ... */

/* tree element for pipes */

struct pline {
    int ntype;
    int type;
    Cmd left;
    Pline right;
};

#define END	0		/* pnode *right is null                     */
#define PIPE	1		/* pnode *right is the rest of the pipeline */

/* tree element for commands */

struct cmd {
    int ntype;
    int type;
    int flags;			/* see CFLAGs below                    */
    int lineno;			/* lineno of script for command        */
    Lklist args;		/* command & argmument List (char *'s) */
    union {
	List list;		/* for SUBSH/CURSH/SHFUNC              */
	Forcmd forcmd;
	struct casecmd *casecmd;
	struct ifcmd *ifcmd;
	struct whilecmd *whilecmd;
	Sublist pline;
	Cond cond;
	void *generic;
    } u;
    Lklist redir;		/* i/o redirections (struct redir *'s)   */
    Lklist vars;		/* param assignments (struct varasg *'s) */
};

#define SIMPLE   0
#define SUBSH    1
#define CURSH    2
#define ZCTIME   3
#define FUNCDEF  4
#define CFOR     5
#define CWHILE   6
#define CREPEAT  7
#define CIF      8
#define CCASE    9
#define CSELECT 10
#define COND    11

#define CFLAG_EXEC    1		/* exec ...    */
#define CFLAG_COMMAND 2		/* command ... */
#define CFLAG_NOGLOB  4		/* noglob ...  */
#define CFLAG_DASH    8		/* - ...       */

/* tree element for redirection lists */

struct redir {
    int ntype;
    int type, fd1, fd2;
    char *name;
};

/* tree element for conditionals */

struct cond {
    int ntype;
    int type;		/* can be cond_type, or a single letter (-a, -b, ...) */
    void *left, *right;
};

#define COND_NOT    0
#define COND_AND    1
#define COND_OR     2
#define COND_STREQ  3
#define COND_STRNEQ 4
#define COND_STRLT  5
#define COND_STRGTR 6
#define COND_NT     7
#define COND_OT     8
#define COND_EF     9
#define COND_EQ    10
#define COND_NE    11
#define COND_LT    12
#define COND_GT    13
#define COND_LE    14
#define COND_GE    15

struct forcmd {			/* for/select */
/* Cmd->args contains list of words to loop thru */
    int ntype;
    int inflag;			/* if there is an in ... clause       */
    char *name;			/* parameter to assign values to      */
    List list;			/* list to look through for each name */
};

struct casecmd {
/* Cmd->args contains word to test */
    int ntype;
    char **pats;
    List *lists;		/* list to execute */
};

/********************************************************************** 
 *                                                                    * 
 *  a command like "if foo then bar elif baz then fubar else fooble"  * 
 *  generates a tree like:                                            * 
 *                                                                    * 
 *  struct ifcmd a = { next =  &b,  ifl = "foo", thenl = "bar" }      * 
 *  struct ifcmd b = { next =  &c,  ifl = "baz", thenl = "fubar" }    * 
 *  struct ifcmd c = { next = NULL, ifl = NULL, thenl = "fooble" }    * 
 *                                                                    * 
 **********************************************************************/

struct ifcmd {
    int ntype;
    List *ifls;
    List *thenls;
};

struct whilecmd {
    int ntype;
    int cond;			/* 0 for while, 1 for until            */
    List cont;			/* condition                           */
    List loop;			/* list to execute until condition met */
};

/* A multio is a list of fds associated with a certain fd.       */
/* Thus if you do "foo >bar >ble", the multio for fd 1 will have */
/* two fds, the result of open("bar",...), and the result of     */
/* open("ble",....).                                             */

/* structure used for multiple i/o redirection */
/* one for each fd open                        */

struct multio {
    int ct;			/* # of redirections on this fd                 */
    int rflag;			/* 0 if open for reading, 1 if open for writing */
    int pipe;			/* fd of pipe if ct > 1                         */
    int fds[OPEN_MAX];		/* list of src/dests redirected to/from this fd */
};

/* node used in command path hash table (cmdnamtab) */

struct cmdnam {
    struct hashnode *next;
    char *nam;			/* hash data */
    int flags;
    union {
	char **name;		/* full pathname if !(flags & BUILTIN) */
	char *cmd;		/* file name for hashed commands       */
	int binnum;		/* func to exec if type & BUILTIN      */
	List list;		/* list to exec if type & SHFUNC       */
    }
    u;
};

#define EXCMD        0x10000
#define BUILTIN      0x20000
#define SHFUNC       0x40000
#define DISABLED     0x80000
#define HASHCMD      (EXCMD | BUILTIN)

#define ISEXCMD(X) ((X) & EXCMD)

/* node used in parameter hash table (paramtab) */

struct param {
    struct hashnode *next;
    char *nam;			/* hash data */
    union {
	char **arr;		/* value if declared array           */
	char *str;		/* value if declared string (scalar) */
	long val;		/* value if declared integer         */
    }
    u;
    union {			/* functions to call to set value */
	void (*cfn) _((Param, char *));
	void (*ifn) _((Param, long));
	void (*afn) _((Param, char **));
    }
    sets;
    union {			/* functions to call to get value */
	char *(*cfn) _((Param));
	long (*ifn) _((Param));
	char **(*afn) _((Param));
    }
    gets;
    int ct;			/* output base or field width            */
    int flags;
    void *data;			/* used by getfns                        */
    char *env;			/* location in environment, if exported  */
    char *ename;		/* name of corresponding environment var */
    Param old;			/* old struct for use with local         */
    int level;			/* if (old != NULL), level of localness  */
};

/* flags for parameters */

#define PMFLAG_s           0	/* scalar                                     */
#define PMFLAG_L           1	/* left justify and remove leading blanks     */
#define PMFLAG_R           2	/* right justify and fill with leading blanks */
#define PMFLAG_Z           4	/* right justify and fill with leading zeros  */
#define PMFLAG_i           8	/* integer                                    */
#define PMFLAG_l          16	/* all lower case                             */
#define PMFLAG_u          32	/* all upper case                             */
#define PMFLAG_r          64	/* readonly                                   */
#define PMFLAG_t         128	/* tagged                                     */
#define PMFLAG_x         256	/* exported                                   */
#define PMFLAG_A         512	/* array                                      */
#define PMFLAG_SPECIAL	1024
#define PMFLAG_UNSET	2048
#define PMTYPE (PMFLAG_i|PMFLAG_A)
#define pmtype(X) ((X)->flags & PMTYPE)

#define MAX_ARRLEN    262144

/* variable assignment tree element */

struct varasg {
    int ntype;
    int type;			/* nonzero means array                   */
    char *name;
    char *str;			/* should've been a union here.  oh well */
    Lklist arr;
};

/* lvalue for variable assignment/expansion */

struct value {
    int isarr;
    struct param *pm;		/* parameter node                      */
    int inv;			/* should we return the index ?        */
    int a;			/* first element of array slice, or -1 */
    int b;			/* last element of array slice, or -1  */
};

struct fdpair {
    int fd1, fd2;
};

/* tty state structure */

struct ttyinfo {
#ifdef HAVE_TERMIOS_H
    struct termios tio;
#else
# ifdef HAVE_TERMIO_H
    struct termio tio;
# else
    struct sgttyb sgttyb;
    int lmodes;
    struct tchars tchars;
    struct ltchars ltchars;
# endif
#endif
#ifdef TIOCGWINSZ
    struct winsize winsize;
#endif
};

/* entry in job table */

struct job {
    pid_t gleader;		/* process group leader of this job  */
    pid_t other;		/* subjob id or subshell pid         */
    int stat;                   /* see STATs below                   */
    char *pwd;			/* current working dir of shell when *
				 * this job was spawned              */
    struct process *procs;	/* list of processes                 */
    Lklist filelist;		/* list of files to delete when done */
    int stty_in_env;		/* if STTY=... is present            */
    struct ttyinfo *ty;		/* the modes specified by STTY       */
};

#define STAT_CHANGED    1	/* status changed and not reported      */
#define STAT_STOPPED    2	/* all procs stopped or exited          */
#define STAT_TIMED      4	/* job is being timed                   */
#define STAT_DONE       8       /* job is done                          */
#define STAT_LOCKED    16	/* shell is finished creating this job, */
                                /*   may be deleted from job table      */
#define STAT_NOPRINT   32	/* job was killed internally,           */
                                /*   we don't want to show that         */
#define STAT_INUSE     64	/* this job entry is in use             */
#define STAT_SUPERJOB 128	/* job has a subjob                     */
#define STAT_SUBJOB   256	/* job is a subjob                      */
#define STAT_CURSH    512	/* last command is in current shell     */

#define SP_RUNNING -1		/* fake status for jobs currently running */

struct timeinfo {
    long ut;                    /* user space time   */
    long st;                    /* system space time */
};

/* node in job process lists */

#define JOBTEXTSIZE 80

struct process {
    struct process *next;
    pid_t pid;                  /* process id                       */
    char text[JOBTEXTSIZE];	/* text to print when 'jobs' is run */
    int status;			/* return code from waitpid/wait3() */
    struct timeinfo ti;
    struct timeval bgtime;	/* time job was spawned             */
    struct timeval endtime;	/* time job exited                  */
};

/* node in alias hash table */

struct alias {
    struct hashnode *next;
    char *nam;			/* hash data                */
    char *text;			/* expansion of alias       */
    int cmd;			/* zero for global aliases, */
				/* one for regular aliases  */
    int inuse;			/* alias is being expanded  */
};

/* node in shell reserved word hash table */

struct reswd {
    struct hashnode *next;
    char *nam;			/* name of reserved word */
    int cmd;			/* corresponding token   */
};

/* node in sched list */

struct schedcmd {
    struct schedcmd *next;
    char *cmd;			/* command to run */
    time_t time;		/* when to run it */
};

#define MAXAL 20		/* maximum number of aliases expanded at once */

/* hash table node */

struct hashnode {
    struct hashnode *next;
    char *nam;
};

/* hash table */

struct hashtab {
    int hsize;			/* size of nodes[]     */
    int ct;			/* # of elements       */
    struct hashnode **nodes;	/* array of size hsize */
};

/* history entry */

struct histent {
    char *lex;			/* lexical history line             */
    char *lit;			/* literal history line             */
    time_t stim;		/* command started time (datestamp) */
    time_t ftim;		/* command finished time            */
    int flags;			/* Misc flags                       */
};

#define HIST_OLD	0x00000001	/* Command is already written to disk*/

/* completion control */

struct compcond {
    struct compcond *and, *or;	/* the next or'ed/and'ed conditions      */
    int type, n;		/* the type (CCT_*) and the array length */
    union {			/* these structs hold the data used to   */
	struct {		/* test this condition                   */
	    int *a, *b;		/* CCT_POS, CCT_NUMWORDS                 */
	}
	r;
	struct {		/* CCT_CURSTR, CCT_CURPAT,... */
	    int *p;
	    char **s;
	}
	s;
	struct {		/* CCT_RANGESTR,... */
	    char **a, **b;
	}
	l;
    }
    u;
};

#define CCT_UNUSED     0
#define CCT_POS        1
#define CCT_CURSTR     2
#define CCT_CURPAT     3
#define CCT_WORDSTR    4
#define CCT_WORDPAT    5
#define CCT_CURSUF     6
#define CCT_CURPRE     7
#define CCT_CURSUB     8
#define CCT_CURSUBC    9
#define CCT_NUMWORDS  10
#define CCT_RANGESTR  11
#define CCT_RANGEPAT  12

struct compctlp {		/* the hash table node for compctls */
    struct hashnode *next;
    char *nam;			/* command name                     */
    Compctl cc;			/* pointer to the compctl desc.     */
};

struct compctl {		/* the real desc. for compctls             */
    int refc;			/* reference count                         */
    struct compctl *next;	/* next compctl for -x                     */
    unsigned long mask;		/* mask of things to complete (CC_*)       */
    char *keyvar;		/* for -k (variable)                       */
    char *glob;			/* for -g (globbing)                       */
    char *str;			/* for -s (expansion)                      */
    char *func;			/* for -K (function)                       */
    char *explain;		/* for -X (explanation)                    */
    char *prefix, *suffix;	/* for -P and -S (prefix, suffix)          */
    char *subcmd;		/* for -l (command name to use)            */
    char *hpat;			/* for -H (history pattern)                */
    int hnum;			/* for -H (number of events to search)     */
    struct compctl *ext;	/* for -x (first of the compctls after -x) */
    struct compcond *cond;	/* for -x (condition for this compctl)     */
    struct compctl *xor;	/* for + (next of the xor'ed compctls)     */
};

#define CC_FILES	(1<<0)
#define CC_COMMPATH	(1<<1)
#define CC_REMOVE       (1<<2)
#define CC_OPTIONS	(1<<3)
#define CC_VARS		(1<<4)
#define CC_BINDINGS	(1<<5)
#define CC_ARRAYS	(1<<6)
#define CC_INTVARS	(1<<7)
#define CC_FUNCS	(1<<8)
#define CC_PARAMS	(1<<9)
#define CC_ENVVARS	(1<<10)
#define CC_JOBS		(1<<11)
#define CC_RUNNING	(1<<12)
#define CC_STOPPED	(1<<13)
#define CC_BUILTINS	(1<<14)
#define CC_ALREG	(1<<15)
#define CC_ALGLOB	(1<<16)
#define CC_USERS	(1<<17)
#define CC_DISCMDS	(1<<18)
#define CC_EXCMDS	(1<<19)
#define CC_SCALARS	(1<<20)
#define CC_READONLYS    (1<<21)
#define CC_SPECIALS	(1<<22)
#define CC_DELETE       (1<<23)
#define CC_NAMED        (1<<24)

#define CC_RESERVED     (1<<31)

/* values in opts[] array */

#define OPT_UNSET   0
#define OPT_INVALID 1		/* opt is invalid, like -$ */
#define OPT_SET     2

/* the options */

struct option {
    char *name;
    char id;			/* corresponding letter */
};

#define OPT_SIZE 128

#define CORRECT             '0'
#define NOCLOBBER           '1'
#define NOBADPATTERN        '2'
#define NONOMATCH           '3'
#define GLOBDOTS            '4'
#define NOTIFY              '5'
#define BGNICE              '6'
#define IGNOREEOF           '7'
#define MARKDIRS            '8'
#define AUTOLIST            '9'
#define NOBEEP              'B'
#define PRINTEXITVALUE      'C'
#define PUSHDTOHOME         'D'
#define PUSHDSILENT         'E'
#define NOGLOBOPT           'F'
#define NULLGLOB            'G'
#define RMSTARSILENT        'H'
#define IGNOREBRACES        'I'
#define AUTOCD              'J'
#define NOBANGHIST          'K'
#define SUNKEYBOARDHACK     'L'
#define SINGLELINEZLE       'M'
#define AUTOPUSHD           'N'
#define CORRECTALL          'O'
#define RCEXPANDPARAM       'P'
#define PATHDIRS            'Q'
#define LONGLISTJOBS        'R'
#define RECEXACT            'S'
#define CDABLEVARS          'T'
#define MAILWARNING         'U'
#define NOPROMPTCR          'V'
#define AUTORESUME          'W'
#define LISTTYPES           'X'
#define MENUCOMPLETE        'Y'
#define USEZLE              'Z'
#define ALLEXPORT           'a'
#define ERREXIT             'e'
#define NORCS               'f'
#define HISTIGNORESPACE     'g'
#define HISTIGNOREDUPS      'h'
#define INTERACTIVE         'i'
#define HISTLIT             'j'
#define INTERACTIVECOMMENTS 'k'
#define LOGINSHELL          'l'
#define MONITOR             'm'
#define NOEXEC              'n'
#define PRIVILEGED          'p'
#define SHINSTDIN           's'
#define NOUNSET             'u'
#define VERBOSE             'v'
#define CHASELINKS          'w'
#define XTRACE              'x'
#define SHWORDSPLIT         'y'
#define HISTNOSTORE         '\3'
#define EXTENDEDGLOB        '\5'
#define GLOBCOMPLETE        '\6'
#define CSHJUNKIEQUOTES     '\7'
#define PUSHDMINUS          '\10'
#define CSHJUNKIELOOPS      '\11'
#define RCQUOTES            '\12'
#define KSHOPTIONPRINT      '\13'
#define NOSHORTLOOPS        '\14'
#define COMPLETEINWORD      '\15'
#define AUTOMENU            '\16'
#define HISTVERIFY          '\17'
#define NOLISTBEEP          '\20'
#define NOHUP               '\21'
#define NOEQUALS            '\22'
#define CSHNULLGLOB         '\23'
#define HASHCMDS            '\24'
#define HASHDIRS            '\25'
#define NUMERICGLOBSORT     '\26'
#define BRACECCL            '\27'
#define HASHLISTALL         '\30'
#define OVERSTRIKE          '\31'
#define NOHISTBEEP          '\32'
#define PUSHDIGNOREDUPS     '\33'
#define AUTOREMOVESLASH     '\34'
#define EXTENDEDHISTORY     '\35'
#define APPENDHISTORY       '\36'
#define CSHJUNKIEHISTORY    '\037'
#define MAGICEQUALSUBST     '\040'
#define GLOBSUBST           '\041'
#define PROMPTSUBST         '\043'
#define ALWAYSLASTPROMPT    '\044'
#define COMPLETEALIASES     '\045'
#define AUTOPARAMKEYS       '\046'
#define ALWAYSTOEND         '\047'
#define NOFLOWCONTROL       '\050'
#define LISTAMBIGUOUS       '\051'
#define AUTONAMEDIRS        '\052'
#define CSHJUNKIEPAREN      '\053'
#define HISTALLOWCLOBBER    '\054'
#define AUTOPARAMSLASH      '\055'
#define LOCALOPTIONS        '\056'
#define BSDECHO             '\057'

#define ALSTAT_MORE 1		/* last alias ended with ' '      */
#define ALSTAT_JUNK 2		/* don't put word in history List */

#undef  isset
#define isset(X) (opts[(int)X] == OPT_SET)
#define unset(X) (opts[(int)X] == OPT_UNSET)
#define interact (isset(INTERACTIVE))
#define jobbing  (isset(MONITOR))
#define jobbingv opts[MONITOR]
#define islogin  (isset(LOGINSHELL))

/* named directories */

typedef struct nameddirs *Nameddirs;

struct nameddirs {
    int len;			/* length of path namdirs[t0].dir */
    int namelen;		/* length of name                 */
    char *name;
    char *dir;
    int homedir;		/* is this name a home directory? */
};

/* interesting termcap strings */

#define TCCLEARSCREEN   0
#define TCLEFT          1
#define TCMULTLEFT      2
#define TCRIGHT         3
#define TCMULTRIGHT     4
#define TCUP            5
#define TCMULTUP        6
#define TCDOWN          7
#define TCMULTDOWN      8
#define TCDEL           9
#define TCMULTDEL      10
#define TCINS          11
#define TCMULTINS      12
#define TCCLEAREOD     13
#define TCCLEAREOL     14
#define TCINSLINE      15
#define TCDELLINE      16
#define TCNEXTTAB      17
#define TCBOLDFACEBEG  18
#define TCSTANDOUTBEG  19
#define TCUNDERLINEBEG 20
#define TCALLATTRSOFF  21
#define TCSTANDOUTEND  22
#define TCUNDERLINEEND 23
#define TC_COUNT       24

#define tccan(X) (tclen[X])

#define TXTBOLDFACE   0x01
#define TXTSTANDOUT   0x02
#define TXTUNDERLINE  0x04
#define TXTDIRTY      0x80

#define txtisset(X)  (txtattrmask & (X))
#define txtset(X)    (txtattrmask |= (X))
#define txtunset(X)  (txtattrmask &= ~(X))

#define TXTNOBOLDFACE	0x10
#define TXTNOSTANDOUT	0x20
#define TXTNOUNDERLINE	0x40

#define txtchangeisset(X)	(txtchange & (X))
#define txtchangeset(X, Y)	(txtchange |= (X), txtchange &= ~(Y))

#define HISTFLAG_DONE   1
#define HISTFLAG_NOEXEC 2
#define HISTFLAG_RECALL 4

#include "ztype.h"

/* structure for foo=bar assignments */
struct asgment {
    struct asgment *next;
    char *name, *value;
};
 
#define cmdpush(X) if (!(cmdsp >= 0 && cmdsp < 256)) {;} else cmdstack[cmdsp++]=(X)
#define cmdpop()   if (cmdsp <= 0) {;} else cmdsp--

#define CS_FOR          0
#define CS_WHILE        1
#define CS_REPEAT       2
#define CS_SELECT       3
#define CS_UNTIL        4
#define CS_IF           5
#define CS_IFTHEN       6
#define CS_ELSE         7
#define CS_ELIF         8
#define CS_MATH         9
#define CS_COND        10
#define CS_CMDOR       11
#define CS_CMDAND      12
#define CS_PIPE        13
#define CS_ERRPIPE     14
#define CS_FOREACH     15
#define CS_CASE        16
#define CS_FUNCDEF     17
#define CS_SUBSH       18
#define CS_CURSH       19
#define CS_ARRAY       20
#define CS_QUOTE       21
#define CS_DQUOTE      22
#define CS_BQUOTE      23
#define CS_CMDSUBST    24
#define CS_MATHSUBST   25
#define CS_ELIFTHEN    26
#define CS_HEREDOC     27
#define CS_HEREDOCD    28

/* shared header files */

#include "version.h"
#include "signals.h"
#include "globals.h"
#include "prototypes.h"
