/* stringcompare two string values. The values SHOULD be string. */ static int STRCMP(pExecuteObject pEo,VARIABLE Op1, VARIABLE Op2, int iCase){ unsigned long n; char *a,*b; char ca,cb; if( memory_IsUndef(Op1) && memory_IsUndef(Op2) )return 0; if( memory_IsUndef(Op1) )return 1; if( memory_IsUndef(Op2) )return -1; iCase &= 1;/* only the lowest bit is about case sensitivity */ n = STRLEN(Op1); if( n > STRLEN(Op2) ) n= STRLEN(Op2); a = STRINGVALUE(Op1); b = STRINGVALUE(Op2); while( n-- ){ ca = *a; cb = *b; if( iCase ){ if( isupper(ca) )ca = tolower(ca); if( isupper(cb) )cb = tolower(cb); } if( ca != cb )return ( (ca)-(cb) ); a++; b++; } if( STRLEN(Op1) == STRLEN(Op2) )return 0; if( STRLEN(Op1) > STRLEN(Op2) )return 1; return -1; }
/*FUNCTION*/ pFixSizeMemoryObject memory_CopyArray(pMemoryObject pMo, pFixSizeMemoryObject p ){ /*noverbatim CUT*/ long aLow,aHigh; pFixSizeMemoryObject result; long i; if( p == NULL )return NULL; if( p->vType != VTYPE_ARRAY )return NULL; aLow = p->ArrayLowLimit; aHigh = p->ArrayHighLimit; result = memory_NewArray(pMo,aLow,aHigh); if( result == NULL )return NULL; for( i=0 ; i <= aHigh-aLow ; i++ ){ if( memory_IsUndef(p->Value.aValue[i]) )continue; switch(p->Value.aValue[i]->vType ){ case VTYPE_ARRAY : result->Value.aValue[i] = memory_CopyArray(pMo,p->Value.aValue[i]); if( result->Value.aValue[i] == NULL )return NULL; continue; case VTYPE_LONG: result->Value.aValue[i] = memory_NewLong(pMo); if( result->Value.aValue[i] == NULL )return NULL; result->Value.aValue[i]->Value.lValue = p->Value.aValue[i]->Value.lValue; continue; case VTYPE_DOUBLE: result->Value.aValue[i] = memory_NewDouble(pMo); if( result->Value.aValue[i] == NULL )return NULL; result->Value.aValue[i]->Value.dValue = p->Value.aValue[i]->Value.dValue; continue; case VTYPE_STRING: result->Value.aValue[i] = memory_NewString(pMo,STRLEN(p->Value.aValue[i])); if( result->Value.aValue[i] == NULL )return NULL; memcpy(result->Value.aValue[i]->Value.pValue, p->Value.aValue[i]->Value.pValue,STRLEN(p->Value.aValue[i])); continue; case VTYPE_REF: result->Value.aValue[i] = memory_NewRef(pMo); memory_SetRef(pMo,&(result->Value.aValue[i]),&(p->Value.aValue[i])); continue; } } return result; }
/*FUNCTION*/ int memory_ReplaceVariable(pMemoryObject pMo, pFixSizeMemoryObject *Lval, pFixSizeMemoryObject NewValue, pMortalList pMortal, int iDupFlag ){ /*noverbatim CUT*/ int iErrorCode; iErrorCode = 0; /* This is quite common that a variable is used to hold the same type of value. Changing the value only and not allocating a new variable and releasing the old speeds up execution a bit. I could see some speed improvement when running the program mandel1.bas */ if( memory_IsUndef(*Lval) && memory_IsUndef(NewValue) )return COMMAND_ERROR_SUCCESS; if( *Lval && NewValue ){ if( NewValue->vType == VTYPE_LONG && (*Lval)->vType == VTYPE_LONG ){ LONGVALUE(*Lval) = LONGVALUE(NewValue); return COMMAND_ERROR_SUCCESS; } if( NewValue->vType == VTYPE_DOUBLE && (*Lval)->vType == VTYPE_DOUBLE ){ DOUBLEVALUE(*Lval) = DOUBLEVALUE(NewValue); return COMMAND_ERROR_SUCCESS; } } /* after the references have been looked after we duplicate the result to have an own copy of the value. */ if( NewValue && iDupFlag ){ NewValue = memory_DupMortalize(pMo,NewValue,pMortal,&iErrorCode); if( iErrorCode )return iErrorCode; } /* if the result of the expression is not undef then immortalize */ if( NewValue ) /* we immortalize the new variable if it is a variable and not NULL meaning undef */ memory_Immortalize(NewValue,pMortal); /* if there are other variables that reference this variable and the value is undef then we need a stored undef */ if( *Lval && (*Lval)->link.rprev && NewValue == NULL )NewValue = memory_NewUndef(pMo); /* The new value will hold the same reference information as the former value. The former on the other hand is going to be unhooked. */ if( *Lval && (*Lval)->link.rprev ){ NewValue->link.rprev = (*Lval)->link.rprev; if( NewValue->link.rprev )(*(NewValue->link.rprev))->next = NewValue; (*Lval)->link.rprev = NULL; NewValue->next = (*Lval)->next; (*Lval)->next = NULL; } /* if this variable had value assigned to it then release that value */ if( *Lval )memory_ReleaseVariable(pMo,*Lval); /* and finally assign the code to the variable */ *Lval = NewValue; return COMMAND_ERROR_SUCCESS; }