📄 si_libs.c
字号:
OpS_Push( si->RE->OpS, &op2 );
CallLibraryFunction( si, 1, 0 ); /* Float.int */
op2 = RE_Pop( si->RE );
OpS_Push( si->RE->OpS, &op3 );
CallLibraryFunction( si, 1, 0 ); /* Float.int */
op3 = RE_Pop( si->RE );
}
if ( (op2->type == typeInteger) && (op3->type == typeInteger) &&
Var_ConvertMethod( CONVERT_STRINGS, op1, NULL ))
{
startIndex = MAX( 0, op2->val.theInt );
stopIndex = MIN( MAX(op3->val.theInt, op3->val.theInt + startIndex), (INT32)op1->theStringLen );
/* 000215,KHN: The "MAX(op3->val.theInt, op3->val.theInt + startIndex)" above
is an simplified overflow check. */
if (startIndex < stopIndex)
{
subStrLen = stopIndex - startIndex;
Var_AssignString( result, (UINT32)subStrLen, &(op1->val.theString[startIndex]) );
}
/* else the result is an empty string (as it is already) */
}
else Var_AssignInvalid( result );
}
else Var_AssignInvalid( result );
Var_Delete( &op3 );
Var_Delete( &op2 );
Var_Delete( &op1 );
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_String_find( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar op2 = RE_Pop( si->RE ); /* substring */
pstructVar op1 = RE_Pop( si->RE ); /* src string */
pstructVar result = Var_New();
pstructStrFind subPos = NULL;
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if ( (VCR_OK == Var_Convert( op1, typeString )) && (VCR_OK == Var_Convert( op2, typeString )))
{
if (op2->theStringLen == 0)
{
Var_AssignInvalid( result );
}
else if (op1->theStringLen == 0)
{
Var_AssignInt( result, -1 );
}
else
{
subPos = FindSubstrings( op1, op2, FALSE );
if (subPos != NULL)
{
Var_AssignInt( result, subPos->subStrPos );
}
else
{
Var_AssignInvalid( result );
}
}
}
else Var_AssignInvalid( result );
StrFind_Delete( &subPos );
Var_Delete( &op2 );
Var_Delete( &op1 );
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_String_replace( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar newSub = RE_Pop( si->RE ); /* newsubstring */
pstructVar oldSub = RE_Pop( si->RE ); /* old substring */
pstructVar src = RE_Pop( si->RE ); /* src string */
pstructVar result = Var_New();
pstructStrFind subPos = NULL;
pstructStrFind el = NULL;
INT32 nbrOfReplaces = 0;
UINT32 newStrSize;
UINT32 srcIndex = 0;
UINT32 dstIndex = 0;
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if ( (VCR_OK == Var_Convert( src, typeString )) && (VCR_OK == Var_Convert( oldSub, typeString )) && (VCR_OK == Var_Convert( newSub, typeString )))
{
subPos = FindSubstrings( src, oldSub, TRUE );
if ((subPos != NULL) && (oldSub->theStringLen != 0))
{
if (subPos->subStrPos == -1)
{
/* no matches! */
StrFind_Delete( &subPos );
}
else
{
/* now find out how big the new string must be */
/* ...find out how many substring replaces are to be made */
el = subPos;
while (el != NULL)
{
nbrOfReplaces++;
el = el->next;
}
}
newStrSize = src->theStringLen + ((newSub->theStringLen - oldSub->theStringLen)*nbrOfReplaces);
/* create and fill out the new string */
Var_NewString( result, newStrSize );
el = subPos;
while (srcIndex < src->theStringLen)
{
if (el != NULL)
{
/* copy the src string until a substring occurs */
if ((INT32)srcIndex < el->subStrPos)
{
COPYSTRINGN( &(result->val.theString[dstIndex]), &(src->val.theString[srcIndex]),
el->subStrPos - srcIndex );
dstIndex += el->subStrPos - srcIndex;
srcIndex = el->subStrPos;
}
/* put the replacement sub string in the new string */
COPYSTRINGN( &(result->val.theString[dstIndex]), newSub->val.theString,
newSub->theStringLen );
srcIndex += oldSub->theStringLen;
dstIndex += newSub->theStringLen;
el = el->next;
}
else
{ /* no more replacements => copy the rest of the src string to the new string */
COPYSTRINGN( &(result->val.theString[dstIndex]), &(src->val.theString[srcIndex]),
src->theStringLen - srcIndex );
dstIndex += src->theStringLen - srcIndex;
srcIndex = src->theStringLen;
}
}
}
else
{
Var_AssignInvalid( result );
}
}
else
{
Var_AssignInvalid( result );
}
StrFind_Delete( &subPos );
Var_Delete( &src );
Var_Delete( &oldSub );
Var_Delete( &newSub );
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_String_elements( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
/*
990308: (KHN) Implemented the Corrigendum (WMLS lib 12)
*/
{
pstructVar separatorStr = RE_Pop( si->RE );
pstructVar str = RE_Pop( si->RE );
pstructVar result = Var_New();
pstructVar separatorChar = Var_New();
pstructStrFind listOfMatches = NULL;
pstructStrFind el = NULL;
INT32 nbrOfElements = 0;
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if ((VCR_OK == Var_Convert( str, typeString )) && (VCR_OK == Var_Convert( separatorStr, typeString ))) {
if (separatorStr->theStringLen > 0) {
Var_NewString( separatorChar, 1 );
separatorChar->val.theString[0] = separatorStr->val.theString[0];
listOfMatches = FindSubstrings( str, separatorChar, TRUE );
if (listOfMatches->subStrPos != -1) {
/* now count how many matches were found */
el = listOfMatches;
while (el != NULL) {
nbrOfElements++;
el = el->next;
}
/* when wanting elements the result is the amount of separator matches + 1 */
nbrOfElements += 1;
}
else {
/* no separator => one element (even if it is an empty string) */
nbrOfElements = 1;
}
Var_AssignInt( result, nbrOfElements );
}
else {
Var_AssignInvalid( result );
}
}
else {
Var_AssignInvalid( result );
}
StrFind_Delete( &listOfMatches );
Var_Delete( &separatorStr );
Var_Delete( &str );
Var_Delete( &separatorChar );
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_String_elementAt( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar separatorStr = RE_Pop( si->RE );
pstructVar elIndex = RE_Pop( si->RE );
pstructVar str = RE_Pop( si->RE );
pstructVar result = Var_New();
pstructVar separatorChar = Var_New();
pstructStrFind listOfMatches = NULL;
pstructStrFind el = NULL;
INT32 nbrOfElements = 0;
UINT32 theIndex;
UINT32 i;
UINT32 startStrPos = 0;
UINT32 endStrPos = 0;
UINT32 newStrLen;
pstructStrFind startEl = NULL; /* the el that has the pos for the start of the element */
pstructStrFind endEl = NULL; /* the el that has the pos for the end of the element */
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if ( (VCR_OK == Var_Convert( str, typeString )) && (VCR_OK == Var_Convert( separatorStr, typeString )) &&
Var_ConvertMethod(CONVERT_INT_FLOAT, elIndex, NULL))
{
if (elIndex->type == typeFloat)
{
OpS_Push( si->RE->OpS, &elIndex );
CallLibraryFunction( si, 1, 0 ); /* Float.int */
elIndex = RE_Pop( si->RE );
}
if ((elIndex->type == typeInteger) && (separatorStr->theStringLen > 0))
{
Var_NewString( separatorChar, 1 );
separatorChar->val.theString[0] = separatorStr->val.theString[0];
listOfMatches = FindSubstrings( str, separatorChar, TRUE );
if (listOfMatches->subStrPos != -1)
{
/* now count how many matches were found */
el = listOfMatches;
while (el != NULL)
{
nbrOfElements++;
el = el->next;
}
/* when wanting elements the result is the amount of separator matches + 1 */
nbrOfElements += 1;
}
else
{
nbrOfElements = (str->theStringLen == 0) ? (0) : (1);
}
/* ensure that the index is within the boundaries */
theIndex = MAX( 0, elIndex->val.theInt );
theIndex = MIN( theIndex, (UINT32)(nbrOfElements-1) );
if (nbrOfElements > 0)
{
if (nbrOfElements != 1)
{
endEl = listOfMatches;
i = 0;
while (i < theIndex)
{
/* step forward in the list of matches so the element's boundaries are
found by getting the separator positions around the element */
startEl = endEl;
endEl = endEl->next;
i++;
}
startStrPos = (startEl==NULL) ? ( 0 ):( (startEl->subStrPos)+1 );
endStrPos = (endEl==NULL) ? ( str->theStringLen ):( endEl->subStrPos );
if (startStrPos <= endStrPos)
{
/* create the result string */
newStrLen = endStrPos - startStrPos;
Var_NewString( result, newStrLen );
COPYSTRINGN( result->val.theString, &(str->val.theString[startStrPos]), newStrLen );
}
/* else an empty string */
}
else
{
/* the entire string is the answer */
Var_Delete( &result );
result = str;
str = NULL;
}
}
/* else the string doesn't contain any elements and the result is an empty string */
}
else
{
Var_AssignInvalid( result );
}
}
else
{
Var_AssignInvalid( result );
}
StrFind_Delete( &listOfMatches );
Var_Delete( &separatorStr );
Var_Delete( &elIndex );
Var_Delete( &str );
Var_Delete( &separatorChar );
OpS_Push( si->RE->OpS, &result );
return ERR_WAE_WMLS_NONE;
}
enumErrorCode Call_String_removeAt( pstructSI si, UINT16 libIndex, UINT8 funcIndex )
{
pstructVar separatorStr = RE_Pop( si->RE );
pstructVar elIndex = RE_Pop( si->RE );
pstructVar str = RE_Pop( si->RE );
pstructVar result = Var_New();
pstructVar separatorChar = Var_New();
pstructStrFind listOfMatches = NULL;
pstructStrFind el = NULL;
INT32 nbrOfElements = 0;
UINT32 theIndex;
UINT32 i;
UINT32 startStrPos = 0;
UINT32 endStrPos = 0;
UINT32 newStrLen;
pstructStrFind startEl = NULL; /* the el that has the pos for the start of the element */
pstructStrFind endEl = NULL; /* the el that has the pos for the end of the element */
libIndex=libIndex; /* just to get rid of a compiler warning */
funcIndex=funcIndex; /* just to get rid of a compiler warning */
if ( (VCR_OK == Var_Convert( str, typeString )) && (VCR_OK == Var_Convert( separatorStr, typeString )) &&
Var_ConvertMethod(CONVERT_INT_FLOAT, elIndex, NULL)) {
if (elIndex->type == typeFloat) {
OpS_Push( si->RE->OpS, &elIndex );
CallLibraryFunction( si, 1, 0 ); /* Float.int */
elIndex = RE_Pop( si->RE );
}
if ((elIndex->type == typeInteger) && (separatorStr->theStringLen > 0))
{
Var_NewString( separatorChar, 1 );
separatorChar->val.theString[0] = separatorStr->val.theString[0];
listOfMatches = FindSubstrings( str, separatorChar, TRUE );
if (listOfMatches->subStrPos != -1) {
/* now count how many matches were found */
el = listOfMatches;
while (el != NULL) {
nbrOfElements++;
el = el->next;
}
/* when wanting elements the result is the amount of separator matches + 1 */
nbrOfElements += 1;
}
else {
nbrOfElements = (str->theStringLen == 0) ? (0) : (1);
}
/* ensure that the index is within the boundaries */
theIndex = MAX( 0, elIndex->val.theInt );
theIndex = MIN( theIndex, (UINT32)(nbrOfElements-1) );
if (nbrOfElements > 0) {
if (nbrOfElements != 1) {
endEl = listOfMatches;
i = 0;
while (i < theIndex) {
/* step forward in the list of matches so the element's boundaries are
found by getting the separator positions around the element */
startEl = endEl;
endEl = endEl->next;
i++;
}
startStrPos = (startEl==NULL) ? ( 0 ):( (startEl->subStrPos)+1 );
endStrPos = (endEl==NULL) ? ( str->theStringLen-1 ):( endEl->subStrPos );
if (endStrPos == str->theStringLen-1) {
/* if the last element is removed the separator is also to be removed */
startStrPos--;
}
if (startStrPos < endStrPos) {
/* create the result string */
newStrLen = str->theStringLen - (endStrPos - startStrPos + 1);
Var_NewString( result, newStrLen );
/* copy the string part before the element */
if (startStrPos > 0) {
COPYSTRINGN( result->val.theString, str->val.theString, startStrPos );
}
/* copy the string part after the element */
if ((endStrPos+1) < str->theStringLen) {
COPYSTRINGN( &(result->val.theString[startStrPos]),
&(str->val.theString[endStrPos+1]), (str->theStringLen - (endStrPos+1)) );
}
}
else {
/* an empty string is to be removed and thus the entire string is the result */
Var_Delete( &result );
result = str;
str = NULL;
}
}
/* else => the entire string is the element to remove so an empty string is the result */
}
/* else the string doesn't contain any elements and the result is an empty string */
}
else {
Var_AssignInvalid( result );
}
}
else {
Var_AssignInvalid( result );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -