|
|
//---------------------------------------------------------------------------
// NtlParse.cpp - parses a ".ntl" file (Native Theme Language)
//---------------------------------------------------------------------------
#include "stdafx.h"
#include "scanner.h"
#include "NtlParse.h"
#include "Utils.h"
#include "SysMetrics.h"
#include "stringtable.h"
//---------------------------------------------------------------------------
#define SYSCOLOR_STRINGS
#include "SysColors.h"
//---------------------------------------------------------------------------
CNtlParser::CNtlParser() { _pPCode = NULL; _iPCodeAllocSize = 0;
_iIfLevel = 0;
for (int i=0; i < ARRAYSIZE(_iStateOffsets); i++) _iStateOffsets[i] = 0; } //---------------------------------------------------------------------------
HRESULT CNtlParser::SourceError(int iMsgResId, ...) { va_list args; va_start(args, iMsgResId);
LPCWSTR pszParam1 = va_arg(args, LPCWSTR); LPCWSTR pszParam2 = va_arg(args, LPCWSTR);
HRESULT hr = MakeErrorEx(iMsgResId, pszParam1, pszParam2, _scan._szFileName, _scan._szLineBuff, _scan._iLineNum); va_end(args);
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseBuffer(LPCWSTR pszSource, LPCWSTR pszSourceFileName, INtlParserCallBack *pCallBack, OUT BYTE **ppPCode, OUT int *piLen) { HRESULT hr = S_OK; _pCallBack = pCallBack;
_scan.AttachMultiLineBuffer(pszSource, pszSourceFileName);
//---- jump to state table at end ----
hr = EmitByte(NTL_JMP); if (FAILED(hr)) goto exit;
int iStateJumpOffset; iStateJumpOffset = int(_u.pb - _pPCode);
hr = EmitInt(0); if (FAILED(hr)) goto exit;
if (! _scan.GetChar('[')) { if (! _scan.EndOfFile()) { hr = SourceError(IDS_MISSING_SECTION_LBRACKET); goto exit; } }
while (! _scan.EndOfFile()) // process each section
{ WCHAR section[_MAX_PATH+1]; _scan.GetId(section);
if (lstrcmpi(section, L"OptionBits")==0) { hr = ParseOptionBitsSection(); } else if (lstrcmpi(section, L"Drawing")==0) { hr = ParseDrawingSection(); } else // "globals", "sysmetrics", or class section
{ hr = SourceError(IDS_UNKNOWN_SECTION_NAME); }
if (FAILED(hr)) break; }
if (FAILED(hr)) goto exit;
//---- update first jump to state table ----
int *ip; ip = (int *)(_pPCode + iStateJumpOffset); *ip = (int)(_u.pb - _pPCode);
//---- build state table at end of stream ----
BYTE iMaxState; iMaxState = 0; for (BYTE i=ARRAYSIZE(_iStateOffsets)-1; i >= 0; i--) { if (_iStateOffsets[i]) { iMaxState = i; break; } }
hr = EmitByte(iMaxState); if (FAILED(hr)) goto exit;
for (int i=1; i <= iMaxState; i++) { hr = EmitInt(_iStateOffsets[i]); if (FAILED(hr)) goto exit; }
exit: if (SUCCEEDED(hr)) { *ppPCode = _pPCode; *piLen = (int)(_u.pb - _pPCode); } else delete [] _pPCode;
_pPCode = NULL; _iPCodeAllocSize = 0;
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseOptionBitsSection() { HRESULT hr = S_OK; WCHAR szOptionName[_MAX_PATH+1];
if (!_scan.GetChar(']')) hr = SourceError(IDS_EXPECTED_END_OF_SECTION); else { while (! _scan.EndOfFile()) { if (_scan.GetChar('[')) // start of new section
break;
if (! _scan.GetId(szOptionName)) { hr = SourceError(IDS_OPTIONNAME_EXPECTED); break; }
if (! _scan.GetChar('=')) { hr = SourceError(IDS_EXPECTED_EQUALS_SIGN); break; }
int iOptionValue; if (! _scan.GetNumber(&iOptionValue)) { hr = SourceError(IDS_INT_EXPECTED); break; }
hr = AddOptionBitName(szOptionName, iOptionValue); if (FAILED(hr)) break; } }
if (FAILED(hr)) goto exit;
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::AddOptionBitName(LPCWSTR szOptionName, int iOptionValue) { HRESULT hr = S_OK; OPTIONBITENTRY option; option.csName = szOptionName; option.iValue = iOptionValue;
for (int i=0; i < _OptionBits.m_nSize; i++) { if ((iOptionValue == _OptionBits[i].iValue) && (lstrcmpi(szOptionName, _OptionBits[i].csName)==0)) break; }
if (i < _OptionBits.m_nSize) // found
hr = SourceError(IDS_ALREADY_DEFINED); else _OptionBits.Add(option);
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::GetBitnumVal(LPCWSTR szName, BYTE *piValue) { HRESULT hr;
hr = MakeErrorEx(IDS_UNKNOWN_BITNAME, szName); for (BYTE i=0; i < _OptionBits.m_nSize; i++) { if (lstrcmpi(szName, _OptionBits[i].csName)==0) { *piValue = i; hr = S_OK; break; } }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseDrawingSection() { HRESULT hr = S_OK; WCHAR szStateName[_MAX_PATH+1]; WCHAR szCmd[_MAX_PATH+1];
if (! _scan.GetChar('(')) { hr = SourceError(IDS_LEFTPAREN_EXPECTED); goto exit; } if (! _scan.GetId(szStateName)) { hr = SourceError(IDS_STATENAME_EXPECTED); goto exit; }
BYTE iStateNum; hr = GetStateNum(szStateName, &iStateNum); if (FAILED(hr)) goto exit; if ((iStateNum < 1) || (iStateNum > MAX_STATES)) { hr = SourceError(IDS_UNKNOWN_STATE, szStateName); goto exit; }
_iStateOffsets[iStateNum] = int(_u.pb - _pPCode);
if (! _scan.GetChar(']')) { hr = SourceError(IDS_RBRACKET_EXPECTED); goto exit; }
while (! _scan.EndOfFile()) { if (_scan.GetChar('[')) // start of new section
break;
if (! _scan.GetId(szCmd)) { hr = SourceError(IDS_DRAWINGPROP_EXPECTED); break; }
if (! _scan.GetChar('=')) { hr = SourceError(IDS_EXPECTED_EQUALS_SIGN); break; }
if (lstrcmpi(szCmd, L"AddBorder")==0) hr = ParseAddBorder(); else if (lstrcmpi(szCmd, L"FillBorder")==0) hr = ParseFillBorder(); else if (lstrcmpi(szCmd, L"LogicalRect")==0) hr = ParseLogicalRect(); else if (lstrcmpi(szCmd, L"FillBrush")==0) hr = ParseFillBrush(); else if (lstrcmpi(szCmd, L"LineBrush")==0) hr = ParseLineBrush(); else if (lstrcmpi(szCmd, L"MoveTo")==0) hr = ParseMoveTo(); else if (lstrcmpi(szCmd, L"LineTo")==0) hr = ParseLineTo(); else if (lstrcmpi(szCmd, L"CurveTo")==0) hr = ParseCurveTo(); else if (lstrcmpi(szCmd, L"Shape")==0) hr = ParseShape(); else if (lstrcmpi(szCmd, L"EndShape")==0) hr = ParseEndShape(); else if (lstrcmpi(szCmd, L"if")==0) hr = ParseIf(); else if (lstrcmpi(szCmd, L"else")==0) hr = ParseElse(); else if (lstrcmpi(szCmd, L"endif")==0) hr = ParseEndIf(); else if (lstrcmpi(szCmd, L"SetOption")==0) hr = ParseSetOption(); else if (lstrcmpi(szCmd, L"GotoState")==0) hr = ParseGotoState(); else hr = SourceError(IDS_DRAWINGPROP_EXPECTED);
if (FAILED(hr)) goto exit;
if (! _scan.EndOfLine()) { hr = SourceError(IDS_EXTRA_PROP_TEXT, _scan._p); goto exit; }
_scan.ForceNextLine(); }
if (SUCCEEDED(hr)) hr = EmitByte(NTL_RETURN); // return to caller (no params)
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseLogicalRect() { HRESULT hr; hr = EmitByte(NTL_LOGRECT);
if (SUCCEEDED(hr)) { if (! _scan.GetKeyword(L"RECT")) { hr = SourceError(IDS_RECT_EXPECTED); } else { hr = ParseEmitRect(); } } return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::EmitCheck(int iLen) { HRESULT hr = S_OK;
int iOffset = (int)(_u.pb - _pPCode);
if (iOffset + iLen > _iPCodeAllocSize) { int iSize = _iPCodeAllocSize + 4096; BYTE *pNew = (BYTE *)realloc(_pPCode, iSize);
if (! pNew) { hr = MakeError32(E_OUTOFMEMORY); } else { _pPCode = pNew; _iPCodeAllocSize = iSize; _u.pb = _pPCode + iOffset; } }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::EmitByte(BYTE eOpCode) { HRESULT hr = EmitCheck(1); if (SUCCEEDED(hr)) { *_u.pb++ = eOpCode; }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::EmitInt(int iValue) { HRESULT hr = EmitCheck(sizeof(int)); if (SUCCEEDED(hr)) { *_u.pi++ = iValue; }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::EmitShort(SHORT sValue) { HRESULT hr = EmitCheck(sizeof(SHORT)); if (SUCCEEDED(hr)) { *_u.ps++ = sValue; }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::EmitString(LPCWSTR szValue) { int len = sizeof(WCHAR) * (1 + lstrlen(szValue));
HRESULT hr = EmitCheck(len); if (SUCCEEDED(hr)) { lstrcpy(_u.pw, szValue); _u.pb += len; }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEmitPoint() { HRESULT hr = S_OK; int ix, iy;
if (! _scan.GetNumber(&ix)) { hr = SourceError(IDS_INT_EXPECTED); goto exit; }
if (! _scan.GetNumber(&iy)) { hr = SourceError(IDS_INT_EXPECTED); goto exit; }
hr = EmitInt(ix); if (FAILED(hr)) goto exit;
hr = EmitInt(iy); if (FAILED(hr)) goto exit;
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEmitRect() { HRESULT hr = S_OK; int iValue; for (int i=0; i < 4; i++) { if (! _scan.GetNumber(&iValue)) { hr = SourceError(IDS_INT_EXPECTED); goto exit; }
hr = EmitInt(iValue); if (FAILED(hr)) goto exit; }
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEmitSize2() { HRESULT hr = ParseEmitSize(); // first size
if (FAILED(hr)) goto exit;
if (_scan.GetChar(',')) { hr = ParseEmitSize(); // second size
if (FAILED(hr)) goto exit; }
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEmitSize4() { HRESULT hr = ParseEmitSize(); // first size
if (FAILED(hr)) goto exit;
if (_scan.GetChar(',')) { hr = ParseEmitSize(); // second size
if (FAILED(hr)) goto exit;
if (_scan.GetChar(',')) { hr = ParseEmitSize(); // third size
if (FAILED(hr)) goto exit;
if (! _scan.GetChar(',')) { hr = SourceError(IDS_COMMA_EXPECTED); goto exit; }
hr = ParseEmitSize(); // forth size
if (FAILED(hr)) goto exit; } }
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEmitSize() { HRESULT hr = S_OK; int iValue; WCHAR szId[_MAX_PATH+1];
if (_scan.GetNumber(&iValue)) { hr = EmitInt(iValue); if (FAILED(hr)) goto exit; } else if (_scan.GetId(szId)) { int cnt = ARRAYSIZE(pszSysMetricIntNames); for (SHORT i=0; i < cnt; i++) { if (lstrcmpi(szId, pszSysMetricIntNames[i])==0) { hr = EmitByte(PT_SYSMETRICINDEX); if (FAILED(hr)) goto exit;
hr = EmitShort(i); if (FAILED(hr)) goto exit;
break; }
if (i == cnt) { hr = SourceError(IDS_SIZE_EXPECTED); goto exit; } } } else hr = SourceError(IDS_SIZE_EXPECTED);
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEmitImagefile() { HRESULT hr = S_OK;
int iIndex; if (! _scan.GetNumber(&iIndex)) iIndex = 0;
//---- emit imagefile ----
hr = EmitByte(PT_IMAGEFILE); if (FAILED(hr)) goto exit;
hr = EmitByte((BYTE)iIndex); if (FAILED(hr)) goto exit;
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEmitColor4() { HRESULT hr = ParseEmitColor(); // first color
if (FAILED(hr)) goto exit;
if (_scan.GetChar(',')) { hr = ParseEmitColor(); // second color
if (FAILED(hr)) goto exit;
if (_scan.GetChar(',')) { hr = ParseEmitColor(); // third color
if (FAILED(hr)) goto exit;
if (! _scan.GetChar(',')) { hr = SourceError(IDS_COMMA_EXPECTED); goto exit; }
hr = ParseEmitColor(); // forth color
if (FAILED(hr)) goto exit; } }
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEmitColor() { HRESULT hr = S_OK; int iRed, iGreen, iBlue; WCHAR szColorId[_MAX_PATH+1];
if (_scan.GetNumber(&iRed)) // RGB numbers specified
{ hr = EmitByte(PT_COLORREF); if (FAILED(hr)) goto exit;
if (! _scan.GetNumber(&iGreen)) { hr = SourceError(IDS_INT_EXPECTED); goto exit; }
if (! _scan.GetNumber(&iBlue)) { hr = SourceError(IDS_INT_EXPECTED); goto exit; }
COLORREF cr = RGB(iRed, iGreen, iBlue);
hr = EmitInt(cr); if (FAILED(hr)) goto exit; } else if (_scan.GetId(szColorId)) { if (lstrcmpi(szColorId, L"NONE")) hr = EmitByte(PT_COLORNULL); else { for (SHORT i=0; i < iSysColorSize; i++) { if (lstrcmpi(szColorId, pszSysColorNames[i])==0) { hr = EmitByte(PT_SYSCOLORINDEX); if (SUCCEEDED(hr)) hr = EmitShort(i); break; } }
if (i == iSysColorSize) hr = SourceError(IDS_COLORVALUE_EXPECTED); } } else hr = SourceError(IDS_COLORVALUE_EXPECTED);
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEmitNone() { HRESULT hr = EmitByte(PT_COLORNULL); return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseAddBorder() { HRESULT hr = S_OK;
while (SUCCEEDED(hr)) { if (_scan.GetKeyword(L"SIZE")) { hr = ParseEmitSize4(); } else if (_scan.GetKeyword(L"COLOR")) { hr = ParseEmitColor4(); } else break; }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseFillBorder() { HRESULT hr = S_OK;
while (SUCCEEDED(hr)) { if (_scan.GetKeyword(L"COLOR")) { hr = ParseEmitColor(); } else if (_scan.GetKeyword(L"IMAGEFILE")) { hr = ParseEmitImagefile(); } else if (_scan.GetKeyword(L"NONE")) { hr = ParseEmitNone(); } else break; }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseFillBrush() { HRESULT hr; hr = EmitByte(NTL_FILLBRUSH);
while (SUCCEEDED(hr)) { if (_scan.GetKeyword(L"COLOR")) { hr = ParseEmitColor(); } else if (_scan.GetKeyword(L"IMAGEFILE")) { hr = ParseEmitImagefile(); } else if (_scan.GetKeyword(L"NONE")) { hr = ParseEmitNone(); } else break; }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseLineBrush() { HRESULT hr; hr = EmitByte(NTL_LINEBRUSH);
if (_scan.GetKeyword(L"NONE")) { hr = ParseEmitNone(); } else { while (SUCCEEDED(hr)) { if (_scan.GetKeyword(L"COLOR")) { hr = ParseEmitColor(); } else if (_scan.GetKeyword(L"SIZE")) { hr = ParseEmitSize(); } else break; } }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseMoveTo() { HRESULT hr; hr = EmitByte(NTL_MOVETO); if (SUCCEEDED(hr)) { if (! _scan.GetKeyword(L"POINT")) hr = SourceError(IDS_POINT_EXPECTED); else hr = ParseEmitPoint(); }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseLineTo() { HRESULT hr; hr = EmitByte(NTL_LINETO); if (SUCCEEDED(hr)) { if (! _scan.GetKeyword(L"POINT")) hr = SourceError(IDS_POINT_EXPECTED); else hr = ParseEmitPoint(); }
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseCurveTo() { HRESULT hr; hr = EmitByte(NTL_CURVETO); if (SUCCEEDED(hr)) { if (! _scan.GetKeyword(L"POINT")) hr = SourceError(IDS_POINT_EXPECTED); }
if (SUCCEEDED(hr)) hr = ParseEmitPoint(); if (SUCCEEDED(hr)) hr = ParseEmitPoint(); if (SUCCEEDED(hr)) hr = ParseEmitPoint();
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseShape() { HRESULT hr; hr = EmitByte(NTL_SHAPE); if (SUCCEEDED(hr)) { if (! _scan.GetKeyword(L"POINT")) hr = SourceError(IDS_POINT_EXPECTED); }
if (SUCCEEDED(hr)) hr = ParseEmitPoint();
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEndShape() { HRESULT hr; hr = EmitByte(NTL_ENDSHAPE); if (SUCCEEDED(hr)) { if (! _scan.GetKeyword(L"POINT")) hr = SourceError(IDS_POINT_EXPECTED); }
if (SUCCEEDED(hr)) hr = ParseEmitPoint();
return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseIf() { HRESULT hr = S_OK; WCHAR szId[_MAX_PATH+1]; NTL_OPCODE opcode; IFRECORD ifrec; if (! _scan.GetId(szId)) { hr = SourceError(IDS_OPTIONNAME_EXPECTED); goto exit; }
BYTE iBitnum; hr = GetBitnumVal(szId, &iBitnum); if (FAILED(hr)) goto exit;
if (! _scan.GetChar('(')) { hr = SourceError(IDS_LEFTPAREN_EXPECTED); goto exit; }
if (_scan.GetKeyword(L"on")) { opcode = NTL_JMPOFF; } else if (_scan.GetKeyword(L"off")) { opcode = NTL_JMPON; } else { hr = SourceError(IDS_ONOFF_EXPECTED); goto exit; }
if (! _scan.GetChar(')')) { hr = SourceError(IDS_LEFTPAREN_EXPECTED); goto exit; }
hr = EmitByte(static_cast<BYTE>(opcode)); if (FAILED(hr)) goto exit;
hr = EmitByte(iBitnum); if (FAILED(hr)) goto exit;
//---- create a new active IFRECORD ----
if (_iIfLevel == MAX_IF_NESTING) { hr = SourceError(IDS_MAX_IFNESTING); goto exit; }
ifrec.iBitNum = iBitnum; ifrec.fIfOn = (opcode == NTL_JMPOFF); ifrec.iIfOffset = (int)(_u.pb - _pPCode); ifrec.iElseOffset = 0;
_IfStack[_iIfLevel++] = ifrec;
//---- emit the jump offset ----
hr = EmitInt(0); // will be fixed up later
if (FAILED(hr)) goto exit;
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseElse() { HRESULT hr = S_OK; WCHAR szId[_MAX_PATH+1]; if (! _scan.GetId(szId)) { hr = SourceError(IDS_OPTIONNAME_EXPECTED); goto exit; }
BYTE iBitnum; hr = GetBitnumVal(szId, &iBitnum); if (FAILED(hr)) goto exit;
if (! _scan.GetChar('(')) { hr = SourceError(IDS_LEFTPAREN_EXPECTED); goto exit; }
BOOL fElseOn; if (_scan.GetKeyword(L"on")) { fElseOn = TRUE; } else if (_scan.GetKeyword(L"off")) { fElseOn = FALSE; } else { hr = SourceError(IDS_ONOFF_EXPECTED); goto exit; }
if (! _scan.GetChar(')')) { hr = SourceError(IDS_LEFTPAREN_EXPECTED); goto exit; }
//---- emit the JMP ----
hr = EmitByte(NTL_JMP); if (FAILED(hr)) goto exit;
//---- validate the IFRECORD ----
if (! _iIfLevel) { hr = SourceError(IDS_NOMATCHINGIF); goto exit; } IFRECORD *ifrec; ifrec = &_IfStack[_iIfLevel - 1];
if (ifrec->iBitNum != iBitnum) { hr = SourceError(IDS_WRONG_IF_BITNAME); goto exit; }
if (ifrec->fIfOn == fElseOn) { hr = SourceError(IDS_WRONG_ELSE_PARAM); goto exit; } //---- update the IFRECORD ----
ifrec->iElseOffset = (int)(_u.pb - _pPCode);
//---- emit the jump offset ----
hr = EmitInt(0); // will be fixed up later
//---- fixup the IF jmp ----
int *ip; ip = (int *)(_pPCode + ifrec->iIfOffset); *ip = (int)(_u.pb - _pPCode); // point to next instruction
ifrec->iIfOffset = 0; // update no longer needed
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseEndIf() { HRESULT hr = S_OK; WCHAR szId[_MAX_PATH+1]; if (! _scan.GetId(szId)) { hr = SourceError(IDS_OPTIONNAME_EXPECTED); goto exit; }
BYTE iBitnum; hr = GetBitnumVal(szId, &iBitnum); if (FAILED(hr)) goto exit;
//---- validate the IFRECORD ----
if (! _iIfLevel) { hr = SourceError(IDS_NOMATCHINGIF); goto exit; } IFRECORD *ifrec; ifrec = &_IfStack[_iIfLevel - 1];
if (ifrec->iBitNum != iBitnum) { hr = SourceError(IDS_WRONG_IF_BITNAME); goto exit; }
//---- fixup where needed ----
int *ip; if (ifrec->iIfOffset) ip = (int *)(_pPCode + ifrec->iIfOffset); else ip = (int *)(_pPCode + ifrec->iElseOffset);
*ip = (int)(_u.pb - _pPCode); // point to next instruction
_iIfLevel--;
exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseSetOption() { HRESULT hr = S_OK; WCHAR szId[_MAX_PATH+1]; if (! _scan.GetId(szId)) { hr = SourceError(IDS_OPTIONNAME_EXPECTED); goto exit; }
BYTE iBitnum; hr = GetBitnumVal(szId, &iBitnum); if (FAILED(hr)) goto exit;
if (! _scan.GetChar('(')) { hr = SourceError(IDS_LEFTPAREN_EXPECTED); goto exit; }
BYTE opcode; if (_scan.GetKeyword(L"on")) { opcode = NTL_SETOPTION; } else if (_scan.GetKeyword(L"off")) { opcode = NTL_CLROPTION; } else { hr = SourceError(IDS_ONOFF_EXPECTED); goto exit; }
hr = EmitByte(opcode); if (FAILED(hr)) goto exit; hr = EmitByte(iBitnum); exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::ParseGotoState() { HRESULT hr = S_OK; WCHAR szId[_MAX_PATH+1]; if (! _scan.GetId(szId)) { hr = SourceError(IDS_STATEID_EXPECTED); goto exit; }
BYTE iStateNum; hr = GetStateNum(szId, &iStateNum); if (FAILED(hr)) goto exit;
if ((iStateNum < 1) || (iStateNum > MAX_STATES)) { hr = SourceError(IDS_BAD_STATENUM); goto exit; }
if (! _iStateOffsets[iStateNum]) { hr = SourceError(IDS_STATE_MUST_BE_DEFINED, szId); goto exit; }
EmitByte(NTL_JMP); EmitInt(_iStateOffsets[iStateNum]); exit: return hr; } //---------------------------------------------------------------------------
HRESULT CNtlParser::GetStateNum(LPCWSTR pszStateName, BYTE *piNum) { HRESULT hr;
if (_pCallBack) hr = _pCallBack->GetStateNum(pszStateName, piNum); else { hr = MakeError32(ERROR_INTERNAL_ERROR); Log(LOG_ERROR, L"CNtlParser::GetStateNum - no callback defined"); } return hr; } //---------------------------------------------------------------------------
|