--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/openenvutils/commandshell/shell/inc/zsh.h Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,1863 @@
+/*
+ * zsh.h - standard header file
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 1992-1997 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 to distribute modified versions of this software 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.
+ *
+ */
+
+#define trashzle() trashzleptr()
+#define zle_resetprompt() zle_resetpromptptr()
+#define zleread(X,Y,H,C) zlereadptr(X,Y,H,C)
+#define spaceinline(X) spaceinlineptr(X)
+#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 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 */
+#define MN_UNSET 4 /* mnumber not yet retrieved */
+
+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 *
+ * 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
+
+/* Meta together with the character following Meta denotes the character *
+ * which is the exclusive or of 32 and the character following Meta. *
+ * This is used to represent characters which otherwise has special *
+ * meaning for zsh. These are the characters for which the imeta() test *
+ * is true: the null character, and the characters from Meta to Marker. */
+
+#define Meta ((char) 0x83)
+
+/* Note that the fourth character in DEFAULT_IFS is Meta *
+ * followed by a space which denotes the null character. */
+
+#define DEFAULT_IFS " \t\n\203 "
+
+/* Character tokens */
+#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) & 0xfc) == 0x98)
+
+/* Marker used in paramsubst for rc_expand_param */
+#define Marker ((char) 0x9c)
+
+/* chars that need to be quoted if meant literally */
+
+#define SPECCHARS "#$^*()=|{}[]`<>?~;&\n\t \\\'\""
+
+enum {
+ NULLTOK, /* 0 */
+ SEPER,
+ NEWLIN,
+ SEMI,
+ DSEMI,
+ AMPER, /* 5 */
+ INPAR,
+ OUTPAR,
+ DBAR,
+ DAMPER,
+ OUTANG, /* 10 */
+ OUTANGBANG,
+ DOUTANG,
+ DOUTANGBANG,
+ INANG,
+ INOUTANG, /* 15 */
+ DINANG,
+ DINANGDASH,
+ INANGAMP,
+ OUTANGAMP,
+ AMPOUTANG, /* 20 */
+ OUTANGAMPBANG,
+ DOUTANGAMP,
+ DOUTANGAMPBANG,
+ TRINANG,
+ BAR, /* 25 */
+ BARAMP,
+ INOUTPAR,
+ DINPAR,
+ DOUTPAR,
+ AMPERBANG, /* 30 */
+ SEMIAMP,
+ DOUTBRACK,
+ STRING,
+ ENVSTRING,
+ ENVARRAY, /* 35 */
+ ENDINPUT,
+ LEXERR,
+
+ /* Tokens for reserved words */
+ BANG, /* ! */
+ DINBRACK, /* [[ */
+ INBRACE, /* { */ /* 40 */
+ OUTBRACE, /* } */
+ CASE, /* case */
+ COPROC, /* coproc */
+ DOLOOP, /* do */
+ DONE, /* done */ /* 45 */
+ ELIF, /* elif */
+ ELSE, /* else */
+ ZEND, /* end */
+ ESAC, /* esac */
+ FI, /* fi */ /* 50 */
+ FOR, /* for */
+ FOREACH, /* foreach */
+ FUNC, /* function */
+ IF, /* if */
+ NOCORRECT, /* nocorrect */ /* 55 */
+ REPEAT, /* repeat */
+ SELECT, /* select */
+ THEN, /* then */
+ TIME, /* time */
+ UNTIL, /* until */ /* 60 */
+ WHILE /* while */
+};
+
+/* Redirection types. If you modify this, you may also have to modify *
+ * redirtab in parse.c and getredirs() in text.c and the IS_* macros *
+ * below. */
+
+enum {
+ REDIR_WRITE, /* > */
+ REDIR_WRITENOW, /* >| */
+ REDIR_APP, /* >> */
+ REDIR_APPNOW, /* >>| */
+ REDIR_ERRWRITE, /* &>, >& */
+ REDIR_ERRWRITENOW, /* >&| */
+ REDIR_ERRAPP, /* >>& */
+ REDIR_ERRAPPNOW, /* >>&| */
+ REDIR_READWRITE, /* <> */
+ REDIR_READ, /* < */
+ REDIR_HEREDOC, /* << */
+ REDIR_HEREDOCDASH, /* <<- */
+ REDIR_HERESTR, /* <<< */
+ REDIR_MERGEIN, /* <&n */
+ REDIR_MERGEOUT, /* >&n */
+ REDIR_CLOSE, /* >&-, <&- */
+ REDIR_INPIPE, /* < <(...) */
+ REDIR_OUTPIPE /* > >(...) */
+};
+
+#define IS_WRITE_FILE(X) ((X)>=REDIR_WRITE && (X)<=REDIR_READWRITE)
+#define IS_APPEND_REDIR(X) (IS_WRITE_FILE(X) && ((X) & 2))
+#define IS_CLOBBER_REDIR(X) (IS_WRITE_FILE(X) && ((X) & 1))
+#define IS_ERROR_REDIR(X) ((X)>=REDIR_ERRWRITE && (X)<=REDIR_ERRAPPNOW)
+#define IS_READFD(X) (((X)>=REDIR_READWRITE && (X)<=REDIR_MERGEIN) || (X)==REDIR_INPIPE)
+#define IS_REDIROP(X) ((X)>=OUTANG && (X)<=TRINANG)
+
+/* Flags for input stack */
+#define INP_FREE (1<<0) /* current buffer can be free'd */
+#define INP_ALIAS (1<<1) /* expanding alias or history */
+#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
+#define META_USEHEAP 1
+#define META_STATIC 2
+#define META_DUP 3
+#define META_ALLOC 4
+#define META_NOALLOC 5
+#define META_HEAPDUP 6
+#define META_HREALLOC 7
+
+
+/**************************/
+/* Abstract types for zsh */
+/**************************/
+
+typedef struct linknode *LinkNode;
+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 options *Options;
+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 conddef *Conddef;
+typedef struct redir *Redir;
+typedef struct complist *Complist;
+typedef struct heap *Heap;
+typedef struct heapstack *Heapstack;
+typedef struct histent *Histent;
+typedef struct hookdef *Hookdef;
+
+typedef struct asgment *Asgment;
+
+
+/********************************/
+/* Definitions for linked lists */
+/********************************/
+
+/* linked list abstract data type */
+
+struct linknode {
+ LinkNode next;
+ LinkNode last;
+ void *dat;
+};
+
+struct linklist {
+ LinkNode first;
+ LinkNode last;
+};
+
+/* Macros for manipulating link lists */
+
+#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 */
+/********************************/
+
+/* 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_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 */
+
+/* Condition types. */
+
+#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
+#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
+
+#define CONDDEF(name, flags, handler, min, max, condid) \
+ { NULL, name, flags, handler, min, max, condid, NULL }
+
+/* tree element for redirection lists */
+
+struct redir {
+ int type;
+ int fd1, fd2;
+ char *name;
+};
+
+/* The number of fds space is allocated for *
+ * each time a multio must increase in size. */
+#define MULTIOUNIT 8
+
+/* 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[MULTIOUNIT]; /* list of src/dests redirected to/from this fd */
+};
+
+/* structure for foo=bar assignments */
+
+struct asgment {
+ struct asgment *next;
+ char *name;
+ char *value;
+};
+
+/* lvalue for variable assignment/expansion */
+
+struct value {
+ int isarr;
+ Param pm; /* parameter node */
+ int inv; /* should we return the index ? */
+ int start; /* first element of array slice, or -1 */
+ int end; /* 1-rel last element of array slice, or -1 */
+ char **arr; /* cache for hash turned into array */
+};
+
+#define MAX_ARRLEN 262144
+
+/********************************************/
+/* Definitions 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 */
+ dev_t dev; /* device */
+ ino_t ino; /* indoe number */
+ int fd; /* file descriptor */
+ Wordcode map; /* pointer to header */
+ Wordcode addr; /* mapped region */
+ int len; /* length */
+ int count; /* reference count */
+ char *filename;
+};
+
+/*
+ * A note on the use of reference counts in Eprogs.
+ *
+ * When an Eprog is created, nref is set to -1 if the Eprog is on the
+ * heap; then no attempt is ever made to free it. (This information is
+ * already present in EF_HEAP; we use the redundancy for debugging
+ * checks.)
+ *
+ * Otherwise, nref is initialised to 1. Calling freeprog() decrements
+ * nref and frees the Eprog if the count is now zero. When the Eprog
+ * is in use, we call useeprog() at the start and freeprog() at the
+ * end to increment and decrement the reference counts. If an attempt
+ * is made to free the Eprog from within, this will then take place
+ * when execution is finished, typically in the call to freeeprog()
+ * in execode(). If the Eprog was on the heap, neither useeprog()
+ * nor freeeprog() has any effect.
+ */
+struct eprog {
+ int flags; /* EF_* below */
+ int len; /* total block length */
+ int npats; /* Patprog cache size */
+ int nref; /* number of references: delete when zero */
+ 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 left, right;
+ char *str;
+ wordcode offs, aoffs;
+ 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 WC_TRY 20
+
+/* increment as necessary */
+#define WC_COUNT 21
+
+#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_TYPE2(C) ((wc_data(C) & ((wordcode) 2)) >> 1)
+#define WC_ASSIGN_SCALAR 0
+#define WC_ASSIGN_ARRAY 1
+#define WC_ASSIGN_NEW 0
+#define WC_ASSIGN_INC 1
+#define WC_ASSIGN_NUM(C) (wc_data(C) >> 2)
+#define WCB_ASSIGN(T,A,N) wc_bld(WC_ASSIGN, ((T) | ((A) << 1) | ((N) << 2)))
+
+#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_TRY_SKIP(C) wc_data(C)
+#define WCB_TRY(O) wc_bld(WC_TRY, (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)
+
+/********************************************/
+/* Definitions for job table and job control */
+/********************************************/
+
+/* entry in the 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 */
+ struct process *auxprocs; /* auxiliary processes e.g multios */
+ LinkList 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<<0) /* status changed and not reported */
+#define STAT_STOPPED (1<<1) /* all procs stopped or exited */
+#define STAT_TIMED (1<<2) /* job is being timed */
+#define STAT_DONE (1<<3) /* job is done */
+#define STAT_LOCKED (1<<4) /* shell is finished creating this job, */
+ /* may be deleted from job table */
+#define STAT_NOPRINT (1<<5) /* job was killed internally, */
+ /* we don't want to show that */
+#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_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 */
+
+struct timeinfo {
+ long ut; /* user space time */
+ long st; /* system space time */
+};
+
+#define JOBTEXTSIZE 80
+
+/* Size to initialise the job table to, and to increment it by when needed. */
+#define MAXJOBS_ALLOC (50)
+
+/* node in job process lists */
+
+#ifdef HAVE_GETRUSAGE
+typedef struct rusage child_times_t;
+#else
+typedef struct timeinfo child_times_t;
+#endif
+
+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() */
+ child_times_t ti;
+ struct timeval bgtime; /* time job was spawned */
+ struct timeval endtime; /* time job exited */
+};
+
+struct execstack {
+ struct execstack *next;
+
+ LinkList args;
+ pid_t list_pipe_pid;
+ int nowait;
+ int pline_level;
+ int list_pipe_child;
+ int list_pipe_job;
+ char list_pipe_text[JOBTEXTSIZE];
+ int lastval;
+ int noeval;
+ int badcshglob;
+ pid_t cmdoutpid;
+ int cmdoutval;
+ int trapreturn;
+ int noerrs;
+ int subsh_close;
+ char *underscore;
+};
+
+struct heredocs {
+ struct heredocs *next;
+ int type;
+ int pc;
+ char *str;
+};
+
+struct dirsav {
+ int dirfd, level;
+ char *dirname;
+ dev_t dev;
+ ino_t ino;
+};
+
+#define MAX_PIPESTATS 256
+
+/*******************************/
+/* Definitions for Hash Tables */
+/*******************************/
+
+typedef void *(*VFunc) _((void *));
+typedef void (*FreeFunc) _((void *));
+
+typedef unsigned (*HashFunc) _((char *));
+typedef void (*TableFunc) _((HashTable));
+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));
+
+/* hash table for standard open hashing */
+
+struct hashtable {
+ /* HASHTABLE DATA */
+ int hsize; /* size of nodes[] (number of hash values) */
+ int ct; /* number of elements */
+ HashNode *nodes; /* array of size hsize */
+
+ /* HASHTABLE METHODS */
+ 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 */
+ /* (getnode2 will ignore DISABLED flag) */
+ RemoveNodeFunc removenode; /* pointer to function to delete a node */
+ ScanFunc disablenode; /* pointer to function to disable a node */
+ 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 */
+#endif
+};
+
+/* generic hash table node */
+
+struct hashnode {
+ HashNode next; /* next in hash chain */
+ char *nam; /* hash key */
+ int flags; /* various flags */
+};
+
+/* The flag to disable nodes in a hash table. Currently *
+ * you can disable builtins, shell functions, aliases and *
+ * 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 {
+ HashNode next; /* next in hash chain */
+ char *nam; /* name of reserved word */
+ int flags; /* flags */
+ int token; /* corresponding lexer token */
+};
+
+/* node in alias hash table (aliastab) */
+
+struct alias {
+ HashNode next; /* next in hash chain */
+ char *nam; /* hash data */
+ int flags; /* flags for alias types */
+ char *text; /* expansion of alias */
+ int inuse; /* alias is being expanded */
+};
+
+/* bit 0 of flags is the DISABLED flag */
+/* is this alias global? */
+#define ALIAS_GLOBAL (1<<1)
+/* is this an alias for suffix handling? */
+#define ALIAS_SUFFIX (1<<2)
+
+/* node in command path hash table (cmdnamtab) */
+
+struct cmdnam {
+ HashNode next; /* next in hash chain */
+ char *nam; /* hash data */
+ int flags;
+ union {
+ char **name; /* full pathname for external commands */
+ char *cmd; /* file name for hashed commands */
+ }
+ u;
+};
+
+/* flag for nodes explicitly added to *
+ * cmdnamtab with hash builtin */
+#define HASHED (1<<1)
+
+/* node in shell function hash table (shfunctab) */
+
+struct shfunc {
+ HashNode next; /* next in hash chain */
+ char *nam; /* name of shell function */
+ int flags; /* various flags */
+ 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) */
+
+/*
+ * Handling of options.
+ *
+ * Option strings are standard in that a trailing `:' indicates
+ * a mandatory argument. In addition, `::' indicates an optional
+ * argument which must immediately follow the option letter if it is present.
+ * `:%' indicates an optional numeric argument which may follow
+ * the option letter or be in the next word; the only test is
+ * that the next character is a digit, and no actual conversion is done.
+ */
+
+#define MAX_OPS 128
+
+/* Macros taking struct option * and char argument */
+/* Option was set as -X */
+#define OPT_MINUS(ops,c) ((ops)->ind[c] & 1)
+/* Option was set as +X */
+#define OPT_PLUS(ops,c) ((ops)->ind[c] & 2)
+/*
+ * Option was set any old how, maybe including an argument
+ * (cheap test when we don't care). Some bits of code
+ * expect this to be 1 or 0.
+ */
+#define OPT_ISSET(ops,c) ((ops)->ind[c] != 0)
+/* Option has an argument */
+#define OPT_HASARG(ops,c) ((ops)->ind[c] > 3)
+/* The argument for the option; not safe if it doesn't have one */
+#define OPT_ARG(ops,c) ((ops)->args[((ops)->ind[c] >> 2) - 1])
+/* Ditto, but safely returns NULL if there is no argument. */
+#define OPT_ARG_SAFE(ops,c) (OPT_HASARG(ops,c) ? OPT_ARG(ops,c) : NULL)
+
+struct options {
+ unsigned char ind[MAX_OPS];
+ char **args;
+ int argscount, argsalloc;
+};
+
+/*
+ * Handler arguments are: builtin name, null-terminated argument
+ * list excluding command name, option structure, the funcid element from the
+ * builtin structure.
+ */
+
+typedef int (*HandlerFunc) _((char *, char **, Options, int));
+#define NULLBINCMD ((HandlerFunc) 0)
+
+struct builtin {
+ HashNode next; /* next in hash chain */
+ char *nam; /* name of builtin */
+ int flags; /* various flags */
+ HandlerFunc handlerfunc; /* pointer to function that executes this builtin */
+ int minargs; /* minimum number of arguments */
+ int maxargs; /* maximum number of arguments, or -1 for no limit */
+ int funcid; /* xbins (see above) for overloaded handlerfuncs */
+ char *optstr; /* string of legal options */
+ char *defopts; /* options set by default for overloaded handlerfuncs */
+};
+
+#define BUILTIN(name, flags, handler, min, max, funcid, optstr, defopts) \
+ { NULL, name, flags, handler, min, max, funcid, optstr, defopts }
+#define BIN_PREFIX(name, flags) \
+ BUILTIN(name, flags | BINF_PREFIX, NULLBINCMD, 0, 0, 0, NULL, NULL)
+
+/* builtin flags */
+/* DISABLE IS DEFINED AS (1<<0) */
+#define BINF_PLUSOPTS (1<<1) /* +xyz legal */
+#define BINF_PRINTOPTS (1<<2)
+#define BINF_ADDED (1<<3) /* is in the builtins hash table */
+#define BINF_MAGICEQUALS (1<<4) /* needs automatic MAGIC_EQUAL_SUBST substitution */
+#define BINF_PREFIX (1<<5)
+#define BINF_DASH (1<<6)
+#define BINF_BUILTIN (1<<7)
+#define BINF_COMMAND (1<<8)
+#define BINF_EXEC (1<<9)
+#define BINF_NOGLOB (1<<10)
+#define BINF_PSPECIAL (1<<11)
+/* Builtin option handling */
+#define BINF_SKIPINVALID (1<<12) /* Treat invalid option as argument */
+#define BINF_KEEPNUM (1<<13) /* `[-+]NUM' can be an option */
+#define BINF_SKIPDASH (1<<14) /* Treat `-' as argument (maybe `+') */
+#define BINF_DASHDASHVALID (1<<15) /* Handle `--' even if SKIPINVALD */
+
+enum { BIN_CHOWN, BIN_CHGRP };
+
+struct module {
+ char *nam;
+ int flags;
+ union {
+ void *handle;
+ Linkedmod linked;
+ char *alias;
+ } 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)
+#define MOD_ALIAS (1<<6)
+
+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 */
+ long patmlen; /* length of pure string or longest match */
+ int globflags; /* globbing flags to set at start */
+ int globend; /* globbing flags set after finish */
+ int flags; /* PAT_* flags */
+ 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 */
+#define PAT_NOTSTART 0x0200 /* Start of string is not real start */
+#define PAT_NOTEND 0x0400 /* End of string is not real end */
+#define PAT_HAS_EXCLUDP 0x0800 /* (internal): top-level path1~path2. */
+
+/* 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)
+
+/* standard node types for get/set/unset union in parameter */
+
+/*
+ * note non-standard const in pointer declaration: structures are
+ * assumed to be read-only.
+ */
+typedef const struct gsu_scalar *GsuScalar;
+typedef const struct gsu_integer *GsuInteger;
+typedef const struct gsu_float *GsuFloat;
+typedef const struct gsu_array *GsuArray;
+typedef const struct gsu_hash *GsuHash;
+
+struct gsu_scalar {
+ char *(*getfn) _((Param));
+ void (*setfn) _((Param, char *));
+ void (*unsetfn) _((Param, int));
+};
+
+struct gsu_integer {
+ zlong (*getfn) _((Param));
+ void (*setfn) _((Param, zlong));
+ void (*unsetfn) _((Param, int));
+};
+
+struct gsu_float {
+ double (*getfn) _((Param));
+ void (*setfn) _((Param, double));
+ void (*unsetfn) _((Param, int));
+};
+
+struct gsu_array {
+ char **(*getfn) _((Param));
+ void (*setfn) _((Param, char **));
+ void (*unsetfn) _((Param, int));
+};
+
+struct gsu_hash {
+ HashTable (*getfn) _((Param));
+ void (*setfn) _((Param, HashTable));
+ void (*unsetfn) _((Param, int));
+};
+
+
+/* node used in parameter hash table (paramtab) */
+
+struct param {
+ HashNode next; /* next in hash chain */
+ char *nam; /* hash data */
+ int flags; /* PM_* flags */
+
+ /* the value of this parameter */
+ union {
+ void *data; /* used by special parameter functions */
+ char **arr; /* value if declared array (PM_ARRAY) */
+ char *str; /* value if declared string (PM_SCALAR) */
+ zlong val; /* value if declared integer (PM_INTEGER) */
+ zlong *valptr; /* value if special pointer to integer */
+ double dval; /* value if declared float
+ (PM_EFLOAT|PM_FFLOAT) */
+ HashTable hash; /* value if declared assoc (PM_HASHED) */
+ } u;
+
+ /*
+ * get/set/unset methods.
+ *
+ * Unlike the data union, this points to a single instance
+ * for every type (although there are special types, e.g.
+ * tied arrays have a different gsu_scalar struct from the
+ * normal one). It's really a poor man's vtable.
+ */
+ union {
+ GsuScalar s;
+ GsuInteger i;
+ GsuFloat f;
+ GsuArray a;
+ GsuHash h;
+ } gsu;
+
+ int base; /* output base or floating point prec */
+ int width; /* field width */
+ 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 */
+};
+
+/* structure stored in struct param's u.data by tied arrays */
+struct tieddata {
+ char ***arrptr; /* pointer to corresponding array */
+ int joinchar; /* character used to join arrays */
+};
+
+/* flags for parameters */
+
+/* parameter types */
+#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_EFLOAT|PM_FFLOAT|PM_ARRAY|PM_HASHED))
+
+#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<<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_HIDEVAL (1<<15) /* Value not shown in `typeset' commands */
+#define PM_TIED (1<<16) /* array tied to colon-path or v.v. */
+
+#define PM_KSHSTORED (1<<17) /* function stored in ksh form */
+#define PM_ZSHSTORED (1<<18) /* function stored in zsh form */
+
+/* Remaining flags do not correspond directly to command line arguments */
+#define PM_LOCAL (1<<21) /* this parameter will be made local */
+#define PM_SPECIAL (1<<22) /* special builtin parameter */
+#define PM_DONTIMPORT (1<<23) /* do not import this variable */
+#define PM_RESTRICTED (1<<24) /* cannot be changed in restricted mode */
+#define PM_UNSET (1<<25) /* has null value */
+#define PM_REMOVABLE (1<<26) /* special can be removed from paramtab */
+#define PM_AUTOLOAD (1<<27) /* autoloaded from module */
+#define PM_NORESTORE (1<<28) /* do not restore value of local special */
+#define PM_HASHELEM (1<<29) /* is a hash-element */
+#define PM_NAMEDDIR (1<<30) /* has a corresponding nameddirtab entry */
+
+/* The option string corresponds to the first of the variables above */
+#define TYPESET_OPTSTR "aiEFALRZlurtxUhHTkz"
+
+/* 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_DQUOTED (1<<8)
+#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 beginning, % 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 *gsu; /* get/set/unset structure */
+};
+
+#define PARAMDEF(name, flags, var, gsu) \
+ { name, flags, (void *) var, (void *) gsu, }
+/*
+ * Note that the following definitions are appropriate for defining
+ * parameters that reference a variable (var). Hence the get/set/unset
+ * methods used will assume var needs dereferencing to get the value.
+ */
+#define INTPARAMDEF(name, var) \
+ { name, PM_INTEGER, (void *) var, NULL }
+#define STRPARAMDEF(name, var) \
+ { name, PM_SCALAR, (void *) var, NULL }
+#define ARRPARAMDEF(name, var) \
+ { name, PM_ARRAY, (void *) var, NULL }
+
+#define setsparam(S,V) assignsparam(S,V,0)
+#define setaparam(S,V) assignaparam(S,V,0)
+
+/* node for named directory hash table (nameddirtab) */
+
+struct nameddir {
+ HashNode next; /* next in hash chain */
+ char *nam; /* directory name */
+ int flags; /* see below */
+ char *dir; /* the directory in full */
+ int diff; /* strlen(.dir) - strlen(.nam) */
+};
+
+/* 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)
+#define PRINT_INCLUDEVALUE (1<<4)
+#define PRINT_TYPESET (1<<5)
+
+/* flags for printing for the whence builtin */
+#define PRINT_WHENCE_CSH (1<<5)
+#define PRINT_WHENCE_VERBOSE (1<<6)
+#define PRINT_WHENCE_SIMPLE (1<<7)
+#define PRINT_WHENCE_FUNCDEF (1<<9)
+#define PRINT_WHENCE_WORD (1<<10)
+
+/***********************************/
+/* Definitions for history control */
+/***********************************/
+
+/* 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 */
+ zlong histnum; /* A sequential history number */
+};
+
+#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 HIST_TMPSTORE 0x00000020 /* Kill when user enters another cmd */
+
+#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 */
+
+#define STOPHIST (stophist += 4);
+#define ALLOWHIST (stophist -= 4);
+
+#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_NO_REWRITE 0x0020
+#define HFILE_USE_OPTIONS 0x8000
+
+/******************************************/
+/* Definitions for programable completion */
+/******************************************/
+
+/* Nothing special. */
+#define IN_NOTHING 0
+/* In command position. */
+#define IN_CMD 1
+/* In a mathematical environment. */
+#define IN_MATH 2
+/* In a condition. */
+#define IN_COND 3
+/* In a parameter assignment (e.g. `foo=bar'). */
+#define IN_ENV 4
+/* In a parameter name in an assignment. */
+#define IN_PAR 5
+
+
+/******************************/
+/* Definition for zsh options */
+/******************************/
+
+/* Possible values of emulation */
+
+#define EMULATE_CSH (1<<1) /* C shell */
+#define EMULATE_KSH (1<<2) /* Korn shell */
+#define EMULATE_SH (1<<3) /* Bourne shell */
+#define EMULATE_ZSH (1<<4) /* `native' mode */
+
+/* option indices */
+
+enum {
+ OPT_INVALID,
+ ALIASESOPT,
+ ALLEXPORT,
+ ALWAYSLASTPROMPT,
+ ALWAYSTOEND,
+ APPENDHISTORY,
+ AUTOCD,
+ AUTOCONTINUE,
+ AUTOLIST,
+ AUTOMENU,
+ AUTONAMEDIRS,
+ AUTOPARAMKEYS,
+ AUTOPARAMSLASH,
+ AUTOPUSHD,
+ AUTOREMOVESLASH,
+ AUTORESUME,
+ BADPATTERN,
+ BANGHIST,
+ BAREGLOBQUAL,
+ BASHAUTOLIST,
+ BEEP,
+ BGNICE,
+ BRACECCL,
+ BSDECHO,
+ CASEGLOB,
+ CBASES,
+ CDABLEVARS,
+ CHASEDOTS,
+ CHASELINKS,
+ CHECKJOBS,
+ CLOBBER,
+ COMPLETEALIASES,
+ COMPLETEINWORD,
+ CORRECT,
+ CORRECTALL,
+ CSHJUNKIEHISTORY,
+ CSHJUNKIELOOPS,
+ CSHJUNKIEQUOTES,
+ CSHNULLCMD,
+ CSHNULLGLOB,
+ EMACSMODE,
+ EQUALS,
+ ERREXIT,
+ ERRRETURN,
+ EXECOPT,
+ EXTENDEDGLOB,
+ EXTENDEDHISTORY,
+ EVALLINENO,
+ FLOWCONTROL,
+ FUNCTIONARGZERO,
+ GLOBOPT,
+ GLOBALEXPORT,
+ GLOBALRCS,
+ GLOBASSIGN,
+ GLOBCOMPLETE,
+ GLOBDOTS,
+ GLOBSUBST,
+ HASHCMDS,
+ HASHDIRS,
+ HASHLISTALL,
+ HISTALLOWCLOBBER,
+ HISTBEEP,
+ HISTEXPIREDUPSFIRST,
+ HISTFINDNODUPS,
+ HISTIGNOREALLDUPS,
+ HISTIGNOREDUPS,
+ HISTIGNORESPACE,
+ HISTNOFUNCTIONS,
+ HISTNOSTORE,
+ HISTREDUCEBLANKS,
+ HISTSAVENODUPS,
+ HISTVERIFY,
+ HUP,
+ IGNOREBRACES,
+ IGNOREEOF,
+ INCAPPENDHISTORY,
+ INTERACTIVE,
+ INTERACTIVECOMMENTS,
+ KSHARRAYS,
+ KSHAUTOLOAD,
+ KSHGLOB,
+ KSHOPTIONPRINT,
+ KSHTYPESET,
+ LISTAMBIGUOUS,
+ LISTBEEP,
+ LISTPACKED,
+ LISTROWSFIRST,
+ LISTTYPES,
+ LOCALOPTIONS,
+ LOCALTRAPS,
+ LOGINSHELL,
+ LONGLISTJOBS,
+ MAGICEQUALSUBST,
+ MAILWARNING,
+ MARKDIRS,
+ MENUCOMPLETE,
+ MONITOR,
+ MULTIOS,
+ NOMATCH,
+ NOTIFY,
+ NULLGLOB,
+ NUMERICGLOBSORT,
+ OCTALZEROES,
+ OVERSTRIKE,
+ PATHDIRS,
+ POSIXBUILTINS,
+ PRINTEIGHTBIT,
+ PRINTEXITVALUE,
+ PRIVILEGED,
+ PROMPTBANG,
+ PROMPTCR,
+ PROMPTPERCENT,
+ PROMPTSUBST,
+ PUSHDIGNOREDUPS,
+ PUSHDMINUS,
+ PUSHDSILENT,
+ PUSHDTOHOME,
+ RCEXPANDPARAM,
+ RCQUOTES,
+ RCS,
+ RECEXACT,
+ RESTRICTED,
+ RMSTARSILENT,
+ RMSTARWAIT,
+ SHAREHISTORY,
+ SHFILEEXPANSION,
+ SHGLOB,
+ SHINSTDIN,
+ SHNULLCMD,
+ SHOPTIONLETTERS,
+ SHORTLOOPS,
+ SHWORDSPLIT,
+ SINGLECOMMAND,
+ SINGLELINEZLE,
+ SUNKEYBOARDHACK,
+ TRANSIENTRPROMPT,
+ TRAPSASYNC,
+ TYPESETSILENT,
+ UNSET,
+ VERBOSE,
+ VIMODE,
+ XTRACE,
+ USEZLE,
+ DVORAK,
+ OPT_SIZE
+};
+
+#undef isset
+#define isset(X) (opts[X])
+#define unset(X) (!opts[X])
+
+#define interact (isset(INTERACTIVE))
+#define jobbing (isset(MONITOR))
+#define islogin (isset(LOGINSHELL))
+
+/***********************************************/
+/* Definitions for terminal and display control */
+/***********************************************/
+
+/* 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
+};
+
+/* defines for whether tabs expand to spaces */
+#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
+#define SGTTYFLAG shttyinfo.tio.c_oflag
+#else /* we're using sgtty */
+#define SGTTYFLAG shttyinfo.sgttyb.sg_flags
+#endif
+# ifdef TAB3
+#define SGTABTYPE TAB3
+# else
+# ifdef OXTABS
+#define SGTABTYPE OXTABS
+# else
+#define SGTABTYPE XTABS
+# endif
+# endif
+
+/* flags for termflags */
+
+#define TERM_BAD 0x01 /* terminal has extremely basic capabilities */
+#define TERM_UNKNOWN 0x02 /* unknown terminal type */
+#define TERM_NOUP 0x04 /* terminal has no up capability */
+#define TERM_SHORT 0x08 /* terminal is < 3 lines high */
+#define TERM_NARROW 0x10 /* terminal is < 3 columns wide */
+
+/* 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 TCHORIZPOS 24
+#define TCUPCURSOR 25
+#define TCDOWNCURSOR 26
+#define TCLEFTCURSOR 27
+#define TCRIGHTCURSOR 28
+#define TC_COUNT 29
+
+#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))
+
+/****************************************/
+/* Definitions for the %_ prompt escape */
+/****************************************/
+
+#define CMDSTACKSZ 256
+#define cmdpush(X) do { \
+ if (cmdsp >= 0 && cmdsp < CMDSTACKSZ) \
+ cmdstack[cmdsp++]=(X); \
+ } while (0)
+#ifdef DEBUG
+# define cmdpop() do { \
+ if (cmdsp <= 0) { \
+ fputs("BUG: cmdstack empty\n", stderr); \
+ fflush(stderr); \
+ } else cmdsp--; \
+ } while (0)
+#else
+# define cmdpop() do { if (cmdsp > 0) cmdsp--; } while (0)
+#endif
+
+#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
+#define CS_BRACE 29
+#define CS_BRACEPAR 30
+#define CS_ALWAYS 31
+
+/* Increment as necessary */
+#define CS_COUNT 32
+
+/*********************
+ * Memory management *
+ *********************/
+
+/* heappush saves the current heap state using this structure */
+
+struct heapstack {
+ struct heapstack *next; /* next one in list for this heap */
+ size_t used;
+};
+
+/* A zsh heap. */
+
+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 */
+
+/* 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 NEWHEAPS(h) do { Heap _switch_oldheaps = h = new_heaps(); do
+# define OLDHEAPS while (0); old_heaps(_switch_oldheaps); } while (0);
+
+# define SWITCHHEAPS(o, h) do { o = switch_heaps(h); do
+# define SWITCHBACKHEAPS(o) while (0); switch_heaps(o); } while (0);
+
+/****************/
+/* Debug macros */
+/****************/
+
+#ifdef DEBUG
+# define DPUTS(X,Y) if (!(X)) {;} else dputs(Y)
+#else
+# define DPUTS(X,Y)
+#endif
+
+/**************************/
+/* Signal handling macros */
+/**************************/
+
+/* These used in the sigtrapped[] array */
+
+#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 */
+#define ZLRF_IGNOREEOF 0x04 /* Ignore an EOF from the keyboard */
+
+/***************************/
+/* Context of zleread call */
+/***************************/
+
+enum {
+ ZLCON_LINE_START, /* Command line at PS1 */
+ ZLCON_LINE_CONT, /* Command line at PS2 */
+ ZLCON_SELECT, /* Select loop */
+ ZLCON_VARED /* Vared command */
+};
+
+/****************/
+/* Entry points */
+/****************/
+
+/* compctl entry point pointers */
+
+typedef int (*CompctlReadFn) _((char *, char **, Options, char *));
+
+/* ZLE entry point pointers */
+
+typedef void (*ZleVoidFn) _((void));
+typedef void (*ZleVoidIntFn) _((int));
+typedef unsigned char * (*ZleReadFn) _((char **, char **, int, int));
+
+/***************************************/
+/* Hooks in core. */
+/***************************************/
+
+#define EXITHOOK (zshhooks + 0)
+#define BEFORETRAPHOOK (zshhooks + 1)
+#define AFTERTRAPHOOK (zshhooks + 2)