| Index: xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
|
| diff --git a/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp b/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
|
| index 3b5f66dd729d97134eda89da38898bc9b9123bc4..8ecc85b4b7cfb2d0d745f56988bfb3010e68cea5 100644
|
| --- a/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
|
| +++ b/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
|
| @@ -1,572 +1,572 @@
|
| -// Copyright 2014 PDFium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
|
| -
|
| -#include "xfa_fm2js.h"
|
| -struct XFA_FMDChar {
|
| - static const FX_WCHAR* inc(const FX_WCHAR*& p) {
|
| - ++p;
|
| - return p;
|
| - }
|
| - static const FX_WCHAR* dec(const FX_WCHAR*& p) {
|
| - --p;
|
| - return p;
|
| - }
|
| - static uint16_t get(const FX_WCHAR* p) { return *p; }
|
| - static FX_BOOL isWhiteSpace(const FX_WCHAR* p) {
|
| - return (*p) == 0x09 || (*p) == 0x0b || (*p) == 0x0c || (*p) == 0x20;
|
| - }
|
| - static FX_BOOL isLineTerminator(const FX_WCHAR* p) {
|
| - return *p == 0x0A || *p == 0x0D;
|
| - }
|
| - static FX_BOOL isBinary(const FX_WCHAR* p) {
|
| - return (*p) >= '0' && (*p) <= '1';
|
| - }
|
| - static FX_BOOL isOctal(const FX_WCHAR* p) {
|
| - return (*p) >= '0' && (*p) <= '7';
|
| - }
|
| - static FX_BOOL isDigital(const FX_WCHAR* p) {
|
| - return (*p) >= '0' && (*p) <= '9';
|
| - }
|
| - static FX_BOOL isHex(const FX_WCHAR* p) {
|
| - return isDigital(p) || ((*p) >= 'a' && (*p) <= 'f') ||
|
| - ((*p) >= 'A' && (*p) <= 'F');
|
| - }
|
| - static FX_BOOL isAlpha(const FX_WCHAR* p) {
|
| - return ((*p) <= 'z' && (*p) >= 'a') || ((*p) <= 'Z' && (*p) >= 'A');
|
| - }
|
| - static FX_BOOL isAvalid(const FX_WCHAR* p, FX_BOOL flag = 0);
|
| - static FX_BOOL string2number(const FX_WCHAR* s,
|
| - FX_DOUBLE* pValue,
|
| - const FX_WCHAR*& pEnd);
|
| - static FX_BOOL isUnicodeAlpha(uint16_t ch);
|
| -};
|
| -inline FX_BOOL XFA_FMDChar::isAvalid(const FX_WCHAR* p, FX_BOOL flag) {
|
| - if (*p == 0) {
|
| - return 1;
|
| - }
|
| - if ((*p <= 0x0A && *p >= 0x09) || *p == 0x0D ||
|
| - (*p <= 0xd7ff && *p >= 0x20) || (*p <= 0xfffd && *p >= 0xe000)) {
|
| - return 1;
|
| - }
|
| - if (!flag) {
|
| - if (*p == 0x0B || *p == 0x0C) {
|
| - return 1;
|
| - }
|
| - }
|
| - return 0;
|
| -}
|
| -inline FX_BOOL XFA_FMDChar::string2number(const FX_WCHAR* s,
|
| - FX_DOUBLE* pValue,
|
| - const FX_WCHAR*& pEnd) {
|
| - if (s) {
|
| - *pValue = wcstod((wchar_t*)s, (wchar_t**)&pEnd);
|
| - }
|
| - return 0;
|
| -}
|
| -inline FX_BOOL XFA_FMDChar::isUnicodeAlpha(uint16_t ch) {
|
| - if (ch == 0 || ch == 0x0A || ch == 0x0D || ch == 0x09 || ch == 0x0B ||
|
| - ch == 0x0C || ch == 0x20 || ch == '.' || ch == ';' || ch == '"' ||
|
| - ch == '=' || ch == '<' || ch == '>' || ch == ',' || ch == '(' ||
|
| - ch == ')' || ch == ']' || ch == '[' || ch == '&' || ch == '|' ||
|
| - ch == '+' || ch == '-' || ch == '*' || ch == '/') {
|
| - return FALSE;
|
| - } else {
|
| - return TRUE;
|
| - }
|
| -}
|
| -static XFA_FMKeyword keyWords[] = {
|
| - {TOKand, 0x00000026, L"&"},
|
| - {TOKlparen, 0x00000028, L"("},
|
| - {TOKrparen, 0x00000029, L")"},
|
| - {TOKmul, 0x0000002a, L"*"},
|
| - {TOKplus, 0x0000002b, L"+"},
|
| - {TOKcomma, 0x0000002c, L","},
|
| - {TOKminus, 0x0000002d, L"-"},
|
| - {TOKdot, 0x0000002e, L"."},
|
| - {TOKdiv, 0x0000002f, L"/"},
|
| - {TOKlt, 0x0000003c, L"<"},
|
| - {TOKassign, 0x0000003d, L"="},
|
| - {TOKgt, 0x0000003e, L">"},
|
| - {TOKlbracket, 0x0000005b, L"["},
|
| - {TOKrbracket, 0x0000005d, L"]"},
|
| - {TOKor, 0x0000007c, L"|"},
|
| - {TOKdotscream, 0x0000ec11, L".#"},
|
| - {TOKdotstar, 0x0000ec18, L".*"},
|
| - {TOKdotdot, 0x0000ec1c, L".."},
|
| - {TOKle, 0x000133f9, L"<="},
|
| - {TOKne, 0x000133fa, L"<>"},
|
| - {TOKeq, 0x0001391a, L"=="},
|
| - {TOKge, 0x00013e3b, L">="},
|
| - {TOKdo, 0x00020153, L"do"},
|
| - {TOKkseq, 0x00020676, L"eq"},
|
| - {TOKksge, 0x000210ac, L"ge"},
|
| - {TOKksgt, 0x000210bb, L"gt"},
|
| - {TOKif, 0x00021aef, L"if"},
|
| - {TOKin, 0x00021af7, L"in"},
|
| - {TOKksle, 0x00022a51, L"le"},
|
| - {TOKkslt, 0x00022a60, L"lt"},
|
| - {TOKksne, 0x00023493, L"ne"},
|
| - {TOKksor, 0x000239c1, L"or"},
|
| - {TOKnull, 0x052931bb, L"null"},
|
| - {TOKbreak, 0x05518c25, L"break"},
|
| - {TOKksand, 0x09f9db33, L"and"},
|
| - {TOKend, 0x0a631437, L"end"},
|
| - {TOKeof, 0x0a63195a, L"eof"},
|
| - {TOKfor, 0x0a7d67a7, L"for"},
|
| - {TOKnan, 0x0b4f91dd, L"nan"},
|
| - {TOKksnot, 0x0b4fd9b1, L"not"},
|
| - {TOKvar, 0x0c2203e9, L"var"},
|
| - {TOKthen, 0x2d5738cf, L"then"},
|
| - {TOKelse, 0x45f65ee9, L"else"},
|
| - {TOKexit, 0x4731d6ba, L"exit"},
|
| - {TOKdownto, 0x4caadc3b, L"downto"},
|
| - {TOKreturn, 0x4db8bd60, L"return"},
|
| - {TOKinfinity, 0x5c0a010a, L"infinity"},
|
| - {TOKendwhile, 0x5c64bff0, L"endwhile"},
|
| - {TOKforeach, 0x67e31f38, L"foreach"},
|
| - {TOKendfunc, 0x68f984a3, L"endfunc"},
|
| - {TOKelseif, 0x78253218, L"elseif"},
|
| - {TOKwhile, 0x84229259, L"while"},
|
| - {TOKendfor, 0x8ab49d7e, L"endfor"},
|
| - {TOKthrow, 0x8db05c94, L"throw"},
|
| - {TOKstep, 0xa7a7887c, L"step"},
|
| - {TOKupto, 0xb5155328, L"upto"},
|
| - {TOKcontinue, 0xc0340685, L"continue"},
|
| - {TOKfunc, 0xcdce60ec, L"func"},
|
| - {TOKendif, 0xe0e8fee6, L"endif"},
|
| -};
|
| -static const FX_WORD KEYWORD_START = TOKdo;
|
| -static const FX_WORD KEYWORD_END = TOKendif;
|
| -const FX_WCHAR* XFA_FM_KeywordToString(XFA_FM_TOKEN op) {
|
| - return keyWords[op].m_keword;
|
| -}
|
| -CXFA_FMToken::CXFA_FMToken() {
|
| - m_type = TOKreserver;
|
| - m_uLinenum = 1;
|
| - m_pNext = 0;
|
| -}
|
| -CXFA_FMToken::CXFA_FMToken(FX_DWORD uLineNum) {
|
| - m_type = TOKreserver;
|
| - m_uLinenum = uLineNum;
|
| - m_pNext = 0;
|
| -}
|
| -CXFA_FMToken::~CXFA_FMToken() {}
|
| -CXFA_FMLexer::CXFA_FMLexer(const CFX_WideStringC& wsFormCalc,
|
| - CXFA_FMErrorInfo* pErrorInfo) {
|
| - m_pScript = wsFormCalc.GetPtr();
|
| - m_uLength = wsFormCalc.GetLength();
|
| - m_uCurrentLine = 1;
|
| - m_ptr = m_pScript;
|
| - m_pToken = 0;
|
| - m_pErrorInfo = pErrorInfo;
|
| -}
|
| -CXFA_FMToken* CXFA_FMLexer::NextToken() {
|
| - CXFA_FMToken* t = 0;
|
| - if (!m_pToken) {
|
| - m_pToken = Scan();
|
| - } else {
|
| - if (m_pToken->m_pNext) {
|
| - t = m_pToken->m_pNext;
|
| - delete m_pToken;
|
| - m_pToken = t;
|
| - } else {
|
| - t = m_pToken;
|
| - m_pToken = Scan();
|
| - delete t;
|
| - }
|
| - }
|
| - return m_pToken;
|
| -}
|
| -CXFA_FMToken* CXFA_FMLexer::Scan() {
|
| - uint16_t ch = 0;
|
| - CXFA_FMToken* p = new CXFA_FMToken(m_uCurrentLine);
|
| - if (!XFA_FMDChar::isAvalid(m_ptr)) {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return p;
|
| - }
|
| - int iRet = 0;
|
| - while (1) {
|
| - if (!XFA_FMDChar::isAvalid(m_ptr)) {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return p;
|
| - }
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - switch (ch) {
|
| - case 0:
|
| - p->m_type = TOKeof;
|
| - return p;
|
| - case 0x0A:
|
| - ++m_uCurrentLine;
|
| - p->m_uLinenum = m_uCurrentLine;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - break;
|
| - case 0x0D:
|
| - XFA_FMDChar::inc(m_ptr);
|
| - break;
|
| - case ';': {
|
| - const FX_WCHAR* pTemp = 0;
|
| - Comment(m_ptr, pTemp);
|
| - m_ptr = pTemp;
|
| - } break;
|
| - case '"': {
|
| - const FX_WCHAR* pTemp = 0;
|
| - p->m_type = TOKstring;
|
| - iRet = String(p, m_ptr, pTemp);
|
| - if (iRet) {
|
| - return p;
|
| - }
|
| - m_ptr = pTemp;
|
| - }
|
| - return p;
|
| - case '0':
|
| - case '1':
|
| - case '2':
|
| - case '3':
|
| - case '4':
|
| - case '5':
|
| - case '6':
|
| - case '7':
|
| - case '8':
|
| - case '9': {
|
| - p->m_type = TOKnumber;
|
| - const FX_WCHAR* pTemp = 0;
|
| - iRet = Number(p, m_ptr, pTemp);
|
| - m_ptr = pTemp;
|
| - if (iRet) {
|
| - Error(FMERR_BAD_SUFFIX_NUMBER);
|
| - return p;
|
| - }
|
| - }
|
| - return p;
|
| - case '=':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - if (ch == '=') {
|
| - p->m_type = TOKeq;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - } else {
|
| - p->m_type = TOKassign;
|
| - return p;
|
| - }
|
| - } else {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return p;
|
| - }
|
| - break;
|
| - case '<':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - if (ch == '=') {
|
| - p->m_type = TOKle;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - } else if (ch == '>') {
|
| - p->m_type = TOKne;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - } else {
|
| - p->m_type = TOKlt;
|
| - return p;
|
| - }
|
| - } else {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return p;
|
| - }
|
| - break;
|
| - case '>':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - if (ch == '=') {
|
| - p->m_type = TOKge;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - } else {
|
| - p->m_type = TOKgt;
|
| - return p;
|
| - }
|
| - } else {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return p;
|
| - }
|
| - break;
|
| - case ',':
|
| - p->m_type = TOKcomma;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - case '(':
|
| - p->m_type = TOKlparen;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - case ')':
|
| - p->m_type = TOKrparen;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - case '[':
|
| - p->m_type = TOKlbracket;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - case ']':
|
| - p->m_type = TOKrbracket;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - case '&':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - p->m_type = TOKand;
|
| - return p;
|
| - case '|':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - p->m_type = TOKor;
|
| - return p;
|
| - case '+':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - p->m_type = TOKplus;
|
| - return p;
|
| - case '-':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - p->m_type = TOKminus;
|
| - return p;
|
| - case '*':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - p->m_type = TOKmul;
|
| - return p;
|
| - case '/':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - if (ch == '/') {
|
| - const FX_WCHAR* pTemp = 0;
|
| - Comment(m_ptr, pTemp);
|
| - m_ptr = pTemp;
|
| - break;
|
| - } else {
|
| - p->m_type = TOKdiv;
|
| - return p;
|
| - }
|
| - } else {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return p;
|
| - }
|
| - break;
|
| - case '.':
|
| - XFA_FMDChar::inc(m_ptr);
|
| - if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - if (ch == '.') {
|
| - p->m_type = TOKdotdot;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - } else if (ch == '*') {
|
| - p->m_type = TOKdotstar;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - } else if (ch == '#') {
|
| - p->m_type = TOKdotscream;
|
| - XFA_FMDChar::inc(m_ptr);
|
| - return p;
|
| - } else if (ch <= '9' && ch >= '0') {
|
| - p->m_type = TOKnumber;
|
| - const FX_WCHAR* pTemp = 0;
|
| - XFA_FMDChar::dec(m_ptr);
|
| - iRet = Number(p, m_ptr, pTemp);
|
| - m_ptr = pTemp;
|
| - if (iRet) {
|
| - Error(FMERR_BAD_SUFFIX_NUMBER);
|
| - }
|
| - return p;
|
| - } else {
|
| - p->m_type = TOKdot;
|
| - return p;
|
| - }
|
| - } else {
|
| - ch = XFA_FMDChar::get(m_ptr);
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return p;
|
| - }
|
| - case 0x09:
|
| - case 0x0B:
|
| - case 0x0C:
|
| - case 0x20:
|
| - XFA_FMDChar::inc(m_ptr);
|
| - break;
|
| - default: {
|
| - const FX_WCHAR* pTemp = 0;
|
| - iRet = Identifiers(p, m_ptr, pTemp);
|
| - m_ptr = pTemp;
|
| - if (iRet) {
|
| - return p;
|
| - }
|
| - p->m_type = IsKeyword(p->m_wstring);
|
| - }
|
| - return p;
|
| - }
|
| - }
|
| -}
|
| -FX_DWORD CXFA_FMLexer::Number(CXFA_FMToken* t,
|
| - const FX_WCHAR* p,
|
| - const FX_WCHAR*& pEnd) {
|
| - FX_DOUBLE number = 0;
|
| - if (XFA_FMDChar::string2number(p, &number, pEnd)) {
|
| - return 1;
|
| - }
|
| - if (pEnd && XFA_FMDChar::isAlpha(pEnd)) {
|
| - return 1;
|
| - }
|
| - t->m_wstring = CFX_WideStringC(p, (pEnd - p));
|
| - return 0;
|
| -}
|
| -FX_DWORD CXFA_FMLexer::String(CXFA_FMToken* t,
|
| - const FX_WCHAR* p,
|
| - const FX_WCHAR*& pEnd) {
|
| - const FX_WCHAR* pStart = p;
|
| - uint16_t ch = 0;
|
| - XFA_FMDChar::inc(p);
|
| - ch = XFA_FMDChar::get(p);
|
| - while (ch) {
|
| - if (!XFA_FMDChar::isAvalid(p)) {
|
| - ch = XFA_FMDChar::get(p);
|
| - pEnd = p;
|
| - t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return 1;
|
| - }
|
| - if (ch == '"') {
|
| - XFA_FMDChar::inc(p);
|
| - if (!XFA_FMDChar::isAvalid(p)) {
|
| - ch = XFA_FMDChar::get(p);
|
| - pEnd = p;
|
| - t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return 1;
|
| - }
|
| - ch = XFA_FMDChar::get(p);
|
| - if (ch == '"') {
|
| - goto NEXT;
|
| - } else {
|
| - break;
|
| - }
|
| - }
|
| - NEXT:
|
| - XFA_FMDChar::inc(p);
|
| - ch = XFA_FMDChar::get(p);
|
| - }
|
| - pEnd = p;
|
| - t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| - return 0;
|
| -}
|
| -FX_DWORD CXFA_FMLexer::Identifiers(CXFA_FMToken* t,
|
| - const FX_WCHAR* p,
|
| - const FX_WCHAR*& pEnd) {
|
| - const FX_WCHAR* pStart = p;
|
| - uint16_t ch = 0;
|
| - ch = XFA_FMDChar::get(p);
|
| - XFA_FMDChar::inc(p);
|
| - if (!XFA_FMDChar::isAvalid(p)) {
|
| - pEnd = p;
|
| - t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return 1;
|
| - }
|
| - ch = XFA_FMDChar::get(p);
|
| - while (ch) {
|
| - if (!XFA_FMDChar::isAvalid(p)) {
|
| - pEnd = p;
|
| - t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| - Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| - return 1;
|
| - }
|
| - ch = XFA_FMDChar::get(p);
|
| - if (XFA_FMDChar::isUnicodeAlpha(ch)) {
|
| - XFA_FMDChar::inc(p);
|
| - } else {
|
| - pEnd = p;
|
| - t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| - return 0;
|
| - }
|
| - }
|
| - pEnd = p;
|
| - t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| - return 0;
|
| -}
|
| -void CXFA_FMLexer::Comment(const FX_WCHAR* p, const FX_WCHAR*& pEnd) {
|
| - unsigned ch = 0;
|
| - XFA_FMDChar::inc(p);
|
| - ch = XFA_FMDChar::get(p);
|
| - while (ch) {
|
| - if (ch == 0x0D) {
|
| - XFA_FMDChar::inc(p);
|
| - pEnd = p;
|
| - return;
|
| - }
|
| - if (ch == 0x0A) {
|
| - ++m_uCurrentLine;
|
| - XFA_FMDChar::inc(p);
|
| - pEnd = p;
|
| - return;
|
| - }
|
| - XFA_FMDChar::inc(p);
|
| - ch = XFA_FMDChar::get(p);
|
| - }
|
| - pEnd = p;
|
| -}
|
| -XFA_FM_TOKEN CXFA_FMLexer::IsKeyword(const CFX_WideStringC& str) {
|
| - int32_t iLength = str.GetLength();
|
| - uint32_t uHash = FX_HashCode_String_GetW(str.GetPtr(), iLength, TRUE);
|
| - int32_t iStart = KEYWORD_START, iEnd = KEYWORD_END;
|
| - int32_t iMid = (iStart + iEnd) / 2;
|
| - XFA_FMKeyword keyword;
|
| - do {
|
| - iMid = (iStart + iEnd) / 2;
|
| - keyword = keyWords[iMid];
|
| - if (uHash == keyword.m_uHash) {
|
| - return keyword.m_type;
|
| - } else if (uHash < keyword.m_uHash) {
|
| - iEnd = iMid - 1;
|
| - } else {
|
| - iStart = iMid + 1;
|
| - }
|
| - } while (iStart <= iEnd);
|
| - return TOKidentifier;
|
| -}
|
| -CXFA_FMLexer::~CXFA_FMLexer() {
|
| - m_pScript = 0;
|
| - m_ptr = m_pScript;
|
| - if (m_pToken) {
|
| - CXFA_FMToken* t1 = m_pToken;
|
| - CXFA_FMToken* t2 = t1->m_pNext;
|
| - while (t2) {
|
| - delete t1;
|
| - t1 = t2;
|
| - t2 = t2->m_pNext;
|
| - }
|
| - delete m_pToken;
|
| - m_pToken = 0;
|
| - }
|
| - m_pErrorInfo = 0;
|
| -}
|
| -void CXFA_FMLexer::Error(XFA_FM_ERRMSG msg, ...) {
|
| - m_pErrorInfo->linenum = m_uCurrentLine;
|
| - const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);
|
| - va_list ap;
|
| - va_start(ap, msg);
|
| - m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
|
| - va_end(ap);
|
| -}
|
| -FX_BOOL CXFA_FMLexer::HasError() const {
|
| - if (m_pErrorInfo->message.IsEmpty()) {
|
| - return FALSE;
|
| - }
|
| - return TRUE;
|
| -}
|
| +// Copyright 2014 PDFium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
|
| +
|
| +#include "xfa_fm2js.h"
|
| +struct XFA_FMDChar {
|
| + static const FX_WCHAR* inc(const FX_WCHAR*& p) {
|
| + ++p;
|
| + return p;
|
| + }
|
| + static const FX_WCHAR* dec(const FX_WCHAR*& p) {
|
| + --p;
|
| + return p;
|
| + }
|
| + static uint16_t get(const FX_WCHAR* p) { return *p; }
|
| + static FX_BOOL isWhiteSpace(const FX_WCHAR* p) {
|
| + return (*p) == 0x09 || (*p) == 0x0b || (*p) == 0x0c || (*p) == 0x20;
|
| + }
|
| + static FX_BOOL isLineTerminator(const FX_WCHAR* p) {
|
| + return *p == 0x0A || *p == 0x0D;
|
| + }
|
| + static FX_BOOL isBinary(const FX_WCHAR* p) {
|
| + return (*p) >= '0' && (*p) <= '1';
|
| + }
|
| + static FX_BOOL isOctal(const FX_WCHAR* p) {
|
| + return (*p) >= '0' && (*p) <= '7';
|
| + }
|
| + static FX_BOOL isDigital(const FX_WCHAR* p) {
|
| + return (*p) >= '0' && (*p) <= '9';
|
| + }
|
| + static FX_BOOL isHex(const FX_WCHAR* p) {
|
| + return isDigital(p) || ((*p) >= 'a' && (*p) <= 'f') ||
|
| + ((*p) >= 'A' && (*p) <= 'F');
|
| + }
|
| + static FX_BOOL isAlpha(const FX_WCHAR* p) {
|
| + return ((*p) <= 'z' && (*p) >= 'a') || ((*p) <= 'Z' && (*p) >= 'A');
|
| + }
|
| + static FX_BOOL isAvalid(const FX_WCHAR* p, FX_BOOL flag = 0);
|
| + static FX_BOOL string2number(const FX_WCHAR* s,
|
| + FX_DOUBLE* pValue,
|
| + const FX_WCHAR*& pEnd);
|
| + static FX_BOOL isUnicodeAlpha(uint16_t ch);
|
| +};
|
| +inline FX_BOOL XFA_FMDChar::isAvalid(const FX_WCHAR* p, FX_BOOL flag) {
|
| + if (*p == 0) {
|
| + return 1;
|
| + }
|
| + if ((*p <= 0x0A && *p >= 0x09) || *p == 0x0D ||
|
| + (*p <= 0xd7ff && *p >= 0x20) || (*p <= 0xfffd && *p >= 0xe000)) {
|
| + return 1;
|
| + }
|
| + if (!flag) {
|
| + if (*p == 0x0B || *p == 0x0C) {
|
| + return 1;
|
| + }
|
| + }
|
| + return 0;
|
| +}
|
| +inline FX_BOOL XFA_FMDChar::string2number(const FX_WCHAR* s,
|
| + FX_DOUBLE* pValue,
|
| + const FX_WCHAR*& pEnd) {
|
| + if (s) {
|
| + *pValue = wcstod((wchar_t*)s, (wchar_t**)&pEnd);
|
| + }
|
| + return 0;
|
| +}
|
| +inline FX_BOOL XFA_FMDChar::isUnicodeAlpha(uint16_t ch) {
|
| + if (ch == 0 || ch == 0x0A || ch == 0x0D || ch == 0x09 || ch == 0x0B ||
|
| + ch == 0x0C || ch == 0x20 || ch == '.' || ch == ';' || ch == '"' ||
|
| + ch == '=' || ch == '<' || ch == '>' || ch == ',' || ch == '(' ||
|
| + ch == ')' || ch == ']' || ch == '[' || ch == '&' || ch == '|' ||
|
| + ch == '+' || ch == '-' || ch == '*' || ch == '/') {
|
| + return FALSE;
|
| + } else {
|
| + return TRUE;
|
| + }
|
| +}
|
| +static XFA_FMKeyword keyWords[] = {
|
| + {TOKand, 0x00000026, L"&"},
|
| + {TOKlparen, 0x00000028, L"("},
|
| + {TOKrparen, 0x00000029, L")"},
|
| + {TOKmul, 0x0000002a, L"*"},
|
| + {TOKplus, 0x0000002b, L"+"},
|
| + {TOKcomma, 0x0000002c, L","},
|
| + {TOKminus, 0x0000002d, L"-"},
|
| + {TOKdot, 0x0000002e, L"."},
|
| + {TOKdiv, 0x0000002f, L"/"},
|
| + {TOKlt, 0x0000003c, L"<"},
|
| + {TOKassign, 0x0000003d, L"="},
|
| + {TOKgt, 0x0000003e, L">"},
|
| + {TOKlbracket, 0x0000005b, L"["},
|
| + {TOKrbracket, 0x0000005d, L"]"},
|
| + {TOKor, 0x0000007c, L"|"},
|
| + {TOKdotscream, 0x0000ec11, L".#"},
|
| + {TOKdotstar, 0x0000ec18, L".*"},
|
| + {TOKdotdot, 0x0000ec1c, L".."},
|
| + {TOKle, 0x000133f9, L"<="},
|
| + {TOKne, 0x000133fa, L"<>"},
|
| + {TOKeq, 0x0001391a, L"=="},
|
| + {TOKge, 0x00013e3b, L">="},
|
| + {TOKdo, 0x00020153, L"do"},
|
| + {TOKkseq, 0x00020676, L"eq"},
|
| + {TOKksge, 0x000210ac, L"ge"},
|
| + {TOKksgt, 0x000210bb, L"gt"},
|
| + {TOKif, 0x00021aef, L"if"},
|
| + {TOKin, 0x00021af7, L"in"},
|
| + {TOKksle, 0x00022a51, L"le"},
|
| + {TOKkslt, 0x00022a60, L"lt"},
|
| + {TOKksne, 0x00023493, L"ne"},
|
| + {TOKksor, 0x000239c1, L"or"},
|
| + {TOKnull, 0x052931bb, L"null"},
|
| + {TOKbreak, 0x05518c25, L"break"},
|
| + {TOKksand, 0x09f9db33, L"and"},
|
| + {TOKend, 0x0a631437, L"end"},
|
| + {TOKeof, 0x0a63195a, L"eof"},
|
| + {TOKfor, 0x0a7d67a7, L"for"},
|
| + {TOKnan, 0x0b4f91dd, L"nan"},
|
| + {TOKksnot, 0x0b4fd9b1, L"not"},
|
| + {TOKvar, 0x0c2203e9, L"var"},
|
| + {TOKthen, 0x2d5738cf, L"then"},
|
| + {TOKelse, 0x45f65ee9, L"else"},
|
| + {TOKexit, 0x4731d6ba, L"exit"},
|
| + {TOKdownto, 0x4caadc3b, L"downto"},
|
| + {TOKreturn, 0x4db8bd60, L"return"},
|
| + {TOKinfinity, 0x5c0a010a, L"infinity"},
|
| + {TOKendwhile, 0x5c64bff0, L"endwhile"},
|
| + {TOKforeach, 0x67e31f38, L"foreach"},
|
| + {TOKendfunc, 0x68f984a3, L"endfunc"},
|
| + {TOKelseif, 0x78253218, L"elseif"},
|
| + {TOKwhile, 0x84229259, L"while"},
|
| + {TOKendfor, 0x8ab49d7e, L"endfor"},
|
| + {TOKthrow, 0x8db05c94, L"throw"},
|
| + {TOKstep, 0xa7a7887c, L"step"},
|
| + {TOKupto, 0xb5155328, L"upto"},
|
| + {TOKcontinue, 0xc0340685, L"continue"},
|
| + {TOKfunc, 0xcdce60ec, L"func"},
|
| + {TOKendif, 0xe0e8fee6, L"endif"},
|
| +};
|
| +static const FX_WORD KEYWORD_START = TOKdo;
|
| +static const FX_WORD KEYWORD_END = TOKendif;
|
| +const FX_WCHAR* XFA_FM_KeywordToString(XFA_FM_TOKEN op) {
|
| + return keyWords[op].m_keword;
|
| +}
|
| +CXFA_FMToken::CXFA_FMToken() {
|
| + m_type = TOKreserver;
|
| + m_uLinenum = 1;
|
| + m_pNext = 0;
|
| +}
|
| +CXFA_FMToken::CXFA_FMToken(FX_DWORD uLineNum) {
|
| + m_type = TOKreserver;
|
| + m_uLinenum = uLineNum;
|
| + m_pNext = 0;
|
| +}
|
| +CXFA_FMToken::~CXFA_FMToken() {}
|
| +CXFA_FMLexer::CXFA_FMLexer(const CFX_WideStringC& wsFormCalc,
|
| + CXFA_FMErrorInfo* pErrorInfo) {
|
| + m_pScript = wsFormCalc.GetPtr();
|
| + m_uLength = wsFormCalc.GetLength();
|
| + m_uCurrentLine = 1;
|
| + m_ptr = m_pScript;
|
| + m_pToken = 0;
|
| + m_pErrorInfo = pErrorInfo;
|
| +}
|
| +CXFA_FMToken* CXFA_FMLexer::NextToken() {
|
| + CXFA_FMToken* t = 0;
|
| + if (!m_pToken) {
|
| + m_pToken = Scan();
|
| + } else {
|
| + if (m_pToken->m_pNext) {
|
| + t = m_pToken->m_pNext;
|
| + delete m_pToken;
|
| + m_pToken = t;
|
| + } else {
|
| + t = m_pToken;
|
| + m_pToken = Scan();
|
| + delete t;
|
| + }
|
| + }
|
| + return m_pToken;
|
| +}
|
| +CXFA_FMToken* CXFA_FMLexer::Scan() {
|
| + uint16_t ch = 0;
|
| + CXFA_FMToken* p = new CXFA_FMToken(m_uCurrentLine);
|
| + if (!XFA_FMDChar::isAvalid(m_ptr)) {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return p;
|
| + }
|
| + int iRet = 0;
|
| + while (1) {
|
| + if (!XFA_FMDChar::isAvalid(m_ptr)) {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return p;
|
| + }
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + switch (ch) {
|
| + case 0:
|
| + p->m_type = TOKeof;
|
| + return p;
|
| + case 0x0A:
|
| + ++m_uCurrentLine;
|
| + p->m_uLinenum = m_uCurrentLine;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + break;
|
| + case 0x0D:
|
| + XFA_FMDChar::inc(m_ptr);
|
| + break;
|
| + case ';': {
|
| + const FX_WCHAR* pTemp = 0;
|
| + Comment(m_ptr, pTemp);
|
| + m_ptr = pTemp;
|
| + } break;
|
| + case '"': {
|
| + const FX_WCHAR* pTemp = 0;
|
| + p->m_type = TOKstring;
|
| + iRet = String(p, m_ptr, pTemp);
|
| + if (iRet) {
|
| + return p;
|
| + }
|
| + m_ptr = pTemp;
|
| + }
|
| + return p;
|
| + case '0':
|
| + case '1':
|
| + case '2':
|
| + case '3':
|
| + case '4':
|
| + case '5':
|
| + case '6':
|
| + case '7':
|
| + case '8':
|
| + case '9': {
|
| + p->m_type = TOKnumber;
|
| + const FX_WCHAR* pTemp = 0;
|
| + iRet = Number(p, m_ptr, pTemp);
|
| + m_ptr = pTemp;
|
| + if (iRet) {
|
| + Error(FMERR_BAD_SUFFIX_NUMBER);
|
| + return p;
|
| + }
|
| + }
|
| + return p;
|
| + case '=':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + if (ch == '=') {
|
| + p->m_type = TOKeq;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + } else {
|
| + p->m_type = TOKassign;
|
| + return p;
|
| + }
|
| + } else {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return p;
|
| + }
|
| + break;
|
| + case '<':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + if (ch == '=') {
|
| + p->m_type = TOKle;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + } else if (ch == '>') {
|
| + p->m_type = TOKne;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + } else {
|
| + p->m_type = TOKlt;
|
| + return p;
|
| + }
|
| + } else {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return p;
|
| + }
|
| + break;
|
| + case '>':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + if (ch == '=') {
|
| + p->m_type = TOKge;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + } else {
|
| + p->m_type = TOKgt;
|
| + return p;
|
| + }
|
| + } else {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return p;
|
| + }
|
| + break;
|
| + case ',':
|
| + p->m_type = TOKcomma;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + case '(':
|
| + p->m_type = TOKlparen;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + case ')':
|
| + p->m_type = TOKrparen;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + case '[':
|
| + p->m_type = TOKlbracket;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + case ']':
|
| + p->m_type = TOKrbracket;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + case '&':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + p->m_type = TOKand;
|
| + return p;
|
| + case '|':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + p->m_type = TOKor;
|
| + return p;
|
| + case '+':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + p->m_type = TOKplus;
|
| + return p;
|
| + case '-':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + p->m_type = TOKminus;
|
| + return p;
|
| + case '*':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + p->m_type = TOKmul;
|
| + return p;
|
| + case '/':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + if (ch == '/') {
|
| + const FX_WCHAR* pTemp = 0;
|
| + Comment(m_ptr, pTemp);
|
| + m_ptr = pTemp;
|
| + break;
|
| + } else {
|
| + p->m_type = TOKdiv;
|
| + return p;
|
| + }
|
| + } else {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return p;
|
| + }
|
| + break;
|
| + case '.':
|
| + XFA_FMDChar::inc(m_ptr);
|
| + if (XFA_FMDChar::isAvalid(m_ptr)) {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + if (ch == '.') {
|
| + p->m_type = TOKdotdot;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + } else if (ch == '*') {
|
| + p->m_type = TOKdotstar;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + } else if (ch == '#') {
|
| + p->m_type = TOKdotscream;
|
| + XFA_FMDChar::inc(m_ptr);
|
| + return p;
|
| + } else if (ch <= '9' && ch >= '0') {
|
| + p->m_type = TOKnumber;
|
| + const FX_WCHAR* pTemp = 0;
|
| + XFA_FMDChar::dec(m_ptr);
|
| + iRet = Number(p, m_ptr, pTemp);
|
| + m_ptr = pTemp;
|
| + if (iRet) {
|
| + Error(FMERR_BAD_SUFFIX_NUMBER);
|
| + }
|
| + return p;
|
| + } else {
|
| + p->m_type = TOKdot;
|
| + return p;
|
| + }
|
| + } else {
|
| + ch = XFA_FMDChar::get(m_ptr);
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return p;
|
| + }
|
| + case 0x09:
|
| + case 0x0B:
|
| + case 0x0C:
|
| + case 0x20:
|
| + XFA_FMDChar::inc(m_ptr);
|
| + break;
|
| + default: {
|
| + const FX_WCHAR* pTemp = 0;
|
| + iRet = Identifiers(p, m_ptr, pTemp);
|
| + m_ptr = pTemp;
|
| + if (iRet) {
|
| + return p;
|
| + }
|
| + p->m_type = IsKeyword(p->m_wstring);
|
| + }
|
| + return p;
|
| + }
|
| + }
|
| +}
|
| +FX_DWORD CXFA_FMLexer::Number(CXFA_FMToken* t,
|
| + const FX_WCHAR* p,
|
| + const FX_WCHAR*& pEnd) {
|
| + FX_DOUBLE number = 0;
|
| + if (XFA_FMDChar::string2number(p, &number, pEnd)) {
|
| + return 1;
|
| + }
|
| + if (pEnd && XFA_FMDChar::isAlpha(pEnd)) {
|
| + return 1;
|
| + }
|
| + t->m_wstring = CFX_WideStringC(p, (pEnd - p));
|
| + return 0;
|
| +}
|
| +FX_DWORD CXFA_FMLexer::String(CXFA_FMToken* t,
|
| + const FX_WCHAR* p,
|
| + const FX_WCHAR*& pEnd) {
|
| + const FX_WCHAR* pStart = p;
|
| + uint16_t ch = 0;
|
| + XFA_FMDChar::inc(p);
|
| + ch = XFA_FMDChar::get(p);
|
| + while (ch) {
|
| + if (!XFA_FMDChar::isAvalid(p)) {
|
| + ch = XFA_FMDChar::get(p);
|
| + pEnd = p;
|
| + t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return 1;
|
| + }
|
| + if (ch == '"') {
|
| + XFA_FMDChar::inc(p);
|
| + if (!XFA_FMDChar::isAvalid(p)) {
|
| + ch = XFA_FMDChar::get(p);
|
| + pEnd = p;
|
| + t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return 1;
|
| + }
|
| + ch = XFA_FMDChar::get(p);
|
| + if (ch == '"') {
|
| + goto NEXT;
|
| + } else {
|
| + break;
|
| + }
|
| + }
|
| + NEXT:
|
| + XFA_FMDChar::inc(p);
|
| + ch = XFA_FMDChar::get(p);
|
| + }
|
| + pEnd = p;
|
| + t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| + return 0;
|
| +}
|
| +FX_DWORD CXFA_FMLexer::Identifiers(CXFA_FMToken* t,
|
| + const FX_WCHAR* p,
|
| + const FX_WCHAR*& pEnd) {
|
| + const FX_WCHAR* pStart = p;
|
| + uint16_t ch = 0;
|
| + ch = XFA_FMDChar::get(p);
|
| + XFA_FMDChar::inc(p);
|
| + if (!XFA_FMDChar::isAvalid(p)) {
|
| + pEnd = p;
|
| + t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return 1;
|
| + }
|
| + ch = XFA_FMDChar::get(p);
|
| + while (ch) {
|
| + if (!XFA_FMDChar::isAvalid(p)) {
|
| + pEnd = p;
|
| + t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| + Error(FMERR_UNSUPPORTED_CHAR, ch);
|
| + return 1;
|
| + }
|
| + ch = XFA_FMDChar::get(p);
|
| + if (XFA_FMDChar::isUnicodeAlpha(ch)) {
|
| + XFA_FMDChar::inc(p);
|
| + } else {
|
| + pEnd = p;
|
| + t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| + return 0;
|
| + }
|
| + }
|
| + pEnd = p;
|
| + t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
|
| + return 0;
|
| +}
|
| +void CXFA_FMLexer::Comment(const FX_WCHAR* p, const FX_WCHAR*& pEnd) {
|
| + unsigned ch = 0;
|
| + XFA_FMDChar::inc(p);
|
| + ch = XFA_FMDChar::get(p);
|
| + while (ch) {
|
| + if (ch == 0x0D) {
|
| + XFA_FMDChar::inc(p);
|
| + pEnd = p;
|
| + return;
|
| + }
|
| + if (ch == 0x0A) {
|
| + ++m_uCurrentLine;
|
| + XFA_FMDChar::inc(p);
|
| + pEnd = p;
|
| + return;
|
| + }
|
| + XFA_FMDChar::inc(p);
|
| + ch = XFA_FMDChar::get(p);
|
| + }
|
| + pEnd = p;
|
| +}
|
| +XFA_FM_TOKEN CXFA_FMLexer::IsKeyword(const CFX_WideStringC& str) {
|
| + int32_t iLength = str.GetLength();
|
| + uint32_t uHash = FX_HashCode_String_GetW(str.GetPtr(), iLength, TRUE);
|
| + int32_t iStart = KEYWORD_START, iEnd = KEYWORD_END;
|
| + int32_t iMid = (iStart + iEnd) / 2;
|
| + XFA_FMKeyword keyword;
|
| + do {
|
| + iMid = (iStart + iEnd) / 2;
|
| + keyword = keyWords[iMid];
|
| + if (uHash == keyword.m_uHash) {
|
| + return keyword.m_type;
|
| + } else if (uHash < keyword.m_uHash) {
|
| + iEnd = iMid - 1;
|
| + } else {
|
| + iStart = iMid + 1;
|
| + }
|
| + } while (iStart <= iEnd);
|
| + return TOKidentifier;
|
| +}
|
| +CXFA_FMLexer::~CXFA_FMLexer() {
|
| + m_pScript = 0;
|
| + m_ptr = m_pScript;
|
| + if (m_pToken) {
|
| + CXFA_FMToken* t1 = m_pToken;
|
| + CXFA_FMToken* t2 = t1->m_pNext;
|
| + while (t2) {
|
| + delete t1;
|
| + t1 = t2;
|
| + t2 = t2->m_pNext;
|
| + }
|
| + delete m_pToken;
|
| + m_pToken = 0;
|
| + }
|
| + m_pErrorInfo = 0;
|
| +}
|
| +void CXFA_FMLexer::Error(XFA_FM_ERRMSG msg, ...) {
|
| + m_pErrorInfo->linenum = m_uCurrentLine;
|
| + const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);
|
| + va_list ap;
|
| + va_start(ap, msg);
|
| + m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
|
| + va_end(ap);
|
| +}
|
| +FX_BOOL CXFA_FMLexer::HasError() const {
|
| + if (m_pErrorInfo->message.IsEmpty()) {
|
| + return FALSE;
|
| + }
|
| + return TRUE;
|
| +}
|
|
|