init and compare opcode hashmap with uppercase symbols
This is necessary now there are TableRef items like #All that need to be matched case insensitive but displayed preserving the case as coded / translated. As a side effect, OOXML functions with _xlfn. prefix are now matched in case that prefix was uppercase. Change-Id: Ie14700d13c40c3e39e6d6aff560bcdfe23707196
This commit is contained in:
@@ -151,7 +151,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool getOpCodeString( OUString& rStr, sal_uInt16 nOp );
|
bool getOpCodeString( OUString& rStr, sal_uInt16 nOp );
|
||||||
void putDefaultOpCode( FormulaCompiler::NonConstOpCodeMapPtr xMap, sal_uInt16 nOp );
|
void putDefaultOpCode( FormulaCompiler::NonConstOpCodeMapPtr xMap, sal_uInt16 nOp, const CharClass* pCharClass );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FormulaCompiler::SeparatorType meSepType;
|
FormulaCompiler::SeparatorType meSepType;
|
||||||
@@ -162,11 +162,13 @@ OpCodeList::OpCodeList( sal_uInt16 nRID, FormulaCompiler::NonConstOpCodeMapPtr x
|
|||||||
Resource( ResId( nRID, *ResourceManager::getResManager()))
|
Resource( ResId( nRID, *ResourceManager::getResManager()))
|
||||||
, meSepType( eSepType)
|
, meSepType( eSepType)
|
||||||
{
|
{
|
||||||
|
SvtSysLocale aSysLocale;
|
||||||
|
const CharClass* pCharClass = (xMap->isEnglish() ? NULL : aSysLocale.GetCharClassPtr());
|
||||||
if (meSepType == FormulaCompiler::RESOURCE_BASE)
|
if (meSepType == FormulaCompiler::RESOURCE_BASE)
|
||||||
{
|
{
|
||||||
for (sal_uInt16 i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; ++i)
|
for (sal_uInt16 i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; ++i)
|
||||||
{
|
{
|
||||||
putDefaultOpCode( xMap, i);
|
putDefaultOpCode( xMap, i, pCharClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -175,9 +177,9 @@ OpCodeList::OpCodeList( sal_uInt16 nRID, FormulaCompiler::NonConstOpCodeMapPtr x
|
|||||||
{
|
{
|
||||||
OUString aOpStr;
|
OUString aOpStr;
|
||||||
if ( getOpCodeString( aOpStr, i) )
|
if ( getOpCodeString( aOpStr, i) )
|
||||||
xMap->putOpCode( aOpStr, OpCode(i));
|
xMap->putOpCode( aOpStr, OpCode(i), pCharClass);
|
||||||
else
|
else
|
||||||
putDefaultOpCode( xMap, i);
|
putDefaultOpCode( xMap, i, pCharClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,12 +237,13 @@ bool OpCodeList::getOpCodeString( OUString& rStr, sal_uInt16 nOp )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpCodeList::putDefaultOpCode( FormulaCompiler::NonConstOpCodeMapPtr xMap, sal_uInt16 nOp )
|
void OpCodeList::putDefaultOpCode( FormulaCompiler::NonConstOpCodeMapPtr xMap, sal_uInt16 nOp,
|
||||||
|
const CharClass* pCharClass )
|
||||||
{
|
{
|
||||||
ResId aRes( nOp, *ResourceManager::getResManager());
|
ResId aRes( nOp, *ResourceManager::getResManager());
|
||||||
aRes.SetRT( RSC_STRING);
|
aRes.SetRT( RSC_STRING);
|
||||||
if (IsAvailableRes( aRes))
|
if (IsAvailableRes( aRes))
|
||||||
xMap->putOpCode( aRes.toString(), OpCode( nOp));
|
xMap->putOpCode( aRes.toString(), OpCode( nOp), pCharClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@@ -508,7 +511,7 @@ uno::Sequence< sheet::FormulaOpCodeMapEntry > FormulaCompiler::OpCodeMap::create
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FormulaCompiler::OpCodeMap::putOpCode( const OUString & rStr, const OpCode eOp )
|
void FormulaCompiler::OpCodeMap::putOpCode( const OUString & rStr, const OpCode eOp, const CharClass* pCharClass )
|
||||||
{
|
{
|
||||||
DBG_ASSERT( 0 < eOp && sal_uInt16(eOp) < mnSymbols, "OpCodeMap::putOpCode: OpCode out of range");
|
DBG_ASSERT( 0 < eOp && sal_uInt16(eOp) < mnSymbols, "OpCodeMap::putOpCode: OpCode out of range");
|
||||||
if (0 < eOp && sal_uInt16(eOp) < mnSymbols)
|
if (0 < eOp && sal_uInt16(eOp) < mnSymbols)
|
||||||
@@ -519,8 +522,10 @@ void FormulaCompiler::OpCodeMap::putOpCode( const OUString & rStr, const OpCode
|
|||||||
"OpCodeMap::putOpCode: reusing OpCode " << static_cast<sal_uInt16>(eOp)
|
"OpCodeMap::putOpCode: reusing OpCode " << static_cast<sal_uInt16>(eOp)
|
||||||
<< ", replacing '" << mpTable[eOp] << "' with '" << rStr << "' in "
|
<< ", replacing '" << mpTable[eOp] << "' with '" << rStr << "' in "
|
||||||
<< (mbEnglish ? "" : "non-") << "English map 0x" << ::std::hex << meGrammar);
|
<< (mbEnglish ? "" : "non-") << "English map 0x" << ::std::hex << meGrammar);
|
||||||
|
// Case preserving opcode -> string, upper string -> opcode
|
||||||
mpTable[eOp] = rStr;
|
mpTable[eOp] = rStr;
|
||||||
mpHashMap->insert( OpCodeHashMap::value_type( rStr, eOp));
|
OUString aUpper( pCharClass ? pCharClass->uppercase( rStr) : rStr.toAsciiUpperCase());
|
||||||
|
mpHashMap->insert( OpCodeHashMap::value_type( aUpper, eOp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,13 +628,15 @@ FormulaCompiler::OpCodeMapPtr FormulaCompiler::CreateOpCodeMap(
|
|||||||
NonConstOpCodeMapPtr xMap( new OpCodeMap( SC_OPCODE_LAST_OPCODE_ID + 1, false,
|
NonConstOpCodeMapPtr xMap( new OpCodeMap( SC_OPCODE_LAST_OPCODE_ID + 1, false,
|
||||||
FormulaGrammar::mergeToGrammar( FormulaGrammar::setEnglishBit(
|
FormulaGrammar::mergeToGrammar( FormulaGrammar::setEnglishBit(
|
||||||
FormulaGrammar::GRAM_EXTERNAL, bEnglish), FormulaGrammar::CONV_UNSPECIFIED)));
|
FormulaGrammar::GRAM_EXTERNAL, bEnglish), FormulaGrammar::CONV_UNSPECIFIED)));
|
||||||
|
SvtSysLocale aSysLocale;
|
||||||
|
const CharClass* pCharClass = (xMap->isEnglish() ? NULL : aSysLocale.GetCharClassPtr());
|
||||||
FormulaOpCodeMapEntry const * pArr2 = rMapping.getConstArray();
|
FormulaOpCodeMapEntry const * pArr2 = rMapping.getConstArray();
|
||||||
FormulaOpCodeMapEntry const * const pStop = pArr2 + rMapping.getLength();
|
FormulaOpCodeMapEntry const * const pStop = pArr2 + rMapping.getLength();
|
||||||
for ( ; pArr2 < pStop; ++pArr2)
|
for ( ; pArr2 < pStop; ++pArr2)
|
||||||
{
|
{
|
||||||
OpCode eOp = OpCode(pArr2->Token.OpCode);
|
OpCode eOp = OpCode(pArr2->Token.OpCode);
|
||||||
if (eOp != ocExternal)
|
if (eOp != ocExternal)
|
||||||
xMap->putOpCode( pArr2->Name, eOp);
|
xMap->putOpCode( pArr2->Name, eOp, pCharClass);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OUString aExternalName;
|
OUString aExternalName;
|
||||||
@@ -722,9 +729,9 @@ void FormulaCompiler::InitSymbolsEnglishXL() const
|
|||||||
// TODO: For now, just replace the separators to the Excel English
|
// TODO: For now, just replace the separators to the Excel English
|
||||||
// variants. Later, if we want to properly map Excel functions with Calc
|
// variants. Later, if we want to properly map Excel functions with Calc
|
||||||
// functions, we'll need to do a little more work here.
|
// functions, we'll need to do a little more work here.
|
||||||
mxSymbolsEnglishXL->putOpCode( OUString(','), ocSep);
|
mxSymbolsEnglishXL->putOpCode( OUString(','), ocSep, NULL);
|
||||||
mxSymbolsEnglishXL->putOpCode( OUString(','), ocArrayColSep);
|
mxSymbolsEnglishXL->putOpCode( OUString(','), ocArrayColSep, NULL);
|
||||||
mxSymbolsEnglishXL->putOpCode( OUString(';'), ocArrayRowSep);
|
mxSymbolsEnglishXL->putOpCode( OUString(';'), ocArrayRowSep, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormulaCompiler::InitSymbolsOOXML() const
|
void FormulaCompiler::InitSymbolsOOXML() const
|
||||||
@@ -1947,9 +1954,9 @@ void FormulaCompiler::UpdateSeparatorsNative(
|
|||||||
{
|
{
|
||||||
NonConstOpCodeMapPtr xSymbolsNative;
|
NonConstOpCodeMapPtr xSymbolsNative;
|
||||||
lcl_fillNativeSymbols( xSymbolsNative);
|
lcl_fillNativeSymbols( xSymbolsNative);
|
||||||
xSymbolsNative->putOpCode( rSep, ocSep);
|
xSymbolsNative->putOpCode( rSep, ocSep, NULL);
|
||||||
xSymbolsNative->putOpCode( rArrayColSep, ocArrayColSep);
|
xSymbolsNative->putOpCode( rArrayColSep, ocArrayColSep, NULL);
|
||||||
xSymbolsNative->putOpCode( rArrayRowSep, ocArrayRowSep);
|
xSymbolsNative->putOpCode( rArrayRowSep, ocArrayRowSep, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormulaCompiler::ResetNativeSymbols()
|
void FormulaCompiler::ResetNativeSymbols()
|
||||||
|
@@ -46,6 +46,7 @@ namespace com { namespace sun { namespace star {
|
|||||||
}
|
}
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
class CharClass;
|
||||||
|
|
||||||
namespace formula
|
namespace formula
|
||||||
{
|
{
|
||||||
@@ -159,7 +160,7 @@ public:
|
|||||||
inline bool hasExternals() const { return !mpExternalHashMap->empty(); }
|
inline bool hasExternals() const { return !mpExternalHashMap->empty(); }
|
||||||
|
|
||||||
/// Put entry of symbol String and OpCode pair.
|
/// Put entry of symbol String and OpCode pair.
|
||||||
void putOpCode( const OUString & rStr, const OpCode eOp );
|
void putOpCode( const OUString & rStr, const OpCode eOp, const CharClass* pCharClass );
|
||||||
|
|
||||||
/// Put entry of symbol String and AddIn international String pair.
|
/// Put entry of symbol String and AddIn international String pair.
|
||||||
void putExternal( const OUString & rSymbol, const OUString & rAddIn );
|
void putExternal( const OUString & rSymbol, const OUString & rAddIn );
|
||||||
|
@@ -3582,26 +3582,27 @@ bool ScCompiler::NextNewToken( bool bInArray )
|
|||||||
{
|
{
|
||||||
mbRewind = false;
|
mbRewind = false;
|
||||||
const OUString aOrg( cSymbol );
|
const OUString aOrg( cSymbol );
|
||||||
|
aUpper.clear();
|
||||||
|
bool bAsciiUpper = false;
|
||||||
|
|
||||||
if (bAsciiNonAlnum)
|
if (bAsciiNonAlnum)
|
||||||
{
|
{
|
||||||
|
bAsciiUpper = lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
|
||||||
if (cSymbol[0] == '#')
|
if (cSymbol[0] == '#')
|
||||||
{
|
{
|
||||||
// This can be only an error constant, if any.
|
// This can be only an error constant, if any.
|
||||||
lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
|
|
||||||
if (IsErrorConstant( aUpper))
|
if (IsErrorConstant( aUpper))
|
||||||
return true;
|
return true;
|
||||||
break; // do; create ocBad token or set error.
|
break; // do; create ocBad token or set error.
|
||||||
}
|
}
|
||||||
if (IsOpCode( aOrg, bInArray ))
|
if (IsOpCode( aUpper, bInArray ))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
aUpper.clear();
|
|
||||||
bool bAsciiUpper = false;
|
|
||||||
if (bMayBeFuncName)
|
if (bMayBeFuncName)
|
||||||
{
|
{
|
||||||
bAsciiUpper = lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
|
if (aUpper.isEmpty())
|
||||||
|
bAsciiUpper = lcl_UpperAsciiOrI18n( aUpper, aOrg, meGrammar);
|
||||||
if (IsOpCode( aUpper, bInArray ))
|
if (IsOpCode( aUpper, bInArray ))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user