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 */
 |