af15e0698b
git-svn-id: svn://10.65.10.50/trunk@4679 c028cbd2-c16b-5b4b-a496-9718f37d4682
215 lines
5.8 KiB
C
Executable File
215 lines
5.8 KiB
C
Executable File
/* 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 */
|