#pragma prototyped
#include <ast.h>
#include <ls.h>
#include <ctype.h>
#include <dirent.h>
#include <fs3d.h>
#include <glob.h>
#include <hash.h>
#include <swap.h>
#include <namval.h>
#include <error.h>
#include <coshell.h>
#include <times.h>
#include <tok.h>
#include <setjmp.h>
#include <sfdisc.h>
#include <tmx.h>
#if DEBUG
#define debug(x) do if (error_info.trace < 0) { error x; } while (0)
#define PANIC (ERROR_PANIC|ERROR_SOURCE|ERROR_SYSTEM),__FILE__,__LINE__
#else
#define debug(x)
#define PANIC ERROR_PANIC
#endif
#define COMMENT '#'
#define MARK_CONTEXT '\002'
#define MARK_QUOTE '\003'
#define SALT '#'
#define VIEWOFFSET '0'
#if _WINIX
#define FILE_SPACE '\001'
#else
#define FILE_SPACE '?'
#endif
#define ATTRNAME '.'
#define ATTRSET '+'
#define ATTRCLEAR '-'
#define CMDTRACE (-6)
#define EXPTRACE (-5)
#define EXPLAIN (state.user&&(state.explain||error_info.trace<=EXPTRACE))
#undef atoi
#undef atol
#undef bind
#undef clrbit
#undef optinit
#undef setbit
#define bind bindrule
#define canon(x) ((state.context&&iscontextp(x,&state.tmppchar))?state.tmppchar:(state.mam.statix?mamcanon(x):pathcanon(x,0,0)))
#define clrbit(v,b) ((v)&=~(1L<<(b)))
#define getar(name) ((Dir_t*)hashget(table.ar,(name)))
#define getbound(name) ((char*)hashget(table.bound,(name)))
#define getdir(id) ((Dir_t*)hashget(table.dir,(char*)(id)))
#define getfile(name) ((File_t*)hashget(table.file,(name)))
#define getold(name) ((char*)hashget(table.oldvalue,(name)))
#define getreg(name) ((int*)hashget(table.regress,(name)))
#define getrule(name) ((Rule_t*)hashget(table.rule,(name)))
#define getvar(name) ((Var_t*)hashget(table.var,(name)))
#define message(x) do if (error_info.trace < 0) { error x; } while (0)
#define notfile(r) (((r)->property&(P_attribute|P_functional|P_make|P_operator|P_state|P_use|P_virtual))||((r)->dynamic&D_scope)||(r)->semaphore||((r)->property&P_dontcare)&&((r)->dynamic&D_bound)&&!(r)->time)
#define oldname(r) do{if(getbound(r->uname))putbound(0,0);if(r->dynamic&D_alias)r->dynamic&=~D_alias;else putrule(r->name,0);r->name=r->uname;r->uname=0;}while(0)
#define putbound(n,d) hashput(table.bound,(char*)(n),(char*)(d))
#define putar(name,d) hashput(table.ar,(name),(char*)(d))
#define putdir(id,d) hashput(table.dir,(char*)(id),(char*)(d))
#define putfile(name,f) hashput(table.file,(char*)(name),(char*)(f))
#define putold(name,v) hashput(table.oldvalue,(char*)(name),(char*)(v))
#define putptr(f,p) (internal.ptr=(char*)(p),sfwrite(f,&internal.ptr,sizeof(internal.ptr)))
#define putreg(name,r) hashput(table.regress,(char*)(name),(char*)(r))
#define putrule(name,r) hashput(table.rule,(char*)(name),(char*)(r))
#define putvar(name,v) hashput(table.var,(char*)(name),(char*)(v))
#define reason(x) do if(EXPLAIN)explain x;while(0)
#define ropen(f,m) ((f)==internal.openfile?(internal.openfile=0,internal.openfd):open(f,m))
#define rsfopen(f) ((f)==internal.openfile?(internal.openfile=0,sfnew(NiL,NiL,SF_UNBOUND,internal.openfd,SF_READ)):sfopen(NiL,f,"re"))
#define setbit(v,b) ((v)|=(1L<<(b)))
#define shquote shellquote
#define statetimeq timestateq
#define timefix(t) t-=(t<state.tolerance)?t:state.tolerance
#define trap() (state.caught?handle():0)
#define tstbit(v,b) ((v)&(1L<<(b)))
#define unviewname(s) (*(s)='(')
#define viewable(r) ((r->property&P_state)&&*r->name=='(')
#define viewname(s,v) (*(s)=VIEWOFFSET+(v))
#define zero(x) memzero(&(x),sizeof(x))
#define isaltstate(s) (nametype(s,NiL)&(NAME_altstate))
#define iscontext(s) (nametype(s,NiL)&(NAME_context))
#define iscontextp(s,p) (nametype(s,p)&(NAME_context))
#define isdynamic(s) (nametype(s,NiL)&(NAME_dynamic|NAME_glob))
#define isglob(s) (nametype(s,NiL)&(NAME_glob))
#define isintvar(s) (nametype(s,NiL)&(NAME_intvar))
#define isstate(s) (nametype(s,NiL)&(NAME_staterule|NAME_altstate|NAME_statevar))
#define isstatevar(s) (nametype(s,NiL)&(NAME_statevar))
#define freelist(x) do{if(x){(x)->rule=(Rule_t*)internal.freelists;internal.freelists=(char*)(x);}}while(0)
#define freerule(r) do{zero(*r);*((char**)r)=internal.freerules;internal.freerules=(char*)(r);}while(0)
#define freevar(v) do{(v)->property&=(V_free|V_import);*((char**)v)=internal.freevars;internal.freevars=(char*)(v);}while(0)
#define newlist(x) do{if(x=(List_t*)internal.freelists){if(x->next){x=x->next;*((char**)internal.freelists)=(char*)x->next;}else internal.freelists=(char*)x->rule;}else x=(List_t*)newchunk(&internal.freelists,sizeof(List_t));}while(0)
#define newrule(r) do{if(r=(Rule_t*)internal.freerules){internal.freerules=(*((char**)r));zero(*r);}else r=(Rule_t*)newchunk(&internal.freerules,sizeof(Rule_t));}while(0)
#define newvar(v) do{if(v=(Var_t*)internal.freevars){internal.freevars=(*((char**)v));}else v=(Var_t*)newchunk(&internal.freevars,sizeof(Var_t));}while(0)
#if CHAR_MIN < 0
#define ctable (ctypes-(CHAR_MIN)+1)
#else
#define ctable (ctypes)
#endif
#define istype(c,t) (ctable[c]&(t))
#define settype(c,t) (ctable[c]|=(t))
#define unsettype(c,t) (ctable[c]&=~(t))
#define NOTYET 0
#define UPDATE 1
#define MAKING 2
#define TOUCH 3
#define EXISTS 4
#define IGNORE 5
#define FAILED 6
#define OLDRULE 7
#define RECOMPILE 1
#define COMPILED 2
#define SAVED 3
#define DELETE NiL
#define KEEP ((char*)1)
#define NOTIME TMX_NOTIME
#define OLDTIME ((Time_t)(1))
#define CURTIME tmxgettime()
#define CURSECS ((Seconds_t)time(NiL))
#define VAR 0
#define CONSISTENT VAR
#define RULE 1
#define PREREQS 2
#define STATERULES 2
#define MINVALUE 32
#define MAXJOBS 128
#define MAXNAME 1024
#define PCTGARBAGE 10
#define MAXVIEW (sizeof(Flags_t)*CHAR_BIT)
#if BINDINDEX
#define MAXBIND UCHAR_MAX
#endif
#define A_clear (1<<0)
#define A_copy (1<<1)
#define A_delete (1<<2)
#define A_group (1<<3)
#define A_insert (1<<4)
#define A_metarule (1<<5)
#define A_negate (1<<6)
#define A_nooptions (1<<7)
#define A_norhs (1<<8)
#define A_null (1<<9)
#define A_scan (1<<10)
#define A_scope (1<<11)
#define A_special (1<<12)
#define A_target (1<<13)
#define C_ID1 (1<<0)
#define C_ID2 (1<<1)
#define C_MATCH (1<<2)
#define C_OPTVAL (1<<3)
#define C_SEP (1<<4)
#define C_TERMINAL (1<<5)
#define C_VARIABLE1 (1<<6)
#define C_VARIABLE2 (1<<7)
#define C_VARPOS1 (1<<8)
#define C_VARPOS2 (1<<9)
#define C_VARPOS3 (1<<10)
#define C_VARPOS4 (1<<11)
#define C_VARPOS5 (1<<12)
#define C_VARPOS6 (1<<13)
#define C_VARPOS7 (1<<14)
#define C_VARPOS8 (1L<<15)
#define NAME_altstate 0x001
#define NAME_assignment 0x002
#define NAME_context 0x004
#define NAME_dynamic 0x008
#define NAME_glob 0x010
#define NAME_identifier 0x020
#define NAME_intvar 0x040
#define NAME_option 0x080
#define NAME_path 0x100
#define NAME_staterule 0x200
#define NAME_statevar 0x400
#define NAME_variable 0x800
#define ARG_ASSIGN (1<<0)
#define ARG_SCRIPT (1<<1)
#define ARG_TARGET (1<<2)
#define BIND_DOT (1<<0)
#define BIND_FORCE (1<<1)
#define BIND_MAKEFILE (1<<2)
#define BIND_RULE (1<<3)
#define MERGE_ALL (1<<0)
#define MERGE_ASSOC (1<<1)
#define MERGE_ATTR (1<<2)
#define MERGE_BOUND (1<<3)
#define MERGE_FORCE (1<<4)
#define MERGE_SCANNED (1<<5)
#define COMP_BASE (1<<0)
#define COMP_DONTCARE (1<<1)
#define COMP_FILE (1<<2)
#define COMP_GLOBAL (1<<3)
#define COMP_INCLUDE (1<<4)
#define COMP_OPTIONS (1<<5)
#define COMP_RULES (1<<6)
#define COMP_NSEC (1<<7)
#define PREREQ_APPEND 1
#define PREREQ_DELETE 2
#define PREREQ_INSERT 3
#define PREREQ_LENGTH 4
#define SCAN_IGNORE 1
#define SCAN_NULL 2
#define SCAN_STATE 3
#define SCAN_USER 8
#define SCAN_MAX UCHAR_MAX
#define CO_ALWAYS (CO_USER<<0)
#define CO_DATAFILE (CO_USER<<1)
#define CO_ERRORS (CO_USER<<2)
#define CO_FOREGROUND (CO_USER<<3)
#define CO_KEEPGOING (CO_USER<<4)
#define CO_LOCALSTACK (CO_USER<<5)
#define CO_PRIMARY (CO_USER<<6)
#define CO_SEMAPHORES (CO_USER<<7)
#define CO_URGENT (CO_USER<<8)
#define P_accept (1<<0)
#define P_after (1<<1)
#define P_always (1<<2)
#define P_archive (1<<3)
#define P_attribute (1<<4)
#define P_before (1<<5)
#define P_command (1<<6)
#define P_dontcare (1<<7)
#define P_force (1<<8)
#define P_foreground (1<<9)
#define P_functional (1<<10)
#define P_ignore (1<<11)
#define P_immediate (1<<12)
#define P_implicit (1<<13)
#define P_internal (1<<14)
#define P_joint (1L<<15)
#define P_make (1L<<16)
#define P_metarule (1L<<17)
#define P_multiple (1L<<18)
#define P_local (1L<<19)
#define P_operator (1L<<20)
#define P_parameter (1L<<21)
#define P_readonly (1L<<22)
#define P_repeat (1L<<23)
#define P_state (1L<<24)
#define P_staterule (1L<<25)
#define P_statevar (1L<<26)
#define P_target (1L<<27)
#define P_terminal (1L<<28)
#define P_use (1L<<29)
#define P_virtual (1L<<30)
#define P_read (1L<<31)
#define P_failure (P_after|P_before)
#define D_alias (1<<0)
#define D_aliaschanged (1<<1)
#define D_bound (1<<2)
#define D_built (1<<3)
#define D_cached (1<<4)
#define D_compiled (1<<5)
#define D_dynamic (1<<6)
#define D_entries (1<<7)
#define D_garbage (1<<8)
#define D_hasafter (1<<9)
#define D_hasbefore (1<<10)
#define D_membertoo (1<<11)
#define D_hassemaphore (1<<12)
#define D_same (1<<13)
#define D_lower (1<<14)
#define D_source (1L<<15)
#define D_member (1L<<16)
#define D_global (1L<<17)
#define D_regular (1L<<18)
#define D_scanned (1L<<19)
#define D_select0 (1L<<20)
#define D_select1 (1L<<21)
#define D_triggered (1L<<22)
#define D_index (1L<<23)
#define D_bindindex (1L<<24)
#define D_intermediate (1L<<25)
#define D_hasscope (1L<<26)
#define D_scope (1L<<27)
#define D_hasmake (1L<<28)
#define D_context (1L<<29)
#define D_lowres (1L<<30)
#define D_CLEAROBJECT (~(D_bindindex|D_built|D_compiled|D_context|D_dynamic|D_index|D_lower|D_lowres|D_scope))
#define M_bind (1<<0)
#define M_compile (1<<1)
#define M_directory (1<<2)
#define M_generate (1<<3)
#define M_mark (1<<4)
#define M_metarule (1<<5)
#define M_scan (1<<6)
#define M_waiting (1<<7)
#define V_compiled (1<<0)
#define V_frozen (1<<1)
#define V_functional (1<<2)
#define V_import (1<<3)
#define V_local_D (1<<4)
#define V_oldvalue (1<<5)
#define V_readonly (1<<6)
#define V_retain (1<<7)
#define V_scan (1<<8)
#define V_local_E (1<<9)
#define V_auxiliary (1<<10)
#define V_append (1<<11)
#define V_free (1<<12)
#define V_builtin (1<<13)
#define V_scope (1<<14)
#define V_restored (1L<<15)
#define V_CLEARSTATE (V_free|V_restored)
#define V_CLEAROBJECT (~(V_auxiliary|V_builtin|V_functional|V_import|V_retain|V_scan|V_scope))
#define VAL_AUXILIARY (1<<0)
#define VAL_BRACE (1<<1)
#define VAL_FILE (1<<2)
#define VAL_PRIMARY (1<<3)
#define VAL_UNBOUND (1<<4)
#define JOB_blocked 1
#define JOB_status 2
typedef struct dirent Dirent_t;
typedef struct stat Stat_t;
struct File_s; typedef struct File_s File_t;
struct Frame_s; typedef struct Frame_s Frame_t;
struct List_s; typedef struct List_s List_t;
struct Rule_s; typedef struct Rule_s Rule_t;
typedef uint32_t Flags_t;
typedef uint32_t Seconds_t;
typedef struct Fileid_s
{
long dev;
long ino;
} Fileid_t;
typedef struct Dir_s
{
char* name;
Time_t time;
unsigned char archive;
unsigned char directory;
unsigned char ignorecase;
unsigned char truncate;
} Dir_t;
struct File_s
{
File_t* next;
Dir_t* dir;
Time_t time;
};
struct Frame_s
{
Frame_t* parent;
Frame_t* previous;
Rule_t* target;
List_t* prereqs;
char* action;
char* original;
char* primary;
char* stem;
Flags_t flags;
struct
{
char* name;
Frame_t* frame;
Time_t time;
} context;
};
#define event u1.u_event
#define statedata u1.u_data
#define uname u1.u_uname
#define unbound(r) ((r)->uname?(r)->uname:(r)->name)
struct Rule_s
{
char* name;
Frame_t* active;
union
{
char* u_uname;
char* u_data;
Time_t u_event;
} u1;
List_t* prereqs;
char* action;
Time_t time;
Flags_t attribute;
Flags_t dynamic;
Flags_t property;
unsigned char scan;
unsigned char semaphore;
unsigned char status;
unsigned char view;
unsigned char mark;
unsigned char preview;
unsigned short must;
unsigned long complink;
Flags_t checked[STATERULES+1];
#if BINDINDEX
unsigned char source;
#endif
};
typedef struct Internal_s
{
Rule_t* accept;
Rule_t* after;
Rule_t* alarm;
Rule_t* always;
Rule_t* archive;
Rule_t* attribute;
Rule_t* before;
Rule_t* command;
Rule_t* dontcare;
Rule_t* force;
Rule_t* foreground;
Rule_t* functional;
Rule_t* freeze;
Rule_t* ignore;
Rule_t* immediate;
Rule_t* implicit;
Rule_t* insert;
Rule_t* joint;
Rule_t* local;
Rule_t* make;
Rule_t* making;
Rule_t* multiple;
Rule_t* op;
Rule_t* parameter;
Rule_t* read;
Rule_t* readonly;
Rule_t* regular;
Rule_t* repeat;
Rule_t* run;
Rule_t* semaphore;
Rule_t* source;
Rule_t* state;
Rule_t* sync;
Rule_t* terminal;
Rule_t* use;
Rule_t* virt;
Rule_t* wait;
Rule_t* active;
Rule_t* bound;
Rule_t* built;
Rule_t* entries;
Rule_t* exists;
Rule_t* failed;
Rule_t* file;
Rule_t* global;
Rule_t* member;
Rule_t* notyet;
Rule_t* scanned;
Rule_t* staterule;
Rule_t* statevar;
Rule_t* target;
Rule_t* triggered;
Rule_t* args;
Rule_t* bind;
Rule_t* clear;
Rule_t* copy;
Rule_t* delete;
Rule_t* dot;
Rule_t* empty;
Rule_t* error;
Rule_t* exports;
Rule_t* globalfiles;
Rule_t* include;
Rule_t* internal;
Rule_t* main;
Rule_t* makefiles;
Rule_t* metarule;
Rule_t* null;
Rule_t* preprocess;
Rule_t* query;
Rule_t* rebind;
Rule_t* reset;
Rule_t* retain;
Rule_t* scan;
Rule_t* script;
Rule_t* special;
Rule_t* tmplist;
Rule_t* unbind;
Rule_t* view;
Rule_t* append_p;
Rule_t* assert_p;
Rule_t* assign_p;
Rule_t* attribute_p;
Rule_t* bind_p;
Rule_t* dontcare_p;
Rule_t* insert_p;
Rule_t* require_p;
Rule_t* source_p;
Sfio_t* met;
Sfio_t* nam;
Sfio_t* tmp;
Sfio_t* val;
Sfio_t* wrk;
char* freelists;
char* freerules;
char* freevars;
char* issource;
char* openfile;
char* pwd;
char* ptr;
int openfd;
int pwdlen;
} Internal_t;
typedef struct External_s
{
char* args;
char* convert;
char* file;
char* files;
char* import;
char* lib;
char* make;
char* nproc;
char* old;
char* pwd;
char* rules;
char* skip;
char* version;
char* viewdot;
char* viewnode;
char* compdone;
char* compinit;
char* done;
char* init;
char* interrupt;
char* jobdone;
char* makedone;
char* makeinit;
char* makeprompt;
char* makerun;
char* mamname;
char* mamaction;
char* order;
char* lock;
char* object;
char* source;
char* state;
char* tmp;
} External_t;
typedef struct Tables_s
{
Hash_table_t* ar;
Hash_table_t* bound;
Hash_table_t* dir;
Hash_table_t* file;
Hash_table_t* oldvalue;
Hash_table_t* regress;
Hash_table_t* rule;
Hash_table_t* var;
} Tables_t;
#define BIND_EXISTS (1<<0)
#define BIND_LOADED (1<<1)
typedef struct Binding_s
{
#if BINDINDEX
Rule_t* path;
#else
char* path;
#endif
char* root;
short pathlen;
short rootlen;
unsigned char flags;
unsigned char map;
} Binding_t;
typedef struct Label_s
{
jmp_buf label;
} Label_t;
typedef struct Mam_s
{
Sfdisc_t disc;
int hold;
int level;
int parent;
int rootlen;
char* label;
char* options;
char* root;
char* type;
Sfio_t* out;
unsigned char dynamic;
unsigned char regress;
unsigned char statix;
unsigned char dontcare;
unsigned char port;
} Mam_t;
typedef struct State_s
{
unsigned char accept;
unsigned char alias;
unsigned char base;
unsigned char caught;
unsigned char compile;
unsigned char compileonly;
unsigned char compatibility;
unsigned char cross;
unsigned char exec;
unsigned char expandall;
unsigned char expandview;
unsigned char explain;
unsigned char explicitrules;
unsigned char finish;
unsigned char force;
unsigned char forceread;
unsigned char forcescan;
unsigned char fsview;
unsigned char fullscan;
unsigned char global;
unsigned char ignore;
unsigned char ignorelock;
unsigned char import;
unsigned char init;
unsigned char intermediate;
unsigned char interpreter;
unsigned char keepgoing;
unsigned char list;
unsigned char localview;
#if BINDINDEX
unsigned char logical;
#endif
unsigned char never;
unsigned char op;
unsigned char override;
unsigned char pushed;
unsigned char push_global;
unsigned char push_user;
unsigned char preprocess;
unsigned char reading;
unsigned char readonly;
unsigned char ruledump;
unsigned char savestate;
unsigned char scan;
unsigned char serialize;
unsigned char silent;
unsigned char strictview;
unsigned char targetcontext;
unsigned char touch;
unsigned char user;
unsigned char val;
unsigned char vardump;
unsigned char virtualdot;
unsigned char waiting;
unsigned char warn;
int argc;
int believe;
int errors;
int interrupt;
int jobs;
int pid;
int readstate;
int reread;
int stateview;
int tabstops;
int targetview;
int tolerance;
int unwind;
Flags_t questionable;
Flags_t test;
Time_t start;
char* corrupt;
char* errorid;
char* hold;
char* loading;
char* makefile;
char* objectfile;
char* regress;
char* rules;
char* statefile;
char* targetprefix;
char* tmppchar;
char* tmpfile;
char* writeobject;
char* writestate;
int* argf;
char** argv;
Dir_t* archive;
Sfio_t* context;
Frame_t* frame;
#if BINDINDEX
Binding_t source[MAXBIND+1];
int maxsource;
#endif
Binding_t view[MAXVIEW+1];
unsigned int maxview;
int (*compnew)(const char*, char*, void*);
void* comparg;
Label_t resume;
Mam_t mam;
Coshell_t* coshell;
Sfio_t* io[11];
} State_t;
typedef struct Var_s
{
char* name;
char* value;
Flags_t property;
size_t length;
char* (*builtin)(char**);
} Var_t;
struct List_s
{
List_t* next;
Rule_t* rule;
};
extern External_t external;
extern Internal_t internal;
extern State_t state;
extern Tables_t table;
extern char null[];
extern char tmpname[];
extern short ctypes[];
extern char* idname;
extern char* initdynamic;
extern char* initstatic;
extern char* version;
extern File_t* addfile(Dir_t*, char*, Time_t);
extern void addprereq(Rule_t*, Rule_t*, int);
extern List_t* append(List_t*, List_t*);
extern int apply(Rule_t*, char*, char*, char*, Flags_t);
extern void argcount(void);
extern void arscan(Rule_t*);
extern void artouch(char*, char*);
extern char* arupdate(char*);
extern Rule_t* associate(Rule_t*, Rule_t*, char*, List_t**);
extern Var_t* auxiliary(char*, int);
extern Rule_t* bind(Rule_t*);
extern void bindattribute(Rule_t*);
extern Rule_t* bindfile(Rule_t*, char*, int);
extern Rule_t* bindstate(Rule_t*, char*);
extern int block(int);
extern void candidates(void);
extern char* call(Rule_t*, char*);
extern Rule_t* catrule(char*, char*, char*, int);
extern char* colonlist(Sfio_t*, char*, int, int);
extern void compile(char*, char*);
extern int complete(Rule_t*, List_t*, Time_t*, Flags_t);
extern void compref(Rule_t*, int);
extern List_t* cons(Rule_t*, List_t*);
extern void dirscan(Rule_t*);
extern void drop(void);
extern void dump(Sfio_t*, int);
extern void dumpaction(Sfio_t*, const char*, char*, const char*);
extern void dumpjobs(int, int);
extern void dumpregress(Sfio_t*, const char*, const char*, char*);
extern void dumprule(Sfio_t*, Rule_t*);
extern void dumpvar(Sfio_t*, Var_t*);
extern void dynamic(Rule_t*);
extern void edit(Sfio_t*, char*, char*, char*, char*);
extern void expand(Sfio_t*, char*);
extern void explain(int, ...);
extern long expr(Sfio_t*, char*);
extern Sfio_t* fapply(Rule_t*, char*, char*, char*, Flags_t);
extern void finish(int);
extern int forcescan(const char*, char* v, void*);
extern char* getarg(char**, int*);
extern void getop(Sfio_t*, char*, int);
extern char* getval(char*, int);
extern char** globv(glob_t*, char*);
extern int handle(void);
extern int hasattribute(Rule_t*, Rule_t*, Rule_t*);
extern int hasafter(Rule_t*, Flags_t);
extern void immediate(Rule_t*);
extern void initcode(void);
extern void inithash(void);
extern void initrule(void);
extern void initscan(int);
extern void inittrap(void);
extern void initview(void);
extern void initwakeup(int);
extern void interpreter(char*);
extern int isoption(const char*);
extern int nametype(const char*, char**);
extern List_t* joint(Rule_t*);
extern List_t* listcopy(List_t*);
extern void listops(Sfio_t*, int);
extern int load(Sfio_t*, const char*, int, int);
extern int loadable(Sfio_t*, Rule_t*, int);
extern void localvar(Sfio_t*, Var_t*, char*, int);
extern char* localview(Rule_t*);
extern void lockstate(int);
extern int make(Rule_t*, Time_t*, char*, Flags_t);
extern int makeafter(Rule_t*, Flags_t);
extern int makebefore(Rule_t*);
extern Rule_t* makerule(char*);
extern void maketop(Rule_t*, int, char*);
extern char* mamcanon(char*);
extern ssize_t mamerror(int, const void*, size_t);
extern char* mamname(Rule_t*);
extern void mampop(Sfio_t*, Rule_t*, Flags_t);
extern int mampush(Sfio_t*, Rule_t*, Flags_t);
extern Sfio_t* mamout(Rule_t*);
extern char* maprule(char*, Rule_t*);
extern void merge(Rule_t*, Rule_t*, int);
extern void mergestate(Rule_t*, Rule_t*);
extern void metaclose(Rule_t*, Rule_t*, int);
extern void metaexpand(Sfio_t*, char*, char*);
extern Rule_t* metaget(Rule_t*, Frame_t*, char*, Rule_t**);
extern Rule_t* metainfo(int, char*, char*, int);
extern int metamatch(char*, char*, char*);
extern Rule_t* metarule(char*, char*, int);
extern void negate(Rule_t*, Rule_t*);
extern void* newchunk(char**, size_t);
extern void newfile(Rule_t*, char*, Time_t);
extern char* objectfile(void);
extern void parentage(Sfio_t*, Rule_t*, char*);
extern int parse(Sfio_t*, char*, char*, Sfio_t*);
extern char* parsefile(void);
extern char* pathname(char*, Rule_t*);
extern void poplocal(void*);
extern int prereqchange(Rule_t*, List_t*, Rule_t*, List_t*);
extern void punt(int);
extern void* pushlocal(void);
extern void readcheck(void);
extern void readclear(void);
extern void readenv(void);
extern int readfile(char*, int, char*);
extern void readstate(void);
extern void rebind(Rule_t*, int);
extern void remdup(List_t*);
extern void remtmp(int);
extern int resolve(char*, int, int);
extern int rstat(char*, Stat_t*, int);
extern void rules(char*);
extern Rule_t* rulestate(Rule_t*, int);
extern void savestate(void);
extern List_t* scan(Rule_t*, Time_t*);
extern int scanargs(int, char**, int*);
extern int set(char*, int, Sfio_t*);
extern Var_t* setvar(char*, char*, int);
extern void shquote(Sfio_t*, char*);
extern Rule_t* source(Rule_t*);
extern int special(Rule_t*);
extern char* statefile(void);
extern Rule_t* staterule(int, Rule_t*, char*, int);
extern Time_t statetime(Rule_t*, int);
extern int statetimeq(Rule_t*, Rule_t*);
extern int strprintf(Sfio_t*, const char*, char*, int, int);
extern void terminate(void);
extern char* timefmt(const char*, Time_t);
extern Time_t timenum(const char*, char**);
extern char* timestr(Time_t);
extern void trigger(Rule_t*, Rule_t*, char*, Flags_t);
extern int unbind(const char*, char*, void*);
extern Dir_t* unique(Rule_t*);
extern void unparse(int);
extern Var_t* varstate(Rule_t*, int);
extern void wakeup(Seconds_t, List_t*);