summary refs log tree commit diff
path: root/Src/zsh.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/zsh.h')
-rw-r--r--Src/zsh.h964
1 files changed, 677 insertions, 287 deletions
diff --git a/Src/zsh.h b/Src/zsh.h
index e96fc6e86..35b9c6737 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -31,15 +31,75 @@
 #define zleread(X,Y,H)  zlereadptr(X,Y,H)
 #define spaceinline(X)  spaceinlineptr(X)
 #define gotword()       gotwordptr()
-#define refresh()       refreshptr()
+#define zrefresh()      refreshptr()
 
 #define compctlread(N,A,O,R) compctlreadptr(N,A,O,R)
 
 /* A few typical macros */
 #define minimum(a,b)  ((a) < (b) ? (a) : (b))
 
+/*
+ * Our longest integer type:  will be a 64 bit either if long already is,
+ * or if we found some alternative such as long long.
+ * Currently we only define this to be longer than a long if --enable-lfs
+ * was given.  That enables internal use of 64-bit types even if
+ * no actual large file support is present.
+ */
+#ifdef ZSH_64_BIT_TYPE
+typedef ZSH_64_BIT_TYPE zlong;
+#ifdef ZSH_64_BIT_UTYPE
+typedef ZSH_64_BIT_UTYPE zulong;
+#else
+typedef unsigned zlong zulong;
+#endif
+#else
+typedef long zlong;
+typedef unsigned long zulong;
+#endif
+
+/*
+ * Double float support requires 64-bit alignment, so if longs and
+ * pointers are less we need to pad out.
+ */
+#ifndef LONG_IS_64_BIT
+# define PAD_64_BIT 1
+#endif
+
 /* math.c */
-typedef int LV;
+typedef struct {
+    union {
+	zlong l;
+	double d;
+    } u;
+    int type;
+} mnumber;
+
+#define MN_INTEGER 1		/* mnumber is integer */
+#define MN_FLOAT   2		/* mnumber is floating point */
+
+typedef struct mathfunc *MathFunc;
+typedef mnumber (*NumMathFunc)(char *, int, mnumber *, int);
+typedef mnumber (*StrMathFunc)(char *, char *, int);
+
+struct mathfunc {
+    MathFunc next;
+    char *name;
+    int flags;
+    NumMathFunc nfunc;
+    StrMathFunc sfunc;
+    char *module;
+    int minargs;
+    int maxargs;
+    int funcid;
+};
+
+#define MFF_STR      1
+#define MFF_ADDED    2
+
+#define NUMMATHFUNC(name, func, min, max, id) \
+    { NULL, name, 0, func, NULL, NULL, min, max, id }
+#define STRMATHFUNC(name, func, id) \
+    { NULL, name, MFF_STR, NULL, func, NULL, 0, 0, id }
 
 /* Character tokens are sometimes casted to (unsigned char)'s.         * 
  * Unfortunately, some compilers don't correctly cast signed to        * 
@@ -207,6 +267,7 @@ enum {
 #define INP_HIST      (1<<2)	/* expanding history                       */
 #define INP_CONT      (1<<3)	/* continue onto previously stacked input  */
 #define INP_ALCONT    (1<<4)	/* stack is continued from alias expn.     */
+#define INP_LINENO    (1<<5)    /* update line number                      */
 
 /* Flags for metafy */
 #define META_REALLOC	0
@@ -228,34 +289,33 @@ typedef struct linklist  *LinkList;
 typedef struct hashnode  *HashNode;
 typedef struct hashtable *HashTable;
 
+typedef struct optname   *Optname;
 typedef struct reswd     *Reswd;
 typedef struct alias     *Alias;
 typedef struct param     *Param;
+typedef struct paramdef  *Paramdef;
 typedef struct cmdnam    *Cmdnam;
 typedef struct shfunc    *Shfunc;
+typedef struct funcstack *Funcstack;
+typedef struct funcwrap  *FuncWrap;
 typedef struct builtin   *Builtin;
 typedef struct nameddir  *Nameddir;
 typedef struct module    *Module;
+typedef struct linkedmod *Linkedmod;
 
+typedef struct patprog   *Patprog;
 typedef struct process   *Process;
 typedef struct job       *Job;
 typedef struct value     *Value;
-typedef struct varasg    *Varasg;
-typedef struct cond      *Cond;
-typedef struct cmd       *Cmd;
-typedef struct pline     *Pline;
-typedef struct sublist   *Sublist;
-typedef struct list      *List;
-typedef struct comp      *Comp;
+typedef struct conddef   *Conddef;
 typedef struct redir     *Redir;
 typedef struct complist  *Complist;
 typedef struct heap      *Heap;
 typedef struct heapstack *Heapstack;
 typedef struct histent   *Histent;
-typedef struct forcmd    *Forcmd;
-typedef struct autofn    *AutoFn;
+typedef struct hookdef   *Hookdef;
 
-typedef struct asgment  *Asgment;
+typedef struct asgment   *Asgment;
 
 
 /********************************/
@@ -277,167 +337,57 @@ struct linklist {
 
 /* Macros for manipulating link lists */
 
-#define addlinknode(X,Y) insertlinknode(X,(X)->last,Y)
-#define uaddlinknode(X,Y) uinsertlinknode(X,(X)->last,Y)
-#define empty(X)     ((X)->first == NULL)
-#define nonempty(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) insertlinknode(X,(LinkNode) X,Y)
-#define incnode(X) (X = nextnode(X))
-#define gethistent(X) (histentarr+((X)%histentct))
-
+#define addlinknode(X,Y)    insertlinknode(X,(X)->last,Y)
+#define zaddlinknode(X,Y)   zinsertlinknode(X,(X)->last,Y)
+#define uaddlinknode(X,Y)   uinsertlinknode(X,(X)->last,Y)
+#define empty(X)            ((X)->first == NULL)
+#define nonempty(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)       insertlinknode(X,(LinkNode) X,Y)
+#define zpushnode(X,Y)      zinsertlinknode(X,(LinkNode) X,Y)
+#define incnode(X)          (X = nextnode(X))
+#define firsthist()         (hist_ring? hist_ring->down->histnum : curhist)
+#define setsizednode(X,Y,Z) ((X)->first[(Y)].dat = (void *) (Z))
+
+/* stack allocated linked lists */
+
+#define local_list0(N) struct linklist N
+#define init_list0(N) \
+    do { \
+        (N).first = NULL; \
+        (N).last = (LinkNode) &(N); \
+    } while (0)
+#define local_list1(N) struct linklist N; struct linknode __n0
+#define init_list1(N,V0) \
+    do { \
+        (N).first = &__n0; \
+        (N).last = &__n0; \
+        __n0.next = NULL; \
+        __n0.last = (LinkNode) &(N); \
+        __n0.dat = (void *) (V0); \
+    } while (0)
 
 /********************************/
 /* Definitions 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.          */
-
-/* Generic node structure for syntax trees */
-struct node {
-    int ntype;			/* 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_AUTOFN 11
-#define N_COUNT  12
-
-/* 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, T1, T2, T3, T4) \
-    ((T0) | ((T1) << 8) | ((T2) << 12) | ((T3) << 16) | ((T4) << 20))
-#define NT_HEAP   (1 << 30)
-
-/* tree element for lists */
-
-struct list {
-    int ntype;			/* node type */
-    int type;
-    Sublist left;
-    List right;
-};
-
 /* These are control flags that are passed *
  * down the execution pipeline.            */
-#define Z_TIMED	(1<<0)	/* pipeline is being timed                   */
-#define Z_SYNC	(1<<1)	/* run this sublist synchronously       (;)  */
-#define Z_ASYNC	(1<<2)	/* run this sublist asynchronously      (&)  */
+#define Z_TIMED	 (1<<0)	/* pipeline is being timed                   */
+#define Z_SYNC	 (1<<1)	/* run this sublist synchronously       (;)  */
+#define Z_ASYNC  (1<<2)	/* run this sublist asynchronously      (&)  */
 #define Z_DISOWN (1<<3)	/* run this sublist without job control (&|) */
+/* (1<<4) is used for Z_END, see the wordcode definitions */
+/* (1<<5) is used for Z_SIMPLE, see the wordcode definitions */
 
-/* tree element for sublists */
-
-struct sublist {
-    int ntype;			/* node type */
-    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;			/* node type */
-    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;			/* node type                    */
-    int type;
-    int flags;			/* see CFLAGs below             */
-    int lineno;			/* lineno of script for command */
-    union {
-	List list;		/* for SUBSH/CURSH/SHFUNC       */
-	Forcmd forcmd;
-	struct casecmd *casecmd;
-	struct ifcmd *ifcmd;
-	struct whilecmd *whilecmd;
-	Sublist pline;
-	Cond cond;
-	AutoFn autofn;
-	void *generic;
-    } u;
-    LinkList args;		/* command & argmument List (char *'s)   */
-    LinkList redir;		/* i/o redirections (struct redir *'s)   */
-    LinkList vars;		/* param assignments (struct varasg *'s) */
-};
-
-/* cmd types */
-#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 CARITH  12
-#define AUTOFN  13
-
-/* flags for command modifiers */
-#define CFLAG_EXEC	(1<<0)	/* exec ...    */
-
-/* tree element for redirection lists */
-
-struct redir {
-    int ntype;			/* node type */
-    int type;
-    int fd1, fd2;
-    char *name;
-};
-
-/* tree element for conditionals */
-
-struct cond {
-    int ntype;		/* node type                     */
-    int type;		/* can be cond_type, or a single */
-			/* letter (-a, -b, ...)          */
-    void *left, *right;
-};
+/* Condition types. */
 
 #define COND_NOT    0
 #define COND_AND    1
@@ -455,50 +405,34 @@ struct cond {
 #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;			/* node type                          */
-    int inflag;			/* if there is an in ... clause       */
-    char *name;			/* initializer or parameter name      */
-    char *condition;		/* arithmetic terminating condition   */
-    char *advance;		/* evaluated after each loop          */
-    List list;			/* list to look through for each name */
-};
-
-struct casecmd {
-/* Cmd->args contains word to test */
-    int ntype;			/* node type       */
-    char **pats;
-    List *lists;		/* list to execute */
+#define COND_MOD   16
+#define COND_MODI  17
+
+typedef int (*CondHandler) _((char **, int));
+
+struct conddef {
+    Conddef next;		/* next in list                       */
+    char *name;			/* the condition name                 */
+    int flags;			/* see CONDF_* below                  */
+    CondHandler handler;	/* handler function                   */
+    int min;			/* minimum number of strings          */
+    int max;			/* maximum number of strings          */
+    int condid;			/* for overloading handler functions  */
+    char *module;		/* module to autoload                 */
 };
 
+#define CONDF_INFIX  1
+#define CONDF_ADDED  2
 
-/*  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;			/* node type */
-    List *ifls;
-    List *thenls;
-};
+#define CONDDEF(name, flags, handler, min, max, condid) \
+    { NULL, name, flags, handler, min, max, condid, NULL }
 
-struct whilecmd {
-    int ntype;			/* node type                           */
-    int cond;			/* 0 for while, 1 for until            */
-    List cont;			/* condition                           */
-    List loop;			/* list to execute until condition met */
-};
-
-/* node for autoloading functions */
+/* tree element for redirection lists */
 
-struct autofn {
-    int ntype;			/* node type                             */
-    Shfunc shf;			/* the shell function to define	         */
+struct redir {
+    int type;
+    int fd1, fd2;
+    char *name;
 };
 
 /* The number of fds space is allocated for  *
@@ -520,14 +454,12 @@ struct multio {
     int fds[MULTIOUNIT];	/* list of src/dests redirected to/from this fd */
 };
 
-/* variable assignment tree element */
+/* structure for foo=bar assignments */
 
-struct varasg {
-    int ntype;			/* node type                             */
-    int type;			/* nonzero means array                   */
+struct asgment {
+    struct asgment *next;
     char *name;
-    char *str;			/* should've been a union here.  oh well */
-    LinkList arr;
+    char *value;
 };
 
 /* lvalue for variable assignment/expansion */
@@ -538,18 +470,191 @@ struct value {
     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  */
+    char **arr;		/* cache for hash turned into array */
 };
 
-/* structure for foo=bar assignments */
+#define MAX_ARRLEN    262144
 
-struct asgment {
-    struct asgment *next;
-    char *name;
-    char *value;
+/********************************************/
+/* Defintions for word code                 */
+/********************************************/
+
+typedef unsigned int wordcode;
+typedef wordcode *Wordcode;
+
+typedef struct funcdump *FuncDump;
+typedef struct eprog *Eprog;
+
+struct funcdump {
+    FuncDump next;		/* next in list */
+    char *name;			/* path name */
+    int fd;			/* file descriptor */
+    Wordcode map;		/* pointer to header */
+    Wordcode addr;		/* mapped region */
+    int len;			/* length */
+    int count;			/* reference count */
 };
 
-#define MAX_ARRLEN    262144
+struct eprog {
+    int flags;			/* EF_* below */
+    int len;			/* total block length */
+    int npats;			/* Patprog cache size */
+    Patprog *pats;		/* the memory block, the patterns */
+    Wordcode prog;		/* memory block ctd, the code */
+    char *strs;			/* memory block ctd, the strings */
+    Shfunc shf;			/* shell function for autoload */
+    FuncDump dump;		/* dump file this is in */
+};
+
+#define EF_REAL 1
+#define EF_HEAP 2
+#define EF_MAP  4
+#define EF_RUN  8
+
+typedef struct estate *Estate;
+
+struct estate {
+    Eprog prog;			/* the eprog executed */
+    Wordcode pc;		/* program counter, current pos */
+    char *strs;			/* strings from prog */
+};
+
+typedef struct eccstr *Eccstr;
+
+struct eccstr {
+    Eccstr next;
+    char *str;
+    wordcode offs;
+    int nfunc;
+};
 
+#define EC_NODUP  0
+#define EC_DUP    1
+#define EC_DUPTOK 2
+
+#define WC_CODEBITS 5
+
+#define wc_code(C)   ((C) & ((wordcode) ((1 << WC_CODEBITS) - 1)))
+#define wc_data(C)   ((C) >> WC_CODEBITS)
+#define wc_bdata(D)  ((D) << WC_CODEBITS)
+#define wc_bld(C,D)  (((wordcode) (C)) | (((wordcode) (D)) << WC_CODEBITS))
+
+#define WC_END      0
+#define WC_LIST     1
+#define WC_SUBLIST  2
+#define WC_PIPE     3
+#define WC_REDIR    4
+#define WC_ASSIGN   5
+#define WC_SIMPLE   6
+#define WC_SUBSH    7
+#define WC_CURSH    8
+#define WC_TIMED    9
+#define WC_FUNCDEF 10
+#define WC_FOR     11
+#define WC_SELECT  12
+#define WC_WHILE   13
+#define WC_REPEAT  14
+#define WC_CASE    15
+#define WC_IF      16
+#define WC_COND    17
+#define WC_ARITH   18
+#define WC_AUTOFN  19
+
+#define WCB_END()           wc_bld(WC_END, 0)
+
+#define WC_LIST_TYPE(C)     wc_data(C)
+#define Z_END               (1<<4) 
+#define Z_SIMPLE            (1<<5)
+#define WC_LIST_SKIP(C)     (wc_data(C) >> 6)
+#define WCB_LIST(T,O)       wc_bld(WC_LIST, ((T) | ((O) << 6)))
+
+#define WC_SUBLIST_TYPE(C)  (wc_data(C) & ((wordcode) 3))
+#define WC_SUBLIST_END      0
+#define WC_SUBLIST_AND      1
+#define WC_SUBLIST_OR       2
+#define WC_SUBLIST_FLAGS(C) (wc_data(C) & ((wordcode) 0x1c))
+#define WC_SUBLIST_COPROC   4
+#define WC_SUBLIST_NOT      8
+#define WC_SUBLIST_SIMPLE  16
+#define WC_SUBLIST_SKIP(C)  (wc_data(C) >> 5)
+#define WCB_SUBLIST(T,F,O)  wc_bld(WC_SUBLIST, ((T) | (F) | ((O) << 5)))
+
+#define WC_PIPE_TYPE(C)     (wc_data(C) & ((wordcode) 1))
+#define WC_PIPE_END         0
+#define WC_PIPE_MID         1
+#define WC_PIPE_LINENO(C)   (wc_data(C) >> 1)
+#define WCB_PIPE(T,L)       wc_bld(WC_PIPE, ((T) | ((L) << 1)))
+
+#define WC_REDIR_TYPE(C)    wc_data(C)
+#define WCB_REDIR(T)        wc_bld(WC_REDIR, (T))
+
+#define WC_ASSIGN_TYPE(C)   (wc_data(C) & ((wordcode) 1))
+#define WC_ASSIGN_SCALAR    0
+#define WC_ASSIGN_ARRAY     1
+#define WC_ASSIGN_NUM(C)    (wc_data(C) >> 1)
+#define WCB_ASSIGN(T,N)     wc_bld(WC_ASSIGN, ((T) | ((N) << 1)))
+
+#define WC_SIMPLE_ARGC(C)   wc_data(C)
+#define WCB_SIMPLE(N)       wc_bld(WC_SIMPLE, (N))
+
+#define WC_SUBSH_SKIP(C)    wc_data(C)
+#define WCB_SUBSH(O)        wc_bld(WC_SUBSH, (O))
+
+#define WC_CURSH_SKIP(C)    wc_data(C)
+#define WCB_CURSH(O)        wc_bld(WC_CURSH, (O))
+
+#define WC_TIMED_TYPE(C)    wc_data(C)
+#define WC_TIMED_EMPTY      0
+#define WC_TIMED_PIPE       1
+#define WCB_TIMED(T)        wc_bld(WC_TIMED, (T))
+
+#define WC_FUNCDEF_SKIP(C)  wc_data(C)
+#define WCB_FUNCDEF(O)      wc_bld(WC_FUNCDEF, (O))
+
+#define WC_FOR_TYPE(C)      (wc_data(C) & 3)
+#define WC_FOR_PPARAM       0
+#define WC_FOR_LIST         1
+#define WC_FOR_COND         2
+#define WC_FOR_SKIP(C)      (wc_data(C) >> 2)
+#define WCB_FOR(T,O)        wc_bld(WC_FOR, ((T) | ((O) << 2)))
+
+#define WC_SELECT_TYPE(C)   (wc_data(C) & 1)
+#define WC_SELECT_PPARAM    0
+#define WC_SELECT_LIST      1
+#define WC_SELECT_SKIP(C)   (wc_data(C) >> 1)
+#define WCB_SELECT(T,O)     wc_bld(WC_SELECT, ((T) | ((O) << 1)))
+
+#define WC_WHILE_TYPE(C)    (wc_data(C) & 1)
+#define WC_WHILE_WHILE      0
+#define WC_WHILE_UNTIL      1
+#define WC_WHILE_SKIP(C)    (wc_data(C) >> 1)
+#define WCB_WHILE(T,O)      wc_bld(WC_WHILE, ((T) | ((O) << 1)))
+
+#define WC_REPEAT_SKIP(C)   wc_data(C)
+#define WCB_REPEAT(O)       wc_bld(WC_REPEAT, (O))
+
+#define WC_CASE_TYPE(C)     (wc_data(C) & 3)
+#define WC_CASE_HEAD        0
+#define WC_CASE_OR          1
+#define WC_CASE_AND         2
+#define WC_CASE_SKIP(C)     (wc_data(C) >> 2)
+#define WCB_CASE(T,O)       wc_bld(WC_CASE, ((T) | ((O) << 2)))
+
+#define WC_IF_TYPE(C)       (wc_data(C) & 3)
+#define WC_IF_HEAD          0
+#define WC_IF_IF            1
+#define WC_IF_ELIF          2
+#define WC_IF_ELSE          3
+#define WC_IF_SKIP(C)       (wc_data(C) >> 2)
+#define WCB_IF(T,O)         wc_bld(WC_IF, ((T) | ((O) << 2)))
+
+#define WC_COND_TYPE(C)     (wc_data(C) & 127)
+#define WC_COND_SKIP(C)     (wc_data(C) >> 7)
+#define WCB_COND(T,O)       wc_bld(WC_COND, ((T) | ((O) << 7)))
+
+#define WCB_ARITH()         wc_bld(WC_ARITH, 0)
+
+#define WCB_AUTOFN()        wc_bld(WC_AUTOFN, 0)
 
 /********************************************/
 /* Defintions for job table and job control */
@@ -583,9 +688,13 @@ struct job {
 #define STAT_INUSE	(1<<6)	/* this job entry is in use             */
 #define STAT_SUPERJOB	(1<<7)	/* job has a subjob                     */
 #define STAT_SUBJOB	(1<<8)	/* job is a subjob                      */
-#define STAT_CURSH	(1<<9)	/* last command is in current shell     */
-#define STAT_NOSTTY	(1<<10)	/* the tty settings are not inherited   */
+#define STAT_WASSUPER   (1<<9)  /* was a super-job, sub-job needs to be */
+				/* deleted */
+#define STAT_CURSH	(1<<10)	/* last command is in current shell     */
+#define STAT_NOSTTY	(1<<11)	/* the tty settings are not inherited   */
 				/* from this job when it exits.         */
+#define STAT_ATTACH	(1<<12)	/* delay reattaching shell to tty       */
+#define STAT_SUBLEADER  (1<<13) /* is super-job, but leader is sub-shell */
 
 #define SP_RUNNING -1		/* fake status for jobs currently running */
 
@@ -631,7 +740,9 @@ struct execstack {
 
 struct heredocs {
     struct heredocs *next;
-    Redir rd;
+    int type;
+    int pc;
+    char *str;
 };
 
 struct dirsav {
@@ -641,6 +752,8 @@ struct dirsav {
     ino_t ino;
 };
 
+#define MAX_PIPESTATS 256
+
 /*******************************/
 /* Definitions for Hash Tables */
 /*******************************/
@@ -654,10 +767,12 @@ typedef void     (*AddNodeFunc)    _((HashTable, char *, void *));
 typedef HashNode (*GetNodeFunc)    _((HashTable, char *));
 typedef HashNode (*RemoveNodeFunc) _((HashTable, char *));
 typedef void     (*FreeNodeFunc)   _((HashNode));
+typedef int      (*CompareFunc)    _((const char *, const char *));
 
 /* type of function that is passed to *
  * scanhashtable or scanmatchtable    */
 typedef void     (*ScanFunc)       _((HashNode, int));
+typedef void     (*ScanTabFunc)    _((HashTable, ScanFunc, int));
 
 typedef void (*PrintTableStats) _((HashTable));
 
@@ -673,6 +788,7 @@ struct hashtable {
     HashFunc hash;		/* pointer to hash function for this table    */
     TableFunc emptytable;	/* pointer to function to empty table         */
     TableFunc filltable;	/* pointer to function to fill table          */
+    CompareFunc cmpnodes;	/* pointer to function to compare two nodes     */
     AddNodeFunc addnode;	/* pointer to function to add new node        */
     GetNodeFunc getnode;	/* pointer to function to get an enabled node */
     GetNodeFunc getnode2;	/* pointer to function to get node            */
@@ -682,6 +798,7 @@ struct hashtable {
     ScanFunc enablenode;	/* pointer to function to enable a node       */
     FreeNodeFunc freenode;	/* pointer to function to free a node         */
     ScanFunc printnode;		/* pointer to function to print a node        */
+    ScanTabFunc scantab;	/* pointer to function to scan table          */
 
 #ifdef HASHTABLE_INTERNAL_MEMBERS
     HASHTABLE_INTERNAL_MEMBERS	/* internal use in hashtable.c                */
@@ -701,6 +818,15 @@ struct hashnode {
  * reserved words.                                        */
 #define DISABLED	(1<<0)
 
+/* node in shell option table */
+
+struct optname {
+    HashNode next;		/* next in hash chain */
+    char *nam;			/* hash data */
+    int flags;
+    int optno;			/* option number */
+};
+
 /* node in shell reserved word hash table (reswdtab) */
 
 struct reswd {
@@ -746,9 +872,42 @@ struct shfunc {
     HashNode next;		/* next in hash chain     */
     char *nam;			/* name of shell function */
     int flags;			/* various flags          */
-    List funcdef;		/* function definition    */
+    Eprog funcdef;		/* function definition    */
 };
 
+/* Shell function context types. */
+
+#define SFC_NONE     0		/* no function running */
+#define SFC_DIRECT   1		/* called directly from the user */
+#define SFC_SIGNAL   2		/* signal handler */
+#define SFC_HOOK     3		/* one of the special functions */
+#define SFC_WIDGET   4		/* user defined widget */
+#define SFC_COMPLETE 5		/* called from completion code */
+#define SFC_CWIDGET  6		/* new style completion widget */
+
+/* node in function stack */
+
+struct funcstack {
+    Funcstack prev;		/* previous in stack */
+    char *name;			/* name of function called */
+};
+
+/* node in list of function call wrappers */
+
+typedef int (*WrapFunc) _((Eprog, FuncWrap, char *));
+
+struct funcwrap {
+    FuncWrap next;
+    int flags;
+    WrapFunc handler;
+    Module module;
+};
+
+#define WRAPF_ADDED 1
+
+#define WRAPDEF(func) \
+    { NULL, 0, func, NULL }
+
 /* node in builtin command hash table (builtintab) */
 
 typedef int (*HandlerFunc) _((char *, char **, char *, int));
@@ -794,11 +953,87 @@ struct builtin {
 struct module {
     char *nam;
     int flags;
-    void *handle;
+    union {
+	void *handle;
+	Linkedmod linked;
+    } u;
     LinkList deps;
+    int wrapper;
 };
 
 #define MOD_BUSY    (1<<0)
+#define MOD_UNLOAD  (1<<1)
+#define MOD_SETUP   (1<<2)
+#define MOD_LINKED  (1<<3)
+#define MOD_INIT_S  (1<<4)
+#define MOD_INIT_B  (1<<5)
+
+typedef int (*Module_func) _((Module));
+
+struct linkedmod {
+    char *name;
+    Module_func setup;
+    Module_func boot;
+    Module_func cleanup;
+    Module_func finish;
+};
+
+/* C-function hooks */
+
+typedef int (*Hookfn) _((Hookdef, void *));
+
+struct hookdef {
+    Hookdef next;
+    char *name;
+    Hookfn def;
+    int flags;
+    LinkList funcs;
+};
+
+#define HOOKF_ALL 1
+
+#define HOOKDEF(name, func, flags) { NULL, name, (Hookfn) func, flags, NULL }
+
+/*
+ * Types used in pattern matching.  Most of these longs could probably
+ * happily be ints.
+ */
+
+struct patprog {
+    long		startoff;  /* length before start of programme */
+    long		size;	   /* total size from start of struct */
+    long		mustoff;   /* offset to string that must be present */
+    int			globflags; /* globbing flags to set at start */
+    int			globend;   /* globbing flags set after finish */
+    int			flags;	   /* PAT_* flags */
+    int			patmlen;   /* length of pure string or longest match */
+    int			patnpar;   /* number of active parentheses */
+    char		patstartch;
+};
+
+/* Flags used in pattern matchers (Patprog) and passed down to patcompile */
+
+#define PAT_FILE	0x0001	/* Pattern is a file name */
+#define PAT_FILET	0x0002	/* Pattern is top level file, affects ~ */
+#define PAT_ANY		0x0004	/* Match anything (cheap "*") */
+#define PAT_NOANCH	0x0008	/* Not anchored at end */
+#define PAT_NOGLD	0x0010	/* Don't glob dots */
+#define PAT_PURES	0x0020	/* Pattern is a pure string: set internally */
+#define PAT_STATIC	0x0040	/* Don't copy pattern to heap as per default */
+#define PAT_SCAN	0x0080	/* Scanning, so don't try must-match test */
+#define PAT_ZDUP        0x0100  /* Copy pattern in real memory */
+
+/* Globbing flags: lower 8 bits gives approx count */
+#define GF_LCMATCHUC	0x0100
+#define GF_IGNCASE	0x0200
+#define GF_BACKREF	0x0400
+#define GF_MATCHREF	0x0800
+
+/* Dummy Patprog pointers. Used mainly in executable code, but the
+ * pattern code needs to know about it, too. */
+
+#define dummy_patprog1 ((Patprog) 1)
+#define dummy_patprog2 ((Patprog) 2)
 
 /* node used in parameter hash table (paramtab) */
 
@@ -812,21 +1047,28 @@ struct param {
 	void *data;		/* used by special parameter functions    */
 	char **arr;		/* value if declared array   (PM_ARRAY)   */
 	char *str;		/* value if declared string  (PM_SCALAR)  */
-	long val;		/* value if declared integer (PM_INTEGER) */
+	zlong val;		/* value if declared integer (PM_INTEGER) */
+	double dval;		/* value if declared float
+				                    (PM_EFLOAT|PM_FFLOAT) */
+        HashTable hash;		/* value if declared assoc   (PM_HASHED)  */
     } u;
 
     /* pointer to function to set value of this parameter */
     union {
 	void (*cfn) _((Param, char *));
-	void (*ifn) _((Param, long));
+	void (*ifn) _((Param, zlong));
+	void (*ffn) _((Param, double));
 	void (*afn) _((Param, char **));
+        void (*hfn) _((Param, HashTable));
     } sets;
 
     /* pointer to function to get value of this parameter */
     union {
 	char *(*cfn) _((Param));
-	long (*ifn) _((Param));
+	zlong (*ifn) _((Param));
+	double (*ffn) _((Param));
 	char **(*afn) _((Param));
+        HashTable (*hfn) _((Param));
     } gets;
 
     /* pointer to function to unset this parameter */
@@ -842,30 +1084,108 @@ struct param {
 /* flags for parameters */
 
 /* parameter types */
-#define PM_SCALAR	0	/* scalar                                     */
-#define PM_ARRAY	(1<<0)	/* array                                      */
-#define PM_INTEGER	(1<<1)	/* integer                                    */
+#define PM_SCALAR	0	/* scalar                                   */
+#define PM_ARRAY	(1<<0)	/* array                                    */
+#define PM_INTEGER	(1<<1)	/* integer                                  */
+#define PM_EFLOAT	(1<<2)	/* double with %e output		    */
+#define PM_FFLOAT	(1<<3)	/* double with %f output		    */
+#define PM_HASHED	(1<<4)	/* association                              */
 
-#define PM_TYPE(X) (X & (PM_SCALAR|PM_INTEGER|PM_ARRAY))
+#define PM_TYPE(X) \
+  (X & (PM_SCALAR|PM_INTEGER|PM_EFLOAT|PM_FFLOAT|PM_ARRAY|PM_HASHED))
 
-#define PM_LEFT		(1<<2)	/* left justify and remove leading blanks     */
-#define PM_RIGHT_B	(1<<3)	/* right justify and fill with leading blanks */
-#define PM_RIGHT_Z	(1<<4)	/* right justify and fill with leading zeros  */
-#define PM_LOWER	(1<<5)	/* all lower case                             */
+#define PM_LEFT		(1<<5)	/* left justify, remove leading blanks      */
+#define PM_RIGHT_B	(1<<6)	/* right justify, fill with leading blanks  */
+#define PM_RIGHT_Z	(1<<7)	/* right justify, fill with leading zeros   */
+#define PM_LOWER	(1<<8)	/* all lower case                           */
 
 /* The following are the same since they *
  * both represent -u option to typeset   */
-#define PM_UPPER	(1<<6)	/* all upper case                             */
-#define PM_UNDEFINED	(1<<6)	/* undefined (autoloaded) shell function      */
-
-#define PM_READONLY	(1<<7)	/* readonly                                   */
-#define PM_TAGGED	(1<<8)	/* tagged                                     */
-#define PM_EXPORTED	(1<<9)	/* exported                                   */
-#define PM_UNIQUE	(1<<10)	/* remove duplicates                          */
-#define PM_SPECIAL	(1<<11) /* special builtin parameter                  */
-#define PM_DONTIMPORT	(1<<12)	/* do not import this variable                */
-#define PM_RESTRICTED	(1<<13) /* cannot be changed in restricted mode       */
-#define PM_UNSET	(1<<14)	/* has null value                             */
+#define PM_UPPER	(1<<9)	/* all upper case                           */
+#define PM_UNDEFINED	(1<<9)	/* undefined (autoloaded) shell function    */
+
+#define PM_READONLY	(1<<10)	/* readonly                                 */
+#define PM_TAGGED	(1<<11)	/* tagged                                   */
+#define PM_EXPORTED	(1<<12)	/* exported                                 */
+
+/* The following are the same since they *
+ * both represent -U option to typeset   */
+#define PM_UNIQUE	(1<<13)	/* remove duplicates                        */
+#define PM_UNALIASED	(1<<13)	/* do not expand aliases when autoloading   */
+
+#define PM_HIDE		(1<<14)	/* Special behaviour hidden by local        */
+#define PM_TIED 	(1<<15)	/* array tied to colon-path or v.v.         */
+
+/* Remaining flags do not correspond directly to command line arguments */
+#define PM_LOCAL	(1<<16) /* this parameter will be made local        */
+#define PM_SPECIAL	(1<<17) /* special builtin parameter                */
+#define PM_DONTIMPORT	(1<<18)	/* do not import this variable              */
+#define PM_RESTRICTED	(1<<19) /* cannot be changed in restricted mode     */
+#define PM_UNSET	(1<<20)	/* has null value                           */
+#define PM_REMOVABLE	(1<<21)	/* special can be removed from paramtab     */
+#define PM_AUTOLOAD	(1<<22) /* autoloaded from module                   */
+#define PM_NORESTORE	(1<<23)	/* do not restore value of local special    */
+
+/* The option string corresponds to the first of the variables above */
+#define TYPESET_OPTSTR "aiEFALRZlurtxUhT"
+
+/* These typeset options take an optional numeric argument */
+#define TYPESET_OPTNUM "LRZiEF"
+
+/* Flags for extracting elements of arrays and associative arrays */
+#define SCANPM_WANTVALS   (1<<0)
+#define SCANPM_WANTKEYS   (1<<1)
+#define SCANPM_WANTINDEX  (1<<2)
+#define SCANPM_MATCHKEY   (1<<3)
+#define SCANPM_MATCHVAL   (1<<4)
+#define SCANPM_MATCHMANY  (1<<5)
+#define SCANPM_ASSIGNING  (1<<6)
+#define SCANPM_KEYMATCH   (1<<7)
+#define SCANPM_ISVAR_AT   ((-1)<<15)	/* Only sign bit is significant */
+
+/*
+ * Flags for doing matches inside parameter substitutions, i.e.
+ * ${...#...} and friends.  This could be an enum, but so
+ * could a lot of other things.
+ */
+
+#define SUB_END		0x0001	/* match end instead of begining, % or %%  */
+#define SUB_LONG	0x0002	/* % or # doubled, get longest match */
+#define SUB_SUBSTR	0x0004	/* match a substring */
+#define SUB_MATCH	0x0008	/* include the matched portion */
+#define SUB_REST	0x0010	/* include the unmatched portion */
+#define SUB_BIND	0x0020	/* index of beginning of string */
+#define SUB_EIND	0x0040	/* index of end of string */
+#define SUB_LEN		0x0080	/* length of match */
+#define SUB_ALL		0x0100	/* match complete string */
+#define SUB_GLOBAL	0x0200	/* global substitution ${..//all/these} */
+#define SUB_DOSUBST	0x0400	/* replacement string needs substituting */
+
+/* Flags as the second argument to prefork */
+#define PF_TYPESET	0x01	/* argument handled like typeset foo=bar */
+#define PF_ASSIGN	0x02	/* argument handled like the RHS of foo=bar */
+#define PF_SINGLE	0x04	/* single word substitution */
+
+struct paramdef {
+    char *name;
+    int flags;
+    void *var;
+    void *set;
+    void *get;
+    void *unset;
+};
+
+#define PARAMDEF(name, flags, var, set, get, unset) \
+    { name, flags, (void *) var, (void *) set, (void *) get, (void *) unset }
+#define INTPARAMDEF(name, var) \
+    { name, PM_INTEGER, (void *) var, (void *) intvarsetfn, \
+      (void *) intvargetfn, (void *) stdunsetfn }
+#define STRPARAMDEF(name, var) \
+    { name, PM_SCALAR, (void *) var, (void *) strvarsetfn, \
+      (void *) strvargetfn, (void *) stdunsetfn }
+#define ARRPARAMDEF(name, var) \
+    { name, PM_ARRAY, (void *) var, (void *) arrvarsetfn, \
+      (void *) arrvargetfn, (void *) stdunsetfn }
 
 /* node for named directory hash table (nameddirtab) */
 
@@ -880,19 +1200,21 @@ struct nameddir {
 /* flags for named directories */
 /* DISABLED is defined (1<<0) */
 #define ND_USERNAME	(1<<1)	/* nam is actually a username       */
+#define ND_NOABBREV	(1<<2)	/* never print as abbrev (PWD or OLDPWD) */
 
 
 /* flags for controlling printing of hash table nodes */
 #define PRINT_NAMEONLY		(1<<0)
 #define PRINT_TYPE		(1<<1)
 #define PRINT_LIST		(1<<2)
+#define PRINT_KV_PAIR		(1<<3)
 
 /* flags for printing for the whence builtin */
-#define PRINT_WHENCE_CSH	(1<<3)
-#define PRINT_WHENCE_VERBOSE	(1<<4)
-#define PRINT_WHENCE_SIMPLE	(1<<5)
-#define PRINT_WHENCE_FUNCDEF	(1<<6)
-#define PRINT_WHENCE_WORD	(1<<7)
+#define PRINT_WHENCE_CSH	(1<<4)
+#define PRINT_WHENCE_VERBOSE	(1<<5)
+#define PRINT_WHENCE_SIMPLE	(1<<6)
+#define PRINT_WHENCE_FUNCDEF	(1<<7)
+#define PRINT_WHENCE_WORD	(1<<8)
 
 /***********************************/
 /* Definitions for history control */
@@ -901,18 +1223,30 @@ struct nameddir {
 /* history entry */
 
 struct histent {
+    HashNode hash_next;		/* next in hash chain               */
     char *text;			/* the history line itself          */
+    int flags;			/* Misc flags                       */
+
+    Histent up;			/* previous line (moving upward)    */
+    Histent down;		/* next line (moving downward)      */
     char *zle_text;		/* the edited history line          */
     time_t stim;		/* command started time (datestamp) */
     time_t ftim;		/* command finished time            */
     short *words;		/* Position of words in history     */
 				/*   line:  as pairs of start, end  */
     int nwords;			/* Number of words in history line  */
-    int flags;			/* Misc flags                       */
+    int histnum;		/* A sequential history number      */
 };
 
-#define HIST_OLD	0x00000001	/* Command is already written to disk*/
-#define HIST_READ	0x00000002	/* Command was read back from disk*/
+#define HIST_MAKEUNIQUE	0x00000001	/* Kill this new entry if not unique */
+#define HIST_OLD	0x00000002	/* Command is already written to disk*/
+#define HIST_READ	0x00000004	/* Command was read back from disk*/
+#define HIST_DUP	0x00000008	/* Command duplicates a later line */
+#define HIST_FOREIGN	0x00000010	/* Command came from another shell */
+
+#define GETHIST_UPWARD  (-1)
+#define GETHIST_DOWNWARD  1
+#define GETHIST_EXACT     0
 
 /* Parts of the code where history expansion is disabled *
  * should be within a pair of STOPHIST ... ALLOWHIST     */
@@ -923,7 +1257,14 @@ struct histent {
 #define HISTFLAG_DONE   1
 #define HISTFLAG_NOEXEC 2
 #define HISTFLAG_RECALL 4
+#define HISTFLAG_SETTY  8
 
+#define HFILE_APPEND		0x0001
+#define HFILE_SKIPOLD		0x0002
+#define HFILE_SKIPDUPS		0x0004
+#define HFILE_SKIPFOREIGN	0x0008
+#define HFILE_FAST		0x0010
+#define HFILE_USE_OPTIONS	0x8000
 
 /******************************************/
 /* Definitions for programable completion */
@@ -972,12 +1313,15 @@ enum {
     BADPATTERN,
     BANGHIST,
     BAREGLOBQUAL,
+    BASHAUTOLIST,
     BEEP,
     BGNICE,
     BRACECCL,
     BSDECHO,
     CDABLEVARS,
+    CHASEDOTS,
     CHASELINKS,
+    CHECKJOBS,
     CLOBBER,
     COMPLETEALIASES,
     COMPLETEINWORD,
@@ -986,6 +1330,7 @@ enum {
     CSHJUNKIEHISTORY,
     CSHJUNKIELOOPS,
     CSHJUNKIEQUOTES,
+    CSHNULLCMD,
     CSHNULLGLOB,
     EQUALS,
     ERREXIT,
@@ -994,6 +1339,7 @@ enum {
     EXTENDEDHISTORY,
     FLOWCONTROL,
     FUNCTIONARGZERO,
+    GLOBALRCS,
     GLOBOPT,
     GLOBASSIGN,
     GLOBCOMPLETE,
@@ -1004,15 +1350,20 @@ enum {
     HASHLISTALL,
     HISTALLOWCLOBBER,
     HISTBEEP,
+    HISTEXPIREDUPSFIRST,
+    HISTFINDNODUPS,
+    HISTIGNOREALLDUPS,
     HISTIGNOREDUPS,
     HISTIGNORESPACE,
     HISTNOFUNCTIONS,
     HISTNOSTORE,
     HISTREDUCEBLANKS,
+    HISTSAVENODUPS,
     HISTVERIFY,
     HUP,
     IGNOREBRACES,
     IGNOREEOF,
+    INCAPPENDHISTORY,
     INTERACTIVE,
     INTERACTIVECOMMENTS,
     KSHARRAYS,
@@ -1021,8 +1372,11 @@ enum {
     KSHOPTIONPRINT,
     LISTAMBIGUOUS,
     LISTBEEP,
+    LISTPACKED,
+    LISTROWSFIRST,
     LISTTYPES,
     LOCALOPTIONS,
+    LOCALTRAPS,
     LOGINSHELL,
     LONGLISTJOBS,
     MAGICEQUALSUBST,
@@ -1056,9 +1410,11 @@ enum {
     RESTRICTED,
     RMSTARSILENT,
     RMSTARWAIT,
+    SHAREHISTORY,
     SHFILEEXPANSION,
     SHGLOB,
     SHINSTDIN,
+    SHNULLCMD,
     SHOPTIONLETTERS,
     SHORTLOOPS,
     SHWORDSPLIT,
@@ -1154,7 +1510,8 @@ struct ttyinfo {
 #define TCALLATTRSOFF  21
 #define TCSTANDOUTEND  22
 #define TCUNDERLINEEND 23
-#define TC_COUNT       24
+#define TCHORIZPOS     24
+#define TC_COUNT       25
 
 #define tccan(X) (tclen[X])
 
@@ -1178,14 +1535,20 @@ struct ttyinfo {
 /* Definitions for the %_ prompt escape */
 /****************************************/
 
-#define cmdpush(X) if (!(cmdsp >= 0 && cmdsp < 256)) {;} else cmdstack[cmdsp++]=(X)
+#define CMDSTACKSZ 256
+#define cmdpush(X) do { \
+                       if (cmdsp >= 0 && cmdsp < CMDSTACKSZ) \
+                           cmdstack[cmdsp++]=(X); \
+                   } while (0)
 #ifdef DEBUG
-# define cmdpop()  if (cmdsp <= 0) { \
-			fputs("BUG: cmdstack empty\n", stderr); \
-			fflush(stderr); \
-		   } else cmdsp--
+# define cmdpop()  do { \
+                       if (cmdsp <= 0) { \
+			   fputs("BUG: cmdstack empty\n", stderr); \
+			   fflush(stderr); \
+		       } else cmdsp--; \
+                   } while (0)
 #else
-# define cmdpop()   if (cmdsp <= 0) {;} else cmdsp--
+# define cmdpop()   do { if (cmdsp > 0) cmdsp--; } while (0)
 #endif
 
 #define CS_FOR          0
@@ -1224,35 +1587,41 @@ struct ttyinfo {
  * Memory management *
  *********************/
 
-#ifndef DEBUG
-# define HEAPALLOC	do { int nonlocal_useheap = global_heapalloc(); do
+/* heappush saves the current heap state using this structure */
 
-# define PERMALLOC	do { int nonlocal_useheap = global_permalloc(); do
+struct heapstack {
+    struct heapstack *next;	/* next one in list for this heap */
+    size_t used;
+};
 
-# define LASTALLOC	while (0); \
-			if (nonlocal_useheap) global_heapalloc(); \
-			else global_permalloc(); \
-		} while(0)
+/* A zsh heap. */
 
-# define LASTALLOC_RETURN \
-			if ((nonlocal_useheap ? global_heapalloc() : \
-			     global_permalloc()), 0) {;} else return
-#else
-# define HEAPALLOC	do { int nonlocal_useheap = global_heapalloc(); \
-			alloc_stackp++; do
+struct heap {
+    struct heap *next;		/* next one                                  */
+    size_t size;		/* size of heap                              */
+    size_t used;		/* bytes used from the heap                  */
+    struct heapstack *sp;	/* used by pushheap() to save the value used */
 
-# define PERMALLOC	do { int nonlocal_useheap = global_permalloc(); \
-			alloc_stackp++; do
+/* Uncomment the following if the struct needs padding to 64-bit size. */
+/* Make sure sizeof(heap) is a multiple of 8 
+#if defined(PAD_64_BIT) && !defined(__GNUC__)
+    size_t dummy;		
+#endif
+*/
+#define arena(X)	((char *) (X) + sizeof(struct heap))
+}
+#if defined(PAD_64_BIT) && defined(__GNUC__)
+  __attribute__ ((aligned (8)))
+#endif
+;
 
-# define LASTALLOC	while (0); alloc_stackp--; \
-			if (nonlocal_useheap) global_heapalloc(); \
-			else global_permalloc(); \
-		} while(0)
+# define LASTALLOC_RETURN return
 
-# define LASTALLOC_RETURN \
-			if ((nonlocal_useheap ? global_heapalloc() : \
-			    global_permalloc()),alloc_stackp--,0){;}else return
-#endif
+# define NEWHEAPS(h)    do { Heap _switch_oldheaps = h = new_heaps(); do
+# define OLDHEAPS       while (0); old_heaps(_switch_oldheaps); } while (0);
+
+# define SWITCHHEAPS(h)  do { Heap _switch_oldheaps = switch_heaps(h); do
+# define SWITCHBACKHEAPS while (0); switch_heaps(_switch_oldheaps); } while (0);
 
 /****************/
 /* Debug macros */
@@ -1260,12 +1629,8 @@ struct ttyinfo {
 
 #ifdef DEBUG
 # define DPUTS(X,Y) if (!(X)) {;} else dputs(Y)
-# define MUSTUSEHEAP(X) if (useheap) {;} else \
-		fprintf(stderr, "BUG: permanent allocation in %s\n", X), \
-		fflush(stderr)
 #else
 # define DPUTS(X,Y)
-# define MUSTUSEHEAP(X)
 #endif
 
 /**************************/
@@ -1274,9 +1639,20 @@ struct ttyinfo {
 
 /* These used in the sigtrapped[] array */
 
-#define ZSIG_TRAPPED	(1<<0)
-#define ZSIG_IGNORED	(1<<1)
-#define ZSIG_FUNC	(1<<2)
+#define ZSIG_TRAPPED	(1<<0)	/* Signal is trapped */
+#define ZSIG_IGNORED	(1<<1)	/* Signal is ignored */
+#define ZSIG_FUNC	(1<<2)	/* Trap is a function, not an eval list */
+/* Mask to get the above flags */
+#define ZSIG_MASK	(ZSIG_TRAPPED|ZSIG_IGNORED|ZSIG_FUNC)
+/* No. of bits to shift local level when storing in sigtrapped */
+#define ZSIG_SHIFT	3
+
+/**********************************/
+/* Flags to third argument of zle */
+/**********************************/
+
+#define ZLRF_HISTORY	0x01	/* OK to access the history list */
+#define ZLRF_NOSETTY	0x02	/* Don't set tty before return */
 
 /****************/
 /* Entry points */
@@ -1291,3 +1667,17 @@ typedef int (*CompctlReadFn) _((char *, char **, char *, char *));
 typedef void (*ZleVoidFn) _((void));
 typedef void (*ZleVoidIntFn) _((int));
 typedef unsigned char * (*ZleReadFn) _((char *, char *, int));
+
+/***************************************/
+/* Pseudo-keyword to mark exportedness */
+/***************************************/
+
+#define mod_export
+
+/***************************************/
+/* Hooks in core.                      */
+/***************************************/
+
+#define EXITHOOK       (zshhooks + 0)
+#define BEFORETRAPHOOK (zshhooks + 1)
+#define AFTERTRAPHOOK  (zshhooks + 2)