/***************************************************************************** * * m4.h * *****************************************************************************/ #ifdef POSIX #include #include #include #include #include #include typedef char TCHAR, *PTCH; typedef const char *PCSTR; typedef unsigned char TBYTE, BYTE, *PBYTE; typedef unsigned int UINT; typedef unsigned long DWORD; typedef int BOOL, HFILE; typedef void *PVOID; #define VOID void #define CONST const #define TEXT(lit) lit #define MAX_PATH PATH_MAX #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #define EOL TEXT("\n") #define cbEol 1 #else #include #define EOL TEXT("\r\n") #define cbEol 2 #endif #include /* offsetof */ /***************************************************************************** * * Dialectical variation * *****************************************************************************/ #ifdef DBG #define DEBUG #endif /***************************************************************************** * * Baggage - Stuff I carry everywhere. * * Stuff that begin with underscores are bottom-level gizmos which tend * to get wrapped by functions with the same name. * *****************************************************************************/ #if defined(_MSC_VER) #define STDCALL __stdcall #undef CDECL /* defines it wrong */ #define CDECL __cdecl #define INLINE static __inline /* Inlines are always static */ #define NORETURN #define PURE #define _pvAllocCb(cb) LocalAlloc(LMEM_FIXED, cb) #define _pvZAllocCb(cb) LocalAlloc(LMEM_FIXED + LMEM_ZEROINIT, cb) #define _pvReallocPvCb(pv, cb) LocalReAlloc(pv, cb, LMEM_MOVEABLE) #define _FreePv(pv) LocalFree(pv) #define PrintPtchPtchVa wvsprintf #define PrintPtchPtchV wsprintf #define exit ExitProcess #define strlen lstrlen #define strcmp lstrcmp #define bzero ZeroMemory #elif defined(__GNUC__) #define STDCALL #define CDECL #define INLINE static __inline__ /* Inlines are always static */ #define NORETURN __NORETURN #define PURE __CONSTVALUE #define _pvAllocCb(cb) malloc(cb) #define _pvZAllocCb(cb) calloc(cb, 1) #define _pvReallocPvCb(pv, cb) realloc(pv, cb) #define _FreePv(pv) free(pv) #define PrintPtchPtchVa vsprintf #define PrintPtchPtchV sprintf #endif typedef TCHAR TCH, *PTSTR; /* More basic types */ typedef UINT ITCH; typedef UINT CTCH; typedef UINT CB; typedef BOOL F; typedef PVOID PV; typedef CONST VOID *PCVOID; typedef CONST TCH *PCTCH, *PCTSTR; #define cbCtch(ctch) ((ctch) * sizeof(TCHAR)) #define ctchCb(cb) ((cb) / sizeof(TCHAR)) #define ctchMax ((CTCH)~0) #define CopyPtchPtchCtch(ptchDst, ptchSrc, ctch) \ memcpy(ptchDst, ptchSrc, cbCtch(ctch)) #define MovePtchPtchCtch(ptchDst, ptchSrc, ctch) \ memmove(ptchDst, ptchSrc, cbCtch(ctch)) #define fEqPtchPtchCtch(ptchDst, ptchSrc, ctch) \ !memcmp(ptchDst, ptchSrc, cbCtch(ctch)) #define pvSubPvCb(pv, cb) ((PV)((PBYTE)pv - (cb))) /* * Round cb up to the nearest multiple of cbAlign. cbAlign must be * a power of 2 whose evaluation entails no side-effects. */ #define ROUNDUP(cb, cbAlign) ((((cb) + (cbAlign) - 1) / (cbAlign)) * (cbAlign)) /* * Returns the number of elements in an array. */ #define cA(a) (sizeof(a)/sizeof(a[0])) /***************************************************************************** * * assert.c * *****************************************************************************/ void NORETURN CDECL Die(PCTSTR pszFormat, ...); int NORETURN STDCALL AssertPszPszLn(PCSTR pszExpr, PCSTR pszFile, int iLine); #ifdef DEBUG #define AssertFPsz(c, psz) ((c) ? 0 : AssertPszPszLn(psz, __FILE__, __LINE__)) #define Validate(c) ((c) ? 0 : AssertPszPszLn(#c, __FILE__, __LINE__)) #define D(x) x #else #define AssertFPsz(c, psz) #define Validate(c) (c) #define D(x) #endif #define Assert(c) AssertFPsz(c, #c) typedef unsigned long SIG; /* Signatures */ #define sigABCD(a,b,c,d) ((a) + ((b)<<8) + ((c)<<16) + ((d)<<24)) #define AssertPNm(p, nm) AssertFPsz((p)->sig == (sig##nm), "Assert"#nm) /***************************************************************************** * * tchMagic - Super-secret value used to signal out-of-band info * *****************************************************************************/ #define tchMagic '\0' /* Out-of-band marker */ #include "io.h" /* File I/O stuff */ #include "m4ctype.h" /* Character types */ #include "tok.h" /* Tokens */ #include "mem.h" /* Memory and GC */ #include "divert.h" /* Diversions */ #include "stream.h" /* Files, streams */ /***************************************************************************** * * A VAL records a macro's value, either the current value or a pushed * value. * * tok - text value (HeapAllocate'd) * fTrace - nonzero if this instance should be traced * pvalPrev - link to previous value * * A MACRO records an active macro. * * tokName - macro name (HeapAllocate'd) * pval - macro value * * A TSFL records the state of a token (token state flags). * *****************************************************************************/ typedef struct VALUE VAL, *PVAL; struct VALUE { D(SIG sig;) TOK tok; BOOL fTrace; PVAL pvalPrev; }; #define sigPval sigABCD('V', 'a', 'l', 'u') #define AssertPval(pval) AssertPNm(pval, Pval) typedef struct MACRO MAC, *PMAC, **PPMAC; struct MACRO { D(SIG sig;) PMAC pmacNext; TOK tokName; PVAL pval; }; #define sigPmac sigABCD('M', 'a', 'c', 'r') #define AssertPmac(pmac) AssertPNm(pmac, Pmac) extern PPMAC mphashpmac; /***************************************************************************** * * operators * * Each operator is called as op(argv), where argv is the magic * cookie for accessing argument vector. * * To access the parameters, use the following macros: * * ctokArgv -- Number of arguments provided, not including $0. * * ptokArgv(i) -- Access the i'th parameter * * Note that it is safe to pass a pptok because the call stack does * not grow during macro expansion. Therefore, the token array * cannot get reallocated. * * For convenience, ptokArgv(ctokArgv+1) is always ptokNil. * *****************************************************************************/ typedef PTOK ARGV; /* Argument vector cookie */ #define ptokArgv(i) (&argv[i]) #define ptchArgv(i) ptchPtok(ptokArgv(i)) #define ctchArgv(i) ctchSPtok(ptokArgv(i)) #define ctokArgv ((ITOK)ctchUPtok(ptokArgv(-1))) #define SetArgvCtok(ctok) SetPtokCtch(ptokArgv(-1), ctok) #define DeclareOp(op) void STDCALL op(ARGV argv) #define DeclareOpc(opc) void STDCALL opc(PTOK ptok, ITOK itok, DWORD dw) typedef void (STDCALL *OP)(ARGV argv); typedef void (STDCALL *OPC)(PTOK ptok, ITOK itok, DWORD dw); typedef void (STDCALL *MOP)(PMAC pmac); void STDCALL EachOpcArgvDw(OPC opc, ARGV argv, DWORD dw); void STDCALL EachReverseOpcArgvDw(OPC opc, ARGV argv, DWORD dw); void STDCALL EachMacroOp(MOP mop); extern OP rgop[]; /***************************************************************************** * * hash.c - Hashing * *****************************************************************************/ typedef unsigned long HASH; extern HASH g_hashMod; HASH STDCALL hashPtok(PCTOK ptok); void STDCALL InitHash(void); /***************************************************************************** * * obj.c - Basic object methods * *****************************************************************************/ void STDCALL PopdefPmac(PMAC pmac); void STDCALL PushdefPmacPtok(PMAC pmac, PCTOK ptok); void STDCALL FreePmac(PMAC pmac); PMAC STDCALL pmacFindPtok(PCTOK ptok); PMAC STDCALL pmacGetPtok(PCTOK ptok); F STDCALL PURE fEqPtokPtok(PCTOK ptok1, PCTOK ptok2); F STDCALL PURE fIdentPtok(PCTOK ptok); PTCH STDCALL ptchDupPtch(PCTCH ptch); PTCH STDCALL ptchDupPtok(PCTOK ptok); /***************************************************************************** * * at.c - Arithmetic types * *****************************************************************************/ typedef int AT; /* AT = arithmetic type */ typedef AT *PAT; /* Pointer to AT */ typedef int DAT; /* Delta to AT */ void STDCALL SkipWhitePtok(PTOK ptok); void STDCALL AddExpAt(AT at); void STDCALL PushAtRadixCtch(AT atConvert, unsigned radix, CTCH ctch); void STDCALL PushAt(AT at); F STDCALL PURE fEvalPtokPat(PTOK ptok, PAT at); AT STDCALL PURE atTraditionalPtok(PCTOK ptok); /***************************************************************************** * * eval.c - Arithmetic evaluation * *****************************************************************************/ extern struct CELL *rgcellEstack; /***************************************************************************** * * crackle.c - Macro expansion * *****************************************************************************/ void STDCALL PushSubstPtokArgv(PTOK ptok, ARGV argv); void STDCALL TraceArgv(ARGV argv); /***************************************************************************** * * main.c - Boring stuff * *****************************************************************************/ HF STDCALL hfInputPtchF(PTCH ptch, F fFatal); /***************************************************************************** * * predef.c - Predefined (a.k.a. built-in) macros * *****************************************************************************/ void STDCALL InitPredefs(void); /***************************************************************************** * * EachOp * * Before calling this macro, define the macro `x' to do whatever * you want. * * EachOpX * * Same as EachOp, except that it also includes the Eof magic. * *****************************************************************************/ #define EachOp() \ x(Define, define) \ x(Undefine, undefine) \ x(Defn, defn) \ x(Pushdef, pushdef) \ x(Popdef, popdef) \ x(Ifdef, ifdef) \ x(Shift, shift) \ /* x(Changequote, changequote) */ \ /* x(Changecom, changecom) */ \ x(Divert, divert) \ /* x(Undivert, undivert) */ \ x(Divnum, divnum) \ x(Dnl, dnl) \ x(Ifelse, ifelse) \ x(Incr, incr) \ x(Decr, decr) \ x(Eval, eval) \ x(Len, len) \ x(Index, index) \ x(Substr, substr) \ x(Translit, translit) \ x(Include, include) \ x(Sinclude, sinclude) \ /* x(Syscmd, syscmd) */ \ /* x(Sysval, sysval) */ \ /* x(Maketemp, maketemp) */ \ /* x(M4exit, m4exit) */ \ /* x(M4wrap, m4wrap) */ \ x(Errprint, errprint) \ x(Dumpdef, dumpdef) \ x(Traceon, traceon) \ x(Traceoff, traceoff) \ x(Patsubst, patsubst) /* GNU extension that the d3d guys rely on */ \ #define EachOpX() EachOp() x(Eof, eof) x(Eoi, eoi) #define x(cop, lop) DeclareOp(op##cop); EachOpX() #undef x enum MAGIC { #define x(cop, lop) tch##cop, EachOpX() #undef x tchMax, };