summaryrefslogtreecommitdiff
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)