diff -r 000000000000 -r 2e3d3ce01487 openenvutils/commandshell/shell/inc/zsh.h --- /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)