/* e4calc.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */ #include "d4all.h" #ifdef ___TURBOC__ #pragma hdrstop #endif void S4FUNCTION expr4calcMassage( EXPR4CALC *calc ) { EXPR4 *exp4 = calc->expr; if( exp4->type == r4num ) { /* Must consist of a single numeric field */ exp4->type = r4numDoub ; exp4->len = sizeof(double) ; exp4->info->len = f4len( exp4->info->fieldPtr ) ; exp4->info->functionI = E4FIELD_NUM_D ; exp4->info->function = (S4OPERATOR *)v4functions[E4FIELD_NUM_D].functionPtr ; } } EXPR4CALC *S4FUNCTION code4calcCreate( CODE4 *c4, EXPR4 *exp4, const char *name ) { #ifdef S4CLIENT CONNECTION4 *connection ; CONNECTION4CALC_CREATE_INFO_IN infoIn ; DATA4 *data ; int rc ; #endif EXPR4CALC *calcPtr ; #ifdef E4PARM_HIGH if ( c4 == 0 || exp4 == 0 || name == 0 ) { error4( 0, e4parm_null, E90920 ) ; return 0 ; } #endif calcPtr = (EXPR4CALC *)mem4createAlloc( c4, &c4->calcMemory, 5, sizeof(EXPR4CALC), 5, 0 ) ; if ( calcPtr == 0 ) return 0 ; #ifdef S4SERVER l4add( &c4->currentClient->calcList, calcPtr ) ; #else l4add( &c4->calcList, calcPtr ) ; #endif calcPtr->expr = exp4 ; u4ncpy( calcPtr->name, name, sizeof(calcPtr->name) ) ; c4upper( calcPtr->name ) ; expr4calcMassage( calcPtr ) ; #ifdef S4CLIENT if ( calcPtr != 0 ) /* need to register calc on server */ { data = exp4->data ; connection = data->dataFile->connection ; rc = connection4assign( connection, CON4CALC_CREATE, data4clientId( data ), data4serverId( data ) ) ; if ( rc < 0 ) return 0 ; memset( &infoIn, 0, sizeof( infoIn ) ) ; u4ncpy( infoIn.calcName, name, sizeof( calcPtr->name ) ) ; connection4addData( connection, &infoIn, sizeof( infoIn ), 0 ) ; connection4addData( connection, exp4->source, strlen( exp4->source ) + 1, 0 ) ; connection4send( connection ) ; rc = connection4receive( connection ) ; if ( rc < 0 ) return 0 ; rc = connection4status( connection ) ; if ( rc < 0 ) { connection4error( connection, c4, rc, E90920 ) ; return 0 ; } } #endif return calcPtr ; } EXPR4CALC *S4FUNCTION expr4calcLookup( CODE4 *c4, const char *name, const unsigned int nameLenIn ) { EXPR4CALC *calcOn ; char buf[sizeof(calcOn->name)] ; unsigned int nameLen ; nameLen = nameLenIn ; if ( nameLen >= sizeof(calcOn->name) ) nameLen = sizeof(calcOn->name)-1 ; u4ncpy( buf, name, nameLen+1 ) ; c4upper( buf ) ; for( calcOn = 0 ;; ) { #ifdef S4SERVER calcOn = (EXPR4CALC *)l4next( &c4->currentClient->calcList, calcOn ) ; #else calcOn = (EXPR4CALC *)l4next( &c4->calcList, calcOn ) ; #endif if ( calcOn == 0 ) return 0 ; if ( strcmp( calcOn->name, buf) == 0 ) return calcOn ; } } void S4FUNCTION expr4calcResultPos( EXPR4CALC *calcPtr, const int newResultPos ) { E4INFO *info ; int i, offset = newResultPos - calcPtr->curResultPos ; if ( offset == 0 ) return ; calcPtr->curResultPos = newResultPos ; info = calcPtr->expr->info ; for( i = calcPtr->expr->infoN; --i >= 0; ) info[i].resultPos += offset ; } #ifdef S4WINTEL /* Expression source must be updated to refect the fact that a calculation had a name change */ /* Caller must ensure names are trimmed in front and back & are upper case */ int S4FUNCTION expr4calcNameChange( EXPR4 **exprOn, const char *oldName, const char *newName ) { EXPR4 *newExpr ; char bufMem[50] ; char *buf ; unsigned pos, bufLen ; int oldNameLen, ptrLen, newNameLen, didAlloc, bufPos, didChange ; const char *ptr ; ptr = expr4source( *exprOn ) ; oldNameLen = strlen( oldName ) ; ptrLen = strlen( ptr ) ; bufLen = sizeof( bufMem ) ; buf = bufMem ; didAlloc = bufPos = didChange = 0 ; for( pos = 0; ptr[pos]; pos++) { buf[bufPos++] = ptr[pos] ; if( (unsigned)bufPos == bufLen ) { if( didAlloc ) { u4allocAgain( (*exprOn)->codeBase, &buf, &bufLen, bufLen+50 ) ; if( buf == 0 ) return -1 ; } else { bufLen += 50 ; buf = (char *) u4allocEr( (*exprOn)->codeBase, bufLen + 50 ) ; if( buf == 0 ) return -1 ; memcpy( buf, bufMem, sizeof(bufMem) ) ; didAlloc = 1 ; } } if( ((unsigned) ptrLen - pos) < (unsigned) oldNameLen ) continue ; if( memicmp( (void *)(ptr+pos), (void *)oldName, oldNameLen ) != 0 ) continue ; if( u4nameChar( ptr[pos+oldNameLen] ) ) continue ; if( pos > 0 ) if( u4nameChar(ptr[pos-1]) ) continue ; didChange = 1 ; newNameLen = strlen(newName) ; if( bufLen <= (unsigned) (bufPos + newNameLen) ) { if( didAlloc ) { u4allocAgain( (*exprOn)->codeBase, &buf, &bufLen, bufLen+ newNameLen + 50 ) ; if( buf == 0 ) return -1 ; } else { bufLen += newNameLen + 50 ; buf = (char *)u4allocEr( (*exprOn)->codeBase, bufLen ) ; if( buf == 0 ) return -1 ; memcpy( buf, bufMem, sizeof(bufMem) ) ; didAlloc = 1 ; } } memcpy( buf+(--bufPos), newName, newNameLen ) ; bufPos += newNameLen ; pos += oldNameLen-1 ; } if( didChange ) { buf[bufPos] = 0 ; newExpr = expr4parseLow( (*exprOn)->data, buf, 0 ) ; if( newExpr ) { expr4free( *exprOn ) ; *exprOn = newExpr ; } if( didAlloc ) u4free( buf ) ; return 0 ; } return 1 ; } #endif /* S4WINTEL */