summaryrefslogtreecommitdiff
path: root/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/src/fxfa/src/fm2js/xfa_lexer.cpp')
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_lexer.cpp1144
1 files changed, 572 insertions, 572 deletions
diff --git a/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp b/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
index 3b5f66dd72..8ecc85b4b7 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;
+}