windows-nt/Source/XPSP1/NT/sdktools/m4/m4.h
2020-09-26 16:20:57 +08:00

399 lines
12 KiB
C

/*****************************************************************************
*
* m4.h
*
*****************************************************************************/
#ifdef POSIX
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
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 <windows.h>
#define EOL TEXT("\r\n")
#define cbEol 2
#endif
#include <stddef.h> /* 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 /* <windows.h> 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,
};