home *** CD-ROM | disk | FTP | other *** search
-
- /* e4exec.c (c)Copyright Sequiter Software Inc., 1987-1990. All rights reserved.
-
- Expression Execution Routines
- */
-
-
- #include "p4misc.h"
- #include "d4all.h"
- #include "e4parse.h"
- #include "u4error.h"
-
- #include <string.h>
- #include <stdlib.h>
-
- extern BASE *v4base ;
- extern E4FUNCTIONS v4functions[] ;
- extern int v4cur_base ;
-
-
- extern char *v4eval_space ;
- extern int v4eval_len ;
-
- static int v4return_left ; /* The amount of result space currently available */
- static char *v4compile_string ; /* The originally compiled string */
- int v4original_base_ref=-1; /* The database reference number when the expression was originally parsed */
- int v4type = -1 ;
- static int v4length = -1 ;
-
- #ifdef PORTABLE
- static int calc_extra_len( E4PARM * ) ;
-
- static int calc_extra_len( E4PARM *parms )
- {
- parms[0].extra_len = sizeof(double) - parms[0].len % sizeof(double) ;
- if ( parms[0].extra_len == sizeof(double) )
- parms[0].extra_len = 0 ;
-
- v4return_left -= parms[0].extra_len ;
- parms[1].p.c += parms[0].extra_len ;
-
- return e4return_len( parms, parms[0].extra_len ) ;
- }
- #endif
-
- int e4return_len( E4PARM *parms, int len )
- {
- if ( v4return_left < len )
- {
- parms[0].len = -1 ;
- u4error( E_OVERFLOW, v4compile_string, (char *) 0 ) ;
- return -1 ;
- }
- return 0 ;
- }
-
- char e4type()
- {
- return( (char) v4type ) ;
- }
-
- int e4length()
- {
- return( v4length ) ;
- }
-
- /* 1. Get function type and parameter information.
- 2. Recursively call to get the parameters.
- 3. Call function with the parameters.
- 4. Return the result.
-
- result_ptr points to where the value should be returned.
- return_len is the length of the available space.
-
- If the function returns a value of a specific length, the
- parameter space will not overlap the last parameter. Otherwise,
- 64 bytes of space will be allocated for the return value. If
- more is returned, the expression evaluation function return
- will overlap the last parameter and perhaps other parameters as well.
-
- Returns
- -1 Error
- >= 0 The length of the return value.
- */
-
- #define VOID_PTR void *
-
- VOID_PTR e4vary( char *comp_ptr )
- {
- int f_code, len, i, n_parms ;
- long field_ref ;
- BASE *base_ptr ;
- FIELD *field_ptr ;
- E4PARM parms[PARM_STACK_SIZE] ;
- void *ptr ;
-
- #ifdef PORTABLE
- char *compile_ptr ;
-
- compile_ptr = comp_ptr ;
-
- compile_ptr += sizeof(int) ;
- memcpy( &len, compile_ptr, sizeof(int) ) ;
- compile_ptr += sizeof(int) ;
-
- v4compile_string = (char *) compile_ptr ;
- compile_ptr += len ;
- #else
- int *compile_ptr ;
- long *long_ptr ;
- compile_ptr = (int *) comp_ptr ;
-
- compile_ptr++ ;
- len = *compile_ptr++ ;
-
- v4compile_string = (char *) compile_ptr ;
- compile_ptr = (int *) ((char *)compile_ptr + len) ;
- #endif
-
- v4return_left = v4eval_len ;
- n_parms = 0 ;
-
- #ifdef PORTABLE
- memcpy( &v4original_base_ref, compile_ptr, sizeof(int) ) ;
- compile_ptr += sizeof(int) ;
- #else
- v4original_base_ref = *compile_ptr++ ;
- #endif
- parms[0].p.c = (char *) v4eval_space ;
-
- for (;;)
- {
- #ifdef PORTABLE
- memcpy( &f_code, compile_ptr, sizeof(int) ) ;
- compile_ptr += sizeof(int) ;
- #else
- f_code = *compile_ptr++ ;
- #endif
-
- if ( n_parms+1 >= PARM_STACK_SIZE )
- {
- u4error( E_OVERFLOW, v4compile_string, (char *) 0 ) ;
- return( (char *) 0 ) ;
- }
-
- if ( f_code > LAST_IMMEDIATE )
- {
- n_parms -= v4functions[f_code].num_parms ;
- for ( i=0; i< v4functions[f_code].num_parms; i++ )
- {
- v4return_left += parms[n_parms+i].len ;
- #ifdef PORTABLE
- v4return_left += parms[n_parms+i].extra_len ;
- #endif
- }
-
- (*v4functions[f_code].function_ptr)( parms+n_parms ) ;
- if ( parms[n_parms].len < 0 ) return( (char *) 0 ) ;
- v4return_left -= parms[n_parms].len ;
- parms[n_parms+1].p.c = parms[n_parms].p.c + parms[n_parms].len ;
-
- #ifdef PORTABLE
- if ( calc_extra_len( parms+n_parms ) < 0 ) return( (VOID_PTR) 0 ) ;
- #endif
-
- n_parms++ ;
- continue ;
- }
-
- if ( f_code < 0 )
- {
- v4type = parms[0].type ;
- v4length = parms[0].len ;
-
- #ifdef PORTABLE
- if ( v4eval_len-v4return_left != v4length + parms[0].extra_len )
- #else
- if ( v4eval_len-v4return_left != v4length )
- #endif
- u4error( E_INTERNAL, "e4vary: Return Length Discrepency", (char *) 0 ) ;
-
- if ( e4return_len( parms, 1) < 0 ) return( (char *) 0 ) ;
- parms[0].p.c[v4length] = '\000' ;
-
- return( v4eval_space ) ;
- }
-
- /* Field or Immediate Data */
- if ( f_code <= LAST_I_FIELD )
- {
- #ifdef PORTABLE
- memcpy( &field_ref, compile_ptr, sizeof(long) ) ;
- compile_ptr += sizeof(long) ;
- #else
- long_ptr = (long *) compile_ptr ;
- field_ref = *long_ptr ;
- compile_ptr = (int *) (((char *) compile_ptr) + sizeof(long)) ;
- #endif
-
- base_ptr = v4base + (int) (field_ref>>16) ;
- field_ptr = base_ptr->fields + (int) (field_ref & 0xFFFF) ;
-
- parms[n_parms].type = v4functions[f_code].return_type ;
-
- switch( f_code )
- { /* Calculate field values directly for slight extra speed */
- case I_FIELD_STR:
- case I_FIELD_NUM_S:
- case I_FIELD_DATE_S:
- if ( e4return_len( parms, field_ptr->width ) < 0 ) return( (VOID_PTR) 0 ) ;
- memcpy( parms[n_parms].p.c, base_ptr->buffer + field_ptr->offset, (size_t) field_ptr->width ) ;
- len = field_ptr->width ;
- if ( f_code == I_FIELD_NUM_S )
- {
- if ( field_ptr->decimals > 0 )
- parms[n_parms].p.c[field_ptr->width-field_ptr->decimals-1] = '.' ;
- }
- break ;
-
- case I_FIELD_NUM_D:
- if ( e4return_len( parms, sizeof(double) ) < 0 ) return( (VOID_PTR) 0 ) ;
- *parms[n_parms].p.d = c4atod( base_ptr->buffer+ field_ptr->offset, field_ptr->width ) ;
- len = sizeof(double) ;
- break ;
-
- case I_FIELD_DATE_D:
- if ( e4return_len( parms, sizeof(double) ) < 0 ) return( (VOID_PTR) 0 ) ;
- c4dt_julian( base_ptr->buffer+ field_ptr->offset, parms[n_parms].p.d ) ;
- len = sizeof(double) ;
- break ;
-
- case I_FIELD_LOG:
- if ( e4return_len( parms, sizeof(int) ) < 0 ) return( (VOID_PTR) 0 ) ;
- *parms[n_parms].p.i = f4true( field_ref ) ;
- len = sizeof(int) ;
- break ;
-
- #ifdef MEMO
- case I_FIELD_MEMO: /* Not Yet Supported */
- break ;
- #endif
- }
-
- v4return_left -= len ;
- parms[n_parms].len = len ;
- parms[n_parms+1].p.c = parms[n_parms].p.c + len ;
-
- #ifdef PORTABLE
- /* Make sure the next position is a multiple of 'sizeof(double)' */
- if ( calc_extra_len( parms+n_parms ) < 0 )
- return( (VOID_PTR) 0 ) ;
- #endif
-
- n_parms++ ;
- continue ;
- }
-
- /* Immediate Data */
- switch( f_code )
- {
- case I_STRING:
- #ifdef PORTABLE
- memcpy( &len, compile_ptr, sizeof(int) ) ;
- compile_ptr += sizeof(int) ;
- #else
- len = *compile_ptr++ ;
- #endif
- parms[n_parms].type = T_STR ;
- break ;
-
- case I_DOUBLE:
- len = (int) sizeof(double) ;
- parms[n_parms].type = T_NUM_DOUB ;
- break ;
- }
-
- if ( e4return_len( parms, len ) < 0 ) return( (VOID_PTR) 0 ) ;
- v4return_left -= len ;
- parms[n_parms].len = len ;
-
- ptr = parms[n_parms].p.v ;
- memcpy( ptr, compile_ptr, (size_t) len ) ;
- #ifdef PORTABLE
- compile_ptr += len ;
- #else
- compile_ptr = (int *) ((char *) compile_ptr + len) ;
- #endif
- parms[n_parms+1].p.c = (char *) ptr+ len ;
-
- #ifdef PORTABLE
- if ( calc_extra_len( parms+n_parms ) < 0 ) return ( (VOID_PTR) 0 ) ;
- #endif
-
- n_parms++ ;
- continue ;
- }
- }
-
-
- VOID_PTR e4exec( char *compile_ptr )
- {
- VOID_PTR result_ptr ;
-
- result_ptr = e4vary( compile_ptr ) ;
-
- if ( v4type == T_NUM_STR )
- {
- *((double *) result_ptr) = c4atod( (char *) result_ptr, v4length ) ;
- v4type = T_NUM_DOUB ;
- }
- if ( v4type == T_DATE_DOUB )
- {
- double index_date ;
-
- index_date = *((double *) result_ptr) ;
-
- c4dt_str( (char *) result_ptr, (double *) &index_date ) ;
- v4type = T_DATE_STR ;
- }
-
- return( result_ptr ) ;
- }
-
-
- extern int v4decimals ;
-
- char * e4string( char *compile_ptr )
- {
- char *result_ptr ;
-
- result_ptr = (char *) e4vary( compile_ptr ) ;
-
- if ( v4type == T_NUM_DOUB )
- {
- char *str, *ptr ;
- int dig_len, is_neg, zeros_len, i ;
-
- v4length = 17 ;
- v4type = T_NUM_STR ;
- str = fcvt( *((double *) result_ptr), v4decimals, &dig_len, &is_neg ) ;
-
- zeros_len = v4length - dig_len - 1 - v4decimals ;
- if ( zeros_len < 0 )
- {
- memset( result_ptr, (int) '*', (size_t) v4length) ;
- return( result_ptr) ;
- }
-
- memset( result_ptr, (int) '0', (size_t) zeros_len ) ;
- ptr = result_ptr + zeros_len ;
- memcpy( ptr, str, (size_t) dig_len ) ;
- ptr += dig_len ;
- *ptr = '.' ;
- memcpy( ++ptr, str+dig_len, (size_t) v4decimals ) ;
- ptr[v4decimals] = '\000' ;
-
- if ( is_neg )
- {
- for ( i=0; i< v4length; i++ )
- result_ptr[i] = (char) 0x5c - result_ptr[i] ;
- }
- return( result_ptr ) ;
- }
-
- if ( v4type == T_NUM_STR )
- {
- int i, negative ;
- char *p ;
-
- for ( i= negative= 0, p= result_ptr; i< v4length; i++, p++ )
- {
- if ( *p == ' ' )
- {
- *p = '0' ;
- }
- else
- {
- if ( *p == '-' )
- {
- *p = '0' ;
- negative = 1 ;
- }
- }
- }
-
- if ( negative )
- {
- for ( i= 0, p= result_ptr; i< v4length; i++, p++ )
- *p = (char) 0x5c - *p ;
- }
-
- return result_ptr ;
- }
-
- if ( v4type == T_DATE_DOUB )
- {
- double index_date ;
-
- index_date = *((double *) result_ptr) ;
-
- c4dt_str( (char *) result_ptr, (double *) &index_date ) ;
- v4type = T_DATE_STR ;
- v4length = 8 ;
- }
-
- return( (char *) result_ptr ) ;
- }
-
-
- VOID_PTR e4eval( char *expr_ptr )
- {
- char *compile_ptr ;
- VOID_PTR result_ptr ;
-
- if ( e4parse( expr_ptr, &compile_ptr) < 0) return( (VOID_PTR) 0) ;
- result_ptr = e4exec( compile_ptr ) ;
- h4free_memory( compile_ptr ) ;
- return( (VOID_PTR) result_ptr ) ;
- }
-
-