Resolves: #i121120 Support RightB(), LeftB(), LenB() and MidB()
Patch by: Zhang Lu Review by: Wang Lei (cherry picked from commit 424079cb8348d77e40f7d3291578bdffbe662f34) Conflicts: formula/inc/formula/compiler.hrc formula/inc/formula/opcode.hxx oox/source/xls/formulabase.cxx sc/inc/helpids.h sc/util/hidother.src sc/util/makefile.mk Change-Id: Ia04aa69aa2764842507b36ba7cc8c99e99a314e9
This commit is contained in:
committed by
Caolán McNamara
parent
1691607cc4
commit
0946de1e2f
@@ -260,6 +260,10 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
|
||||
String SC_OPCODE_RIGHT { Text = "RIGHT" ; };
|
||||
String SC_OPCODE_SEARCH { Text = "SEARCH" ; };
|
||||
String SC_OPCODE_MID { Text = "MID" ; };
|
||||
String SC_OPCODE_LENB { Text = "LENB" ; };
|
||||
String SC_OPCODE_RIGHTB { Text = "RIGHTB" ; };
|
||||
String SC_OPCODE_LEFTB { Text = "LEFTB" ; };
|
||||
String SC_OPCODE_MIDB { Text = "MIDB" ; };
|
||||
String SC_OPCODE_TEXT { Text = "TEXT" ; };
|
||||
String SC_OPCODE_SUBSTITUTE { Text = "SUBSTITUTE" ; };
|
||||
String SC_OPCODE_REPT { Text = "REPT" ; };
|
||||
@@ -601,6 +605,10 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
|
||||
String SC_OPCODE_RIGHT { Text = "RIGHT" ; };
|
||||
String SC_OPCODE_SEARCH { Text = "SEARCH" ; };
|
||||
String SC_OPCODE_MID { Text = "MID" ; };
|
||||
String SC_OPCODE_LENB { Text = "LENB" ; };
|
||||
String SC_OPCODE_RIGHTB { Text = "RIGHTB" ; };
|
||||
String SC_OPCODE_LEFTB { Text = "LEFTB" ; };
|
||||
String SC_OPCODE_MIDB { Text = "MIDB" ; };
|
||||
String SC_OPCODE_TEXT { Text = "TEXT" ; };
|
||||
String SC_OPCODE_SUBSTITUTE { Text = "SUBSTITUTE" ; };
|
||||
String SC_OPCODE_REPT { Text = "REPT" ; };
|
||||
@@ -1578,6 +1586,22 @@ Resource RID_STRLIST_FUNCTION_NAMES
|
||||
{
|
||||
Text [ en-US ] = "MID" ;
|
||||
};
|
||||
String SC_OPCODE_LENB
|
||||
{
|
||||
Text [ en-US ] = "LENB" ;
|
||||
};
|
||||
String SC_OPCODE_RIGHTB
|
||||
{
|
||||
Text [ en-US ] = "RIGHTB" ;
|
||||
};
|
||||
String SC_OPCODE_LEFTB
|
||||
{
|
||||
Text [ en-US ] = "LEFTB" ;
|
||||
};
|
||||
String SC_OPCODE_MIDB
|
||||
{
|
||||
Text [ en-US ] = "MIDB" ;
|
||||
};
|
||||
String SC_OPCODE_TEXT
|
||||
{
|
||||
Text [ en-US ] = "TEXT" ;
|
||||
|
||||
@@ -403,9 +403,13 @@
|
||||
#define SC_OPCODE_COUNT_IFS 405
|
||||
#define SC_OPCODE_SKEWP 406
|
||||
#define SC_OPCODE_STOP_2_PAR 407
|
||||
#define SC_OPCODE_LAST_OPCODE_ID 406 /* last OpCode */
|
||||
#define SC_OPCODE_LENB 408
|
||||
#define SC_OPCODE_RIGHTB 409
|
||||
#define SC_OPCODE_LEFTB 410
|
||||
#define SC_OPCODE_MIDB 412
|
||||
#define SC_OPCODE_LAST_OPCODE_ID 413 /* last OpCode */
|
||||
|
||||
#define SC_OPCODE_STOP_FUNCTION 407
|
||||
#define SC_OPCODE_STOP_FUNCTION 412
|
||||
|
||||
/*** Internal ***/
|
||||
#define SC_OPCODE_INTERNAL_BEGIN 9999
|
||||
|
||||
@@ -301,6 +301,10 @@ enum OpCodeEnum
|
||||
ocSubstitute = SC_OPCODE_SUBSTITUTE,
|
||||
ocRept = SC_OPCODE_REPT,
|
||||
ocConcat = SC_OPCODE_CONCAT,
|
||||
ocLenB = SC_OPCODE_LENB,
|
||||
ocRightB = SC_OPCODE_RIGHTB,
|
||||
ocLeftB = SC_OPCODE_LEFTB,
|
||||
ocMidB = SC_OPCODE_MIDB,
|
||||
ocNumberValue = SC_OPCODE_NUMBERVALUE,
|
||||
// Matrix functions
|
||||
ocMatValue = SC_OPCODE_MAT_VALUE,
|
||||
|
||||
@@ -26,6 +26,10 @@ $(eval $(call gb_CppunitTest_use_externals,sc_ucalc,\
|
||||
mdds_headers \
|
||||
orcus \
|
||||
orcus-parser \
|
||||
icu_headers \
|
||||
icudata \
|
||||
icui18n \
|
||||
icuuc \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_libraries,sc_ucalc, \
|
||||
|
||||
@@ -38,6 +38,10 @@ $(eval $(call gb_Library_use_sdk_api,sc))
|
||||
$(eval $(call gb_Library_use_externals,sc,\
|
||||
boost_headers \
|
||||
mdds_headers \
|
||||
icu_headers \
|
||||
icudata \
|
||||
icui18n \
|
||||
icuuc \
|
||||
))
|
||||
|
||||
ifeq ($(ENABLE_TELEPATHY),TRUE)
|
||||
|
||||
@@ -665,6 +665,10 @@
|
||||
#define HID_FUNC_LINKS "SC_HID_FUNC_LINKS"
|
||||
#define HID_FUNC_RECHTS "SC_HID_FUNC_RECHTS"
|
||||
#define HID_FUNC_TEIL "SC_HID_FUNC_TEIL"
|
||||
#define HID_FUNC_LENB "SC_HID_FUNC_LENB"
|
||||
#define HID_FUNC_RIGHTB "SC_HID_FUNC_RIGHTB"
|
||||
#define HID_FUNC_LEFTB "SC_HID_FUNC_LEFTB"
|
||||
#define HID_FUNC_MIDB "SC_HID_FUNC_MIDB"
|
||||
#define HID_FUNC_WIEDERHOLEN "SC_HID_FUNC_WIEDERHOLEN"
|
||||
#define HID_FUNC_WECHSELN "SC_HID_FUNC_WECHSELN"
|
||||
#define HID_FUNC_BASIS "SC_HID_FUNC_BASIS"
|
||||
|
||||
@@ -5369,14 +5369,18 @@ void Test::testFunctionLists()
|
||||
"FIXED",
|
||||
"JIS",
|
||||
"LEFT",
|
||||
"LEFTB",
|
||||
"LEN",
|
||||
"LENB",
|
||||
"LOWER",
|
||||
"MID",
|
||||
"MIDB",
|
||||
"NUMBERVALUE",
|
||||
"PROPER",
|
||||
"REPLACE",
|
||||
"REPT",
|
||||
"RIGHT",
|
||||
"RIGHTB",
|
||||
"ROMAN",
|
||||
"SEARCH",
|
||||
"SUBSTITUTE",
|
||||
|
||||
@@ -788,6 +788,10 @@ void ScSTEXY();
|
||||
void ScSlope();
|
||||
void ScTrend();
|
||||
void ScInfo();
|
||||
void ScLenB();
|
||||
void ScRightB();
|
||||
void ScLeftB();
|
||||
void ScMidB();
|
||||
|
||||
static const double fMaxGammaArgument;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <unotools/transliterationwrapper.hxx>
|
||||
#include <rtl/ustring.hxx>
|
||||
#include <rtl/logfile.hxx>
|
||||
#include <unicode/uchar.h>
|
||||
|
||||
#include "patattr.hxx"
|
||||
#include "global.hxx"
|
||||
@@ -8620,6 +8621,182 @@ void ScInterpreter::ScLeft()
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
UBlockCode from;
|
||||
UBlockCode to;
|
||||
} UBlockScript;
|
||||
|
||||
static UBlockScript scriptList[] = {
|
||||
{UBLOCK_HANGUL_JAMO, UBLOCK_HANGUL_JAMO},
|
||||
{UBLOCK_CJK_RADICALS_SUPPLEMENT, UBLOCK_HANGUL_SYLLABLES},
|
||||
{UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS,UBLOCK_CJK_RADICALS_SUPPLEMENT },
|
||||
{UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS,UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS},
|
||||
{UBLOCK_CJK_COMPATIBILITY_FORMS, UBLOCK_CJK_COMPATIBILITY_FORMS},
|
||||
{UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS, UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS},
|
||||
{UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT},
|
||||
{UBLOCK_CJK_STROKES, UBLOCK_CJK_STROKES}
|
||||
};
|
||||
#define scriptListCount sizeof (scriptList) / sizeof (UBlockScript)
|
||||
bool SAL_CALL lcl_getScriptClass(sal_uInt32 currentChar)
|
||||
{
|
||||
// for the locale of ja-JP, character U+0x005c and U+0x20ac should be ScriptType::Asian
|
||||
if( (currentChar == 0x005c || currentChar == 0x20ac) &&
|
||||
(MsLangId::getSystemLanguage() == LANGUAGE_JAPANESE) )
|
||||
return true;
|
||||
sal_uInt16 i;
|
||||
static sal_Int16 nRet = 0;
|
||||
UBlockCode block = (UBlockCode)ublock_getCode((sal_uInt32)currentChar);
|
||||
for ( i = 0; i < scriptListCount; i++) {
|
||||
if (block <= scriptList[i].to) break;
|
||||
}
|
||||
nRet = (i < scriptListCount && block >= scriptList[i].from);
|
||||
return nRet;
|
||||
}
|
||||
bool IsDBCS(sal_Unicode ch)
|
||||
{
|
||||
return lcl_getScriptClass(ch);
|
||||
}
|
||||
sal_Int32 getLengthB(String &str)
|
||||
{
|
||||
sal_Int32 index = 0;
|
||||
sal_Int32 length = 0;
|
||||
if(0 == str.Len())
|
||||
return 0;
|
||||
while(index < str.Len()){
|
||||
if(IsDBCS(str.GetChar(index)))
|
||||
length += 2;
|
||||
else
|
||||
length++;
|
||||
index++;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
void ScInterpreter::ScLenB()
|
||||
{
|
||||
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "luzhang", "ScInterpreter::ScLenB" );
|
||||
String aStr( GetString() );
|
||||
PushDouble( getLengthB(aStr) );
|
||||
}
|
||||
void lcl_RightB(String &aStr, sal_Int32 n)
|
||||
{
|
||||
if( n < getLengthB(aStr) )
|
||||
{
|
||||
sal_Int32 index = aStr.Len();
|
||||
while(index-- >= 0)
|
||||
{
|
||||
if(0 == n)
|
||||
{
|
||||
aStr.Erase( 0, index + 1);
|
||||
break;
|
||||
}
|
||||
if(-1 == n)
|
||||
{
|
||||
aStr.Erase( 0, index + 2 );
|
||||
aStr.InsertAscii(" ", 0);
|
||||
break;
|
||||
}
|
||||
if(IsDBCS(aStr.GetChar(index)))
|
||||
n -= 2;
|
||||
else
|
||||
n--;
|
||||
}
|
||||
}
|
||||
}
|
||||
void ScInterpreter::ScRightB()
|
||||
{
|
||||
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "luzhang", "ScInterpreter::ScRightB" );
|
||||
sal_uInt8 nParamCount = GetByte();
|
||||
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
|
||||
{
|
||||
sal_Int32 n;
|
||||
if (nParamCount == 2)
|
||||
{
|
||||
double nVal = ::rtl::math::approxFloor(GetDouble());
|
||||
if ( nVal < 0.0 || nVal > STRING_MAXLEN )
|
||||
{
|
||||
PushIllegalArgument();
|
||||
return ;
|
||||
}
|
||||
else
|
||||
n = (xub_StrLen) nVal;
|
||||
}
|
||||
else
|
||||
n = 1;
|
||||
String aStr( GetString() );
|
||||
lcl_RightB(aStr, n);
|
||||
PushString( aStr );
|
||||
}
|
||||
}
|
||||
void lcl_LeftB(String &aStr, sal_Int32 n)
|
||||
{
|
||||
if( n < getLengthB(aStr) )
|
||||
{
|
||||
sal_Int32 index = -1;
|
||||
while(index++ < aStr.Len())
|
||||
{
|
||||
if(0 == n)
|
||||
{
|
||||
aStr.Erase( index );
|
||||
break;
|
||||
}
|
||||
if(-1 == n)
|
||||
{
|
||||
aStr.Erase( index - 1 );
|
||||
aStr.InsertAscii(" ");
|
||||
break;
|
||||
}
|
||||
if(IsDBCS(aStr.GetChar(index)))
|
||||
n -= 2;
|
||||
else
|
||||
n--;
|
||||
}
|
||||
}
|
||||
}
|
||||
void ScInterpreter::ScLeftB()
|
||||
{
|
||||
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "luzhang", "ScInterpreter::ScLeftB" );
|
||||
sal_uInt8 nParamCount = GetByte();
|
||||
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
|
||||
{
|
||||
sal_Int32 n;
|
||||
if (nParamCount == 2)
|
||||
{
|
||||
double nVal = ::rtl::math::approxFloor(GetDouble());
|
||||
if ( nVal < 0.0 || nVal > STRING_MAXLEN )
|
||||
{
|
||||
PushIllegalArgument();
|
||||
return ;
|
||||
}
|
||||
else
|
||||
n = (xub_StrLen) nVal;
|
||||
}
|
||||
else
|
||||
n = 1;
|
||||
String aStr( GetString() );
|
||||
lcl_LeftB(aStr, n);
|
||||
PushString( aStr );
|
||||
}
|
||||
}
|
||||
void ScInterpreter::ScMidB()
|
||||
{
|
||||
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "luzhang", "ScInterpreter::ScMidB" );
|
||||
if ( MustHaveParamCount( GetByte(), 3 ) )
|
||||
{
|
||||
double fAnz = ::rtl::math::approxFloor(GetDouble());
|
||||
double fAnfang = ::rtl::math::approxFloor(GetDouble());
|
||||
String rStr( GetString() );
|
||||
if (fAnfang < 1.0 || fAnz < 0.0 || fAnfang > double(STRING_MAXLEN) || fAnz > double(STRING_MAXLEN))
|
||||
PushIllegalArgument();
|
||||
else
|
||||
{
|
||||
|
||||
lcl_LeftB(rStr, (xub_StrLen)fAnfang + (xub_StrLen)fAnz - 1);
|
||||
sal_Int32 nCnt = getLengthB(rStr) - (xub_StrLen)fAnfang + 1;
|
||||
lcl_RightB(rStr, nCnt>0 ? nCnt:0);
|
||||
PushString(rStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScInterpreter::ScRight()
|
||||
{
|
||||
|
||||
@@ -4174,6 +4174,10 @@ StackVar ScInterpreter::Interpret()
|
||||
case ocGetPivotData : ScGetPivotData(); break;
|
||||
case ocJis : ScJis(); break;
|
||||
case ocAsc : ScAsc(); break;
|
||||
case ocLenB : ScLenB(); break;
|
||||
case ocRightB : ScRightB(); break;
|
||||
case ocLeftB : ScLeftB(); break;
|
||||
case ocMidB : ScMidB(); break;
|
||||
case ocUnicode : ScUnicode(); break;
|
||||
case ocUnichar : ScUnichar(); break;
|
||||
case ocBitAnd : ScBitAnd(); break;
|
||||
|
||||
@@ -203,6 +203,10 @@ static const XclFunctionInfo saFuncTable_2[] =
|
||||
{ ocIsLogical, 198, 1, 1, V, { VR }, 0, 0 },
|
||||
{ ocDBCount2, 199, 3, 3, V, { RO, RR }, 0, 0 },
|
||||
{ ocCurrency, 204, 1, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 },
|
||||
{ ocLeftB, 208, 1, 2, V, { VR }, 0, 0 },
|
||||
{ ocRightB, 209, 1, 2, V, { VR }, 0, 0 },
|
||||
{ ocMidB, 210, 3, 3, V, { VR }, 0, 0 },
|
||||
{ ocLenB, 211, 1, 1, V, { VR }, 0, 0 },
|
||||
{ ocRoundUp, 212, 2, 2, V, { VR }, 0, 0 },
|
||||
{ ocRoundDown, 213, 2, 2, V, { VR }, 0, 0 },
|
||||
{ ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }
|
||||
|
||||
@@ -439,10 +439,10 @@ static const FunctionData saFuncTableBiff3[] =
|
||||
{ 0/*"FIND"*/, "FINDB", 205, 205, 2, 3, V, { VR }, 0 },
|
||||
{ 0/*"SEARCH"*/, "SEARCHB", 206, 206, 2, 3, V, { VR }, 0 },
|
||||
{ 0/*"REPLACE"*/, "REPLACEB", 207, 207, 4, 4, V, { VR }, 0 },
|
||||
{ 0/*"LEFT"*/, "LEFTB", 208, 208, 1, 2, V, { VR }, 0 },
|
||||
{ 0/*"RIGHT"*/, "RIGHTB", 209, 209, 1, 2, V, { VR }, 0 },
|
||||
{ 0/*"MID"*/, "MIDB", 210, 210, 3, 3, V, { VR }, 0 },
|
||||
{ 0/*"LEN"*/, "LENB", 211, 211, 1, 1, V, { VR }, 0 },
|
||||
{ "LEFTB", "LEFTB", 208, 208, 1, 2, V, { VR }, 0 },
|
||||
{ "RIGHTB", "RIGHTB", 209, 209, 1, 2, V, { VR }, 0 },
|
||||
{ "MIDB", "MIDB", 210, 210, 3, 3, V, { VR }, 0 },
|
||||
{ "LENB", "LENB", 211, 211, 1, 1, V, { VR }, 0 },
|
||||
{ "ROUNDUP", "ROUNDUP", 212, 212, 2, 2, V, { VR }, 0 },
|
||||
{ "ROUNDDOWN", "ROUNDDOWN", 213, 213, 2, 2, V, { VR }, 0 },
|
||||
{ "ASC", "ASC", 214, 214, 1, 1, V, { VR }, 0 },
|
||||
|
||||
@@ -9608,6 +9608,130 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
|
||||
Text [ en-US ] = "The integer number of bits the value is to be shifted." ;
|
||||
};
|
||||
};
|
||||
Resource SC_OPCODE_LENB
|
||||
{
|
||||
String 1 // Description
|
||||
{
|
||||
Text [ en-US ] = "Calculates length of a text string, with DBCS" ;
|
||||
};
|
||||
ExtraData =
|
||||
{
|
||||
0;
|
||||
ID_FUNCTION_GRP_TEXT;
|
||||
U2S( HID_FUNC_LENB );
|
||||
1; 0;
|
||||
0;
|
||||
};
|
||||
String 2 // Name of Parameter 1
|
||||
{
|
||||
Text [ en-US ] = "text" ;
|
||||
};
|
||||
String 3 // Description of Parameter 1
|
||||
{
|
||||
Text [ en-US ] = "The text in which the length is to be determined." ;
|
||||
};
|
||||
};
|
||||
Resource SC_OPCODE_RIGHTB
|
||||
{
|
||||
String 1 // Description
|
||||
{
|
||||
Text [ en-US ] = "Returns the last character or characters of a text,with DBCS" ;
|
||||
};
|
||||
ExtraData =
|
||||
{
|
||||
0;
|
||||
ID_FUNCTION_GRP_TEXT;
|
||||
U2S( HID_FUNC_RIGHTB );
|
||||
2; 0; 1;
|
||||
0;
|
||||
};
|
||||
String 2 // Name of Parameter 1
|
||||
{
|
||||
Text [ en-US ] = "text" ;
|
||||
};
|
||||
String 3 // Description of Parameter 1
|
||||
{
|
||||
Text [ en-US ] = "The text in which the end partial words are to be determined." ;
|
||||
};
|
||||
String 4 // Name of Parameter 2
|
||||
{
|
||||
Text [ en-US ] = "number" ;
|
||||
};
|
||||
String 5 // Description of Parameter 2
|
||||
{
|
||||
Text [ en-US ] = "The number of characters for the end text." ;
|
||||
};
|
||||
};
|
||||
Resource SC_OPCODE_LEFTB
|
||||
{
|
||||
String 1 // Description
|
||||
{
|
||||
Text [ en-US ] = "Returns the first character or characters of a text,with DBCS" ;
|
||||
};
|
||||
ExtraData =
|
||||
{
|
||||
0;
|
||||
ID_FUNCTION_GRP_TEXT;
|
||||
U2S( HID_FUNC_LEFTB );
|
||||
2; 0; 1;
|
||||
0;
|
||||
};
|
||||
String 2 // Name of Parameter 1
|
||||
{
|
||||
Text [ en-US ] = "text" ;
|
||||
};
|
||||
String 3 // Description of Parameter 1
|
||||
{
|
||||
Text [ en-US ] = "The text where the initial partial words are to be determined." ;
|
||||
};
|
||||
String 4 // Name of Parameter 2
|
||||
{
|
||||
Text [ en-US ] = "number" ;
|
||||
};
|
||||
String 5 // Description of Parameter 2
|
||||
{
|
||||
Text [ en-US ] = "The number of characters for the start text." ;
|
||||
};
|
||||
};
|
||||
Resource SC_OPCODE_MIDB
|
||||
{
|
||||
String 1 // Description
|
||||
{
|
||||
Text [ en-US ] = "Returns a partial text string of a text, with DBCS" ;
|
||||
};
|
||||
ExtraData =
|
||||
{
|
||||
0;
|
||||
ID_FUNCTION_GRP_TEXT;
|
||||
U2S( HID_FUNC_MIDB );
|
||||
3; 0; 0; 0;
|
||||
0;
|
||||
};
|
||||
String 2 // Name of Parameter 1
|
||||
{
|
||||
Text [ en-US ] = "text" ;
|
||||
};
|
||||
String 3 // Description of Parameter 1
|
||||
{
|
||||
Text [ en-US ] = "The text in which partial words are to be determined." ;
|
||||
};
|
||||
String 4 // Name of Parameter 2
|
||||
{
|
||||
Text [ en-US ] = "start" ;
|
||||
};
|
||||
String 5 // Description of Parameter 2
|
||||
{
|
||||
Text [ en-US ] = "The position from which the part word is to be determined." ;
|
||||
};
|
||||
String 6 // Name of Parameter 3
|
||||
{
|
||||
Text [ en-US ] = "number" ;
|
||||
};
|
||||
String 7 // Description of Parameter 3
|
||||
{
|
||||
Text [ en-US ] = "The number of characters for the text." ;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#if defined(U2S)
|
||||
|
||||
Reference in New Issue
Block a user