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