campo-sirio/cb5/e4calc.c

187 lines
4.7 KiB
C
Raw Normal View History

/* e4calc.c (c)Copyright Sequiter Software Inc., 1991-1994. All rights reserved. */
#include "d4all.h"
#ifndef S4UNIX
#ifdef ___TURBOC__
#pragma hdrstop
#endif
#endif
void S4FUNCTION expr4calc_delete( EXPR4CALC *calc )
{
CODE4 *c4;
if( !calc || !calc->expr )
return;
c4 = calc->expr->code_base ;
if( calc->total != 0 )
{
l4remove( &c4->total_list, calc->total ) ;
mem4free( c4->total_memory, calc->total ) ;
}
l4remove( &c4->calc_list, calc ) ;
expr4free( calc->expr ) ;
mem4free( c4->calc_memory, calc ) ;
}
void S4FUNCTION expr4calc_reset( CODE4 *c4 )
{
while( c4->calc_list.n_link > 0 )
expr4calc_delete( (EXPR4CALC *)c4->calc_list.last_node ) ;
}
void S4FUNCTION expr4calc_massage( EXPR4CALC *calc )
{
EXPR4 *exp4 = calc->expr;
if( exp4->type == r4num )
{
/* Must consist of a single numeric field */
exp4->type = r4num_doub ;
exp4->len = sizeof(double) ;
exp4->info->len = f4len( exp4->info->field_ptr ) ;
exp4->info->function_i = E4FIELD_NUM_D ;
exp4->info->function = (S4OPERATOR S4PTR *)v4functions[E4FIELD_NUM_D].function_ptr ;
}
}
EXPR4CALC *S4FUNCTION expr4calc_create( CODE4 *c4, EXPR4 *exp4, char *name )
{
EXPR4CALC *calc_ptr = (EXPR4CALC *) mem4create_alloc( c4, &c4->calc_memory, 5, sizeof(EXPR4CALC), 5, 0 ) ;
if ( calc_ptr == 0 )
return 0 ;
l4add( &c4->calc_list, calc_ptr ) ;
calc_ptr->expr = exp4 ;
u4ncpy( calc_ptr->name, name, sizeof(calc_ptr->name) ) ;
c4upper( calc_ptr->name ) ;
expr4calc_massage( calc_ptr );
return calc_ptr ;
}
EXPR4CALC *S4FUNCTION expr4calc_lookup( CODE4 *c4, char *name, unsigned name_len )
{
EXPR4CALC *calc_on ;
char buf[sizeof(calc_on->name)] ;
if ( name_len >= sizeof(calc_on->name) )
name_len = sizeof(calc_on->name)-1 ;
u4ncpy( buf, name, name_len+1 ) ;
c4upper( buf ) ;
for( calc_on = 0 ;; )
{
calc_on = (EXPR4CALC *) l4next( &c4->calc_list, calc_on ) ;
if ( calc_on == 0 )
return 0 ;
if ( strcmp( calc_on->name, buf) == 0 )
return calc_on ;
}
}
void S4FUNCTION expr4calc_result_pos( EXPR4CALC *calc_ptr, int new_result_pos )
{
E4INFO *info ;
int i, offset = new_result_pos - calc_ptr->cur_result_pos ;
if ( offset == 0 )
return ;
calc_ptr->cur_result_pos = new_result_pos ;
info = calc_ptr->expr->info ;
for( i = calc_ptr->expr->info_n; --i >= 0; )
info[i].result_pos += offset ;
}
#ifndef S4UNIX
/* 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 expr4calc_name_change( EXPR4 **expr_on, char *old_name, char *new_name )
{
EXPR4 *new_expr ;
char buf_mem[50] ;
char *ptr, *buf ;
unsigned pos, buf_len ;
int old_name_len, ptr_len, new_name_len, did_alloc, buf_pos, did_change ;
ptr = expr4source( *expr_on ) ;
old_name_len = strlen( old_name ) ;
ptr_len = strlen( ptr ) ;
buf_len = sizeof( buf_mem ) ;
buf = buf_mem ;
did_alloc = buf_pos = did_change = 0 ;
for( pos = 0; ptr[pos]; pos++)
{
buf[buf_pos++] = ptr[pos] ;
if( (unsigned)buf_pos == buf_len )
{
if( did_alloc )
{
u4alloc_again( (*expr_on)->code_base, &buf, &buf_len, buf_len+50 ) ;
if( buf == 0 )
return -1 ;
}
else
{
buf_len += 50 ;
buf = (char *) u4alloc_er( (*expr_on)->code_base, buf_len + 50 ) ;
if( buf == 0 )
return -1 ;
memcpy( buf, buf_mem, sizeof(buf_mem) ) ;
did_alloc = 1 ;
}
}
if( ((unsigned) ptr_len - pos) < (unsigned) old_name_len ) continue ;
if( memicmp( ptr+pos, old_name, old_name_len ) != 0 ) continue ;
if( u4name_char( ptr[pos+old_name_len] ) ) continue ;
if( pos > 0 )
if( u4name_char(ptr[pos-1]) ) continue ;
did_change = 1 ;
new_name_len = strlen(new_name) ;
if( buf_len <= (unsigned) (buf_pos + new_name_len) )
{
if( did_alloc )
{
u4alloc_again( (*expr_on)->code_base, &buf, &buf_len, buf_len+ new_name_len + 50 ) ;
if( buf == 0 )
return -1 ;
}
else
{
buf_len += new_name_len + 50 ;
buf = (char *)u4alloc_er( (*expr_on)->code_base, buf_len ) ;
if( buf == 0 )
return -1 ;
memcpy( buf, buf_mem, sizeof(buf_mem) ) ;
did_alloc = 1 ;
}
}
memcpy( buf+(--buf_pos), new_name, new_name_len ) ;
buf_pos += new_name_len ;
pos += old_name_len-1 ;
}
if( did_change )
{
buf[buf_pos] = 0 ;
new_expr = expr4parse( (*expr_on)->data, buf ) ;
if( new_expr )
{
expr4free( *expr_on ) ;
*expr_on = new_expr ;
}
if( did_alloc )
u4free( buf ) ;
return 0 ;
}
return 1 ;
}
#endif