273 lines
8.2 KiB
C
273 lines
8.2 KiB
C
|
/*
|
||
|
* Parser
|
||
|
*/
|
||
|
|
||
|
#ifndef DUI_PARSER_PARSEROBJ_H_INCLUDED
|
||
|
#define DUI_PARSER_PARSEROBJ_H_INCLUDED
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
namespace DirectUI
|
||
|
{
|
||
|
|
||
|
#define MAXIDENT 31
|
||
|
|
||
|
////////////////////////////////////////////////////////
|
||
|
// Parser table definitions
|
||
|
|
||
|
struct EnumTable
|
||
|
{
|
||
|
LPWSTR pszEnum;
|
||
|
int nEnum;
|
||
|
};
|
||
|
|
||
|
typedef HRESULT (*PLAYTCREATE)(int, int*, Value**);
|
||
|
struct LayoutTable
|
||
|
{
|
||
|
LPWSTR pszLaytType;
|
||
|
PLAYTCREATE pfnLaytCreate;
|
||
|
};
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
LPWSTR pszElType;
|
||
|
IClassInfo* pci;
|
||
|
} ElementTable;
|
||
|
|
||
|
struct SysColorTable
|
||
|
{
|
||
|
LPWSTR pszSysColor;
|
||
|
int nSysColor;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////
|
||
|
// Parser tree data structures
|
||
|
// Parse tree nodes are any data structure dynamically allocated to store tree information
|
||
|
|
||
|
// Parse tree node types
|
||
|
#define NT_ValueNode 0
|
||
|
#define NT_PropValPairNode 1
|
||
|
#define NT_ElementNode 2
|
||
|
#define NT_AttribNode 3
|
||
|
#define NT_RuleNode 4
|
||
|
#define NT_SheetNode 5
|
||
|
|
||
|
// Tree node base class
|
||
|
struct Node
|
||
|
{
|
||
|
BYTE nType;
|
||
|
};
|
||
|
|
||
|
// Value node
|
||
|
#define VNT_Normal 0
|
||
|
#define VNT_LayoutCreate 1
|
||
|
#define VNT_SheetRef 2
|
||
|
#define VNT_EnumFixup 3 // Map name to int Value once PropertyInfo is known
|
||
|
|
||
|
struct LayoutCreate
|
||
|
{
|
||
|
union
|
||
|
{
|
||
|
PLAYTCREATE pfnLaytCreate;
|
||
|
LPWSTR pszLayout; // Fixup happens immediately during Value creation
|
||
|
};
|
||
|
int dNumParams;
|
||
|
int* pParams;
|
||
|
};
|
||
|
|
||
|
struct EnumsList
|
||
|
{
|
||
|
int dNumParams;
|
||
|
LPWSTR* pEnums; // Enums to be OR'd
|
||
|
};
|
||
|
|
||
|
struct ValueNode : Node
|
||
|
{
|
||
|
BYTE nValueType;
|
||
|
union
|
||
|
{
|
||
|
Value* pv; // VNT_Normal
|
||
|
LayoutCreate lc; // VNT_LayoutCreate, created during Element creates
|
||
|
LPWSTR psres; // VNT_SheetRef
|
||
|
EnumsList el; // VNT_EnumFixup
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// Property/Value Pair
|
||
|
#define PVPNT_Normal 0
|
||
|
#define PVPNT_Fixup 1 // Map name to ppi once Element type is known
|
||
|
|
||
|
struct PropValPairNode : Node
|
||
|
{
|
||
|
BYTE nPropValPairType;
|
||
|
union
|
||
|
{
|
||
|
PropertyInfo* ppi; // PVPNT_Normal
|
||
|
LPWSTR pszProperty; // PVPNT_Fixup
|
||
|
};
|
||
|
ValueNode* pvn;
|
||
|
|
||
|
PropValPairNode* pNext;
|
||
|
};
|
||
|
|
||
|
// Element node
|
||
|
struct ElementNode : Node
|
||
|
{
|
||
|
IClassInfo* pci;
|
||
|
PropValPairNode* pPVNodes;
|
||
|
LPWSTR pszResID;
|
||
|
Value* pvContent;
|
||
|
|
||
|
ElementNode* pChild;
|
||
|
ElementNode* pNext;
|
||
|
};
|
||
|
|
||
|
// Sheet attribute node
|
||
|
#define PALOGOP_Equal 0
|
||
|
#define PALOGOP_NotEqual 1
|
||
|
|
||
|
struct AttribNode : PropValPairNode
|
||
|
{
|
||
|
UINT nLogOp;
|
||
|
};
|
||
|
|
||
|
// Sheet rule node
|
||
|
struct RuleNode : Node
|
||
|
{
|
||
|
IClassInfo* pci;
|
||
|
AttribNode* pCondNodes;
|
||
|
PropValPairNode* pDeclNodes;
|
||
|
|
||
|
RuleNode* pNext;
|
||
|
};
|
||
|
|
||
|
// Sheet node
|
||
|
struct SheetNode : Node
|
||
|
{
|
||
|
Value* pvSheet; // Create once all Rules are known
|
||
|
RuleNode* pRules;
|
||
|
LPWSTR pszResID;
|
||
|
};
|
||
|
|
||
|
// Intermediate parser data structures
|
||
|
struct ParamsList
|
||
|
{
|
||
|
int dNumParams;
|
||
|
int* pParams;
|
||
|
};
|
||
|
|
||
|
struct StartTag
|
||
|
{
|
||
|
WCHAR szTag[MAXIDENT];
|
||
|
WCHAR szResID[MAXIDENT];
|
||
|
PropValPairNode* pPVNodes;
|
||
|
};
|
||
|
|
||
|
// Parser
|
||
|
|
||
|
typedef void (CALLBACK *PPARSEERRORCB)(LPCWSTR pszError, LPCWSTR pszToken, int dLine);
|
||
|
|
||
|
class Parser
|
||
|
{
|
||
|
public:
|
||
|
static HRESULT Create(const CHAR* pBuffer, int cCharCount, HANDLE* pHList, PPARSEERRORCB pfnErrorCB, OUT Parser** ppParser);
|
||
|
static HRESULT Create(UINT uRCID, HANDLE* pHList, PPARSEERRORCB pfnErrorCB, OUT Parser** ppParser);
|
||
|
static HRESULT Create(LPCWSTR pFile, HANDLE* pHList, PPARSEERRORCB pfnErrorCB, OUT Parser** ppParser);
|
||
|
|
||
|
static HRESULT Create(const CHAR* pBuffer, int cCharCount, HINSTANCE hInst, PPARSEERRORCB pfnErrorCB, OUT Parser** ppParser);
|
||
|
static HRESULT Create(UINT uRCID, HINSTANCE hInst, PPARSEERRORCB pfnErrorCB, OUT Parser** ppParser);
|
||
|
static HRESULT Create(LPCWSTR pFile, HINSTANCE hInst, PPARSEERRORCB pfnErrorCB, OUT Parser** ppParser);
|
||
|
|
||
|
void Destroy() { HDelete<Parser>(this); }
|
||
|
|
||
|
HRESULT CreateElement(LPCWSTR pszResID, Element* peSubstitute, OUT Element** ppElement);
|
||
|
virtual Value* GetSheet(LPCWSTR pszResID);
|
||
|
LPCWSTR ResIDFromSheet(Value* pvSheet);
|
||
|
|
||
|
void GetPath(LPCWSTR pIn, LPWSTR pOut);
|
||
|
|
||
|
// Parser/scanner only use
|
||
|
int _Input(CHAR* pBuffer, int cMaxChars);
|
||
|
void* _TrackNodeAlloc(SIZE_T s); // Parse-tree node memory
|
||
|
void _UnTrackNodeAlloc(Node* pn); // Parse-tree node memory
|
||
|
void* _TrackAlloc(SIZE_T s); // Node-specific state
|
||
|
void* _TrackTempAlloc(SIZE_T s); // Parse-time temporary memory
|
||
|
void _TrackTempAlloc(void* pm); // Parse-time temporary memory
|
||
|
void* _TrackTempReAlloc(void* pm, SIZE_T s); // Parse-time temporary memory
|
||
|
void _UnTrackTempAlloc(void* pm); // Parse-time temporary memory
|
||
|
void _ParseError(LPCWSTR pszError, LPCWSTR pszToken, int dLine);
|
||
|
|
||
|
ValueNode* _CreateValueNode(BYTE nValueType, void* pData);
|
||
|
PropValPairNode* _CreatePropValPairNode(LPCWSTR pszProperty, ValueNode* pvn, UINT* pnLogOp = NULL);
|
||
|
RuleNode* _CreateRuleNode(LPCWSTR pszClass, AttribNode* pCondNodes, PropValPairNode* pDeclNodes);
|
||
|
ElementNode* _CreateElementNode(StartTag* pst, Value* pvContent);
|
||
|
SheetNode* _CreateSheetNode(LPCWSTR pszResID, RuleNode* pRuleNodes);
|
||
|
static int _QuerySysMetric(int idx);
|
||
|
static LPCWSTR _QuerySysMetricStr(int idx, LPWSTR psz, UINT c);
|
||
|
|
||
|
bool WasParseError() { return _fParseError; }
|
||
|
HANDLE GetHandle(int iHandle) { return _pHList[iHandle]; }
|
||
|
HINSTANCE GetHInstance() { return static_cast<HINSTANCE>(GetHandle(0)); } // Always assume 0th item is the default HINSTANCE used
|
||
|
|
||
|
static HRESULT ReplaceSheets(Element* pe, Parser* pFrom, Parser* pTo);
|
||
|
|
||
|
DynamicArray<ElementNode*>* _pdaElementList; // Root Element list
|
||
|
DynamicArray<SheetNode*>* _pdaSheetList; // Sheet list
|
||
|
|
||
|
// Global parser context
|
||
|
static Parser* g_pParserCtx;
|
||
|
static bool g_fParseAbort;
|
||
|
static HDC g_hDC;
|
||
|
static int g_nDPI;
|
||
|
static HRESULT g_hrParse; // Abnormal errors during parse
|
||
|
|
||
|
Parser() { }
|
||
|
HRESULT Initialize(const CHAR* pBuffer, int cCharCount, HANDLE* pHList, PPARSEERRORCB pfnErrorCB);
|
||
|
HRESULT Initialize(UINT uRCID, HANDLE* pHList, PPARSEERRORCB pfnErrorCB);
|
||
|
HRESULT Initialize(LPCWSTR pFile, HANDLE* pHList, PPARSEERRORCB pfnErrorCB);
|
||
|
|
||
|
// Single HINSTANCE, setup internal default list
|
||
|
// 0th entry is always default HINSTANCE when no handle is specified
|
||
|
HRESULT Initialize(const CHAR* pBuffer, int cCharCount, HINSTANCE hInst, PPARSEERRORCB pfnErrorCB) { _hDefault = hInst; return Initialize(pBuffer, cCharCount, &_hDefault, pfnErrorCB); }
|
||
|
HRESULT Initialize(UINT uRCID, HINSTANCE hInst, PPARSEERRORCB pfnErrorCB) { _hDefault = hInst; return Initialize(uRCID, &_hDefault, pfnErrorCB); }
|
||
|
HRESULT Initialize(LPCWSTR pFile, HINSTANCE hInst, PPARSEERRORCB pfnErrorCB) { _hDefault = hInst; return Initialize(pFile, &_hDefault, pfnErrorCB); }
|
||
|
|
||
|
virtual ~Parser();
|
||
|
|
||
|
virtual bool ConvertEnum(LPCWSTR pszEnum, int* pEnum, PropertyInfo* ppi);
|
||
|
virtual PLAYTCREATE ConvertLayout(LPCWSTR pszLayout);
|
||
|
virtual IClassInfo* ConvertElement(LPCWSTR pszElement);
|
||
|
|
||
|
private:
|
||
|
HRESULT _ParseBuffer(const CHAR* pBuffer, int cCharCount);
|
||
|
void _DestroyTables();
|
||
|
|
||
|
// Error handling
|
||
|
bool _fParseError;
|
||
|
PPARSEERRORCB _pfnErrorCB;
|
||
|
|
||
|
// Input callback buffer and tracking
|
||
|
const CHAR* _pInputBuf;
|
||
|
int _dInputChars;
|
||
|
int _dInputPtr;
|
||
|
|
||
|
// Parse tree allocations and temporary parse-time only allocations
|
||
|
DynamicArray<Node*>* _pdaNodeMemTrack; // Parser nodes
|
||
|
DynamicArray<void*>* _pdaMemTrack; // Parser node extra memory
|
||
|
DynamicArray<void*>* _pdaTempMemTrack; // Temp parse-time only memory
|
||
|
|
||
|
bool _FixupPropValPairNode(PropValPairNode* ppvpn, IClassInfo* pci, bool bRestrictVal);
|
||
|
|
||
|
WCHAR _szDrive[MAX_PATH]; // Drive letter to the file being parsed
|
||
|
WCHAR _szPath[MAX_PATH]; // Path to the file being parsed
|
||
|
|
||
|
HANDLE* _pHList; // Pointer to handle list used for exposing runtime handles during parse
|
||
|
HANDLE _hDefault; // Default handle list (1 item - default HINSTANCE) if no list is provided
|
||
|
|
||
|
HRESULT _InstantiateElementNode(ElementNode* pn, Element* peSubstitute, Element* peParent, OUT Element** ppElement);
|
||
|
};
|
||
|
|
||
|
} // namespace DirectUI
|
||
|
|
||
|
#endif // DUI_PARSER_PARSEROBJ_H_INCLUDED
|