home *** CD-ROM | disk | FTP | other *** search
-
- /* e4functi.c (c)Copyright Sequiter Software Inc., 1987-1990. All rights reserved. */
-
- #include "p4misc.h"
- #include "d4all.h"
- #include "e4parse.h"
- #include "u4error.h"
-
- #include <string.h>
- #include <time.h>
-
- #ifndef NO_POW
- #include <math.h>
- #endif
-
- extern BASE *v4base ;
- extern int v4original_base_ref, v4cur_base ;
-
- E4FUNCTIONS v4functions[] =
- {
- /* I_FIELD_STR, 0 */
- { 0, 0, "", (E4FUNC *) 0, 0, T_STR, 0 },
-
- /* I_FIELD_LOG, 1 */
- { 1, 0, "", (E4FUNC *) 0, 0, T_LOG, 0 },
-
- /* I_FIELD_DATE_D, 2 */
- { 2, 0, "", (E4FUNC *) 0, 0, T_DATE_DOUB, 0 },
-
- /* I_FIELD_DATE_S, 3 */
- { 3, 0, "", (E4FUNC *) 0, 0, T_DATE_STR, 0 },
-
- /* I_FIELD_NUM_D, 4 */
- { 4, 0, "", (E4FUNC *) 0, 0, T_NUM_DOUB, 0 },
-
- /* I_FIELD_NUM_S, 5 */
- { 5, 0, "", (E4FUNC *) 0, 0, T_NUM_STR, 0 },
-
- /* I_STRING, 6 */
- { 6, 0, "", (E4FUNC *) 0, 0, T_STR, 0 },
-
- /* I_DOUBLE, 7 */
- { 7, 0, "", (E4FUNC *) 0, 0, T_NUM_DOUB, 0 },
-
- { 8, 6, ".TRUE.", e4true, 0, T_LOG, 0 },
- { 8, 3, ".T.", e4true, 0, T_LOG, 0 },
- { 10, 7, ".FALSE.",e4false, 0, T_LOG, 0 },
- { 10, 3, ".F.", e4false, 0, T_LOG, 0 },
- { 12, 5, ".NOT.", e4not, 5, T_LOG, 1, T_LOG },
-
- #ifdef NO_POW
- { 17, 0,"", (E4FUNC *) 0, 9, T_NUM_DOUB, 2, T_NUM_DOUB, T_NUM_DOUB },
- { 17, 0,"", (E4FUNC *) 0, 9, T_NUM_DOUB, 2, T_NUM_DOUB, T_NUM_DOUB },
- #else
- { 17, 1,"^", e4power, 9, T_NUM_DOUB, 2, T_NUM_DOUB, T_NUM_DOUB },
- { 17, 2,"**", e4power, 9, T_NUM_DOUB, 2, T_NUM_DOUB, T_NUM_DOUB },
- #endif
-
- { 19, 1,"#", e4not_equal, 6, T_LOG, 2, T_STR, T_STR },
- { 19, 2,"<>", e4not_equal, 6, T_LOG, 2, T_STR, T_STR },
- { 19, 2,"<>", e4not_equal, 6, T_LOG, 2, T_NUM_DOUB, T_NUM_DOUB },
- { 19, 2,"<>", e4not_equal, 6, T_LOG, 2, T_DATE_DOUB, T_DATE_DOUB },
- { 19, 2,"<>", e4not_equal, 6, T_LOG, 2, T_LOG, T_LOG },
-
- { 21, 2,">=", e4greater_eq, 6, T_LOG, 2, T_STR, T_STR },
- { 21, 2,">=", e4greater_eq, 6, T_LOG, 2, T_NUM_DOUB, T_NUM_DOUB },
- { 21, 2,">=", e4greater_eq, 6, T_LOG, 2, T_DATE_DOUB, T_DATE_DOUB },
-
- { 23, 2,"<=", e4less_eq, 6, T_LOG, 2, T_STR, T_STR },
- { 23, 2,"<=", e4less_eq, 6, T_LOG, 2, T_NUM_DOUB, T_NUM_DOUB },
- { 23, 2,"<=", e4less_eq, 6, T_LOG, 2, T_DATE_DOUB, T_DATE_DOUB },
-
- { 25, 1,"+", e4add, 7, T_NUM_DOUB, 2, T_NUM_DOUB, T_NUM_DOUB },
- { 25, 1,"+", e4add, 7, T_DATE_DOUB, 2, T_NUM_DOUB, T_DATE_DOUB },
- { 25, 1,"+", e4add, 7, T_DATE_DOUB, 2, T_DATE_DOUB, T_NUM_DOUB },
- { 25, 1,"+", e4concatenate, 7, T_STR, 2, T_STR, T_STR },
-
- { 30, 1,"-", e4sub, 7, T_NUM_DOUB, 2, T_NUM_DOUB, T_NUM_DOUB },
- { 30, 1,"-", e4sub, 7, T_NUM_DOUB, 2, T_DATE_DOUB, T_DATE_DOUB },
- { 30, 1,"-", e4sub, 7, T_DATE_DOUB, 2, T_DATE_DOUB, T_NUM_DOUB },
- { 30, 1,"-", e4concat_two, 7, T_STR, 2, T_STR, T_STR },
-
- { 40, 1,"*", e4multiply, 8, T_NUM_DOUB, 2, T_NUM_DOUB, T_NUM_DOUB },
- { 50, 1,"/", e4divide, 8, T_NUM_DOUB, 2, T_NUM_DOUB, T_NUM_DOUB },
-
- { 70, 1,"$", e4contain, 6, T_LOG, 2, T_STR, T_STR },
-
- { 80, 1,"=", e4equal, 6, T_LOG, 2, T_STR, T_STR },
- { 80, 1,"=", e4equal, 6, T_LOG, 2, T_NUM_DOUB, T_NUM_DOUB },
- { 80, 1,"=", e4equal, 6, T_LOG, 2, T_DATE_DOUB, T_DATE_DOUB },
- { 80, 1,"=", e4equal, 6, T_LOG, 2, T_LOG, T_LOG },
-
- {100, 1,">", e4greater, 6, T_LOG, 2, T_STR, T_STR },
- {100, 1,">", e4greater, 6, T_LOG, 2, T_NUM_DOUB, T_NUM_DOUB },
- {100, 1,">", e4greater, 6, T_LOG, 2, T_DATE_DOUB, T_DATE_DOUB },
-
- {110, 1,"<", e4less, 6, T_LOG, 2, T_STR, T_STR },
- {110, 1,"<", e4less, 6, T_LOG, 2, T_NUM_DOUB, T_NUM_DOUB },
- {110, 1,"<", e4less, 6, T_LOG, 2, T_DATE_DOUB, T_DATE_DOUB },
-
- {150, 4,".OR.", e4or, 3, T_LOG, 2, T_LOG, T_LOG },
- {160, 5,".AND.", e4and, 4, T_LOG, 2, T_LOG, T_LOG },
-
- {170, 4,"STOD", e4stod, 0, T_DATE_DOUB, 1, T_STR },
- {175, 4,"CTOD", e4ctod, 0, T_DATE_DOUB, 1, T_STR },
- {180, 4,"DTOS", e4dtos, 0, T_STR, 1, T_DATE_STR },
- {180, 4,"DTOS", e4dtos, 0, T_STR, 1, T_DATE_DOUB },
- {185, 4,"DTOC", e4dtoc, 0, T_STR, 1, T_DATE_STR },
- {185, 4,"DTOC", e4dtoc, 0, T_STR, 1, T_DATE_DOUB },
- {190, 4,"DATE", e4date, 0, T_DATE_DOUB, 0 },
- {194, 3,"DAY", e4day, 0, T_NUM_DOUB, 1, T_DATE_DOUB },
- {194, 3,"DAY", e4day, 0, T_NUM_DOUB, 1, T_DATE_STR },
- {196, 5,"MONTH", e4month, 0, T_NUM_DOUB, 1, T_DATE_DOUB },
- {196, 5,"MONTH", e4month, 0, T_NUM_DOUB, 1, T_DATE_STR },
- {198, 4,"YEAR", e4year, 0, T_NUM_DOUB, 1, T_DATE_DOUB },
- {198, 4,"YEAR", e4year, 0, T_NUM_DOUB, 1, T_DATE_STR },
-
- {200, 7,"DELETED", e4deleted, 0, T_LOG, 0 },
- {210, 3,"DEL", e4del, 0, T_STR, 0 },
- {220, 3,"IIF", e4iif, 0, T_STR, 3, T_LOG, T_STR, T_STR },
- {220, 3,"IIF", e4iif, 0, T_NUM_DOUB, 3, T_LOG, T_NUM_DOUB, T_NUM_DOUB },
- {220, 3,"IIF", e4iif, 0, T_LOG, 3, T_LOG, T_LOG, T_LOG },
- {220, 3,"IIF", e4iif, 0, T_DATE_DOUB, 3, T_LOG, T_DATE_DOUB, T_DATE_DOUB },
- {230, 8,"RECCOUNT",e4reccount,0, T_NUM_DOUB, 0 },
- {240, 5,"RECNO", e4recno, 0, T_NUM_DOUB, 0 },
- {250, 3,"STR", e4str, 0, T_STR, 3, T_NUM_DOUB, T_NUM_DOUB, T_NUM_DOUB },
- {260, 6,"SUBSTR", e4substr, 0, T_STR, 3, T_STR, T_NUM_DOUB, T_NUM_DOUB },
- {270, 4,"TIME", e4time, 0, T_STR, 0 },
- {280, 5,"UPPER", e4upper, 0, T_STR, 1, T_STR },
- {290, 3,"VAL", e4val, 0, T_NUM_DOUB, 1, T_STR },
- {-1},
- } ;
-
-
- /* Function rules
-
- 1. Place the result back in parameter one.
- 2. If the result is of length greater than the length of
- parameter one, be aware that the result will overwrite
- parameter two, ...
- 3. If the type of the result is different than the type
- of parameter one, place the result type in 'parms[0].type'.
- 4. If the length of the result is different from the length
- of parameter one, place the resulting length in 'parms[0].len'.
- 5. If there is an error, put a length of '-1' in 'parms[0].len'.
- */
-
- void e4true( E4PARM *parms )
- {
- if ( e4return_len(parms, sizeof(int)) < 0 ) return ;
- parms[0].len = sizeof(int) ;
- *parms[0].p.i = 1 ;
- parms[0].type = T_LOG ;
- }
-
- void e4false( E4PARM *parms )
- {
- if ( e4return_len(parms, sizeof(int)) < 0 ) return ;
- parms[0].len = sizeof(int) ;
- *parms[0].p.i = 0 ;
- parms[0].type = T_LOG ;
- }
-
- void e4add( E4PARM *parms )
- {
- *parms[0].p.d += *parms[1].p.d ;
- if ( parms[1].type == T_DATE_DOUB )
- parms[0].type = T_DATE_DOUB ;
- }
-
- void e4concatenate( E4PARM *parms )
- {
- #ifdef PORTABLE
- memcpy( parms[0].p.c+ parms[0].len, parms[1].p.c, (size_t) parms[1].len ) ;
- #endif
-
- /* Unless there is extra alignment lJngth, the parameters are
- already concatenated together. */
- parms[0].len += parms[1].len ;
- }
-
- void e4sub( E4PARM *parms )
- {
- *parms[0].p.d -= *parms[1].p.d ;
- if ( parms[0].type == parms[1].type )
- parms[0].type = T_NUM_DOUB ;
- else
- parms[0].type = T_DATE_DOUB ;
- }
-
- void e4concat_two( E4PARM *parms )
- {
- int n, len ;
- char *ptr ;
-
- /* Count the Number of Spaces to Move */
- for( ptr = parms[0].p.c + (len = parms[0].len-1), n=0;
- len-- >= 0 && (*ptr == ' ' || *ptr == '\000');
- n++, ptr-- ) ;
-
- memmove( parms[0].p.c+ (parms[0].len- n), parms[1].p.c, (size_t) parms[1].len) ;
- memset( parms[0].p.c+ (parms[0].len -n) + parms[1].len, (int) ' ', (size_t) n ) ;
-
- parms[0].len += parms[1].len ;
- }
-
- void e4multiply( E4PARM *parms )
- {
- *parms[0].p.d *= *parms[1].p.d ;
- }
-
- void e4divide( E4PARM *parms )
- {
- *parms[0].p.d /= *parms[1].p.d ;
- }
-
- #ifndef NO_POW
- void e4power( E4PARM *parms )
- {
- if ( e4return_len(parms, sizeof(double)) < 0 ) return ;
- parms[0].len = sizeof(double) ;
- parms[0].type = T_NUM_DOUB ;
- *parms[0].p.d = pow( *parms[0].p.d, *parms[1].p.d ) ;
- }
- #endif
-
- void e4not_equal( E4PARM *parms )
- {
- int rc, len ;
-
- switch( parms[1].type )
- {
- case T_STR:
- if ( parms[0].len < parms[1].len )
- len = parms[0].len ;
- else
- len = parms[1].len ;
-
- rc = memcmp( parms[0].p.c, parms[1].p.c, (size_t) len) ;
-
- if ( rc == 0 )
- if ( parms[0].len < parms[1].len )
- rc = -1 ;
- break ;
-
- case T_NUM_DOUB:
- case T_DATE_DOUB:
- if ( *parms[0].p.d < *parms[1].p.d )
- rc = -1 ;
- else
- {
- if ( *parms[0].p.d == *parms[1].p.d )
- rc = 0 ;
- else
- rc = 1 ;
- }
- break ;
-
- case T_LOG:
- /* Equal if .T. and .T. or .F. .and .F. */
- rc = ! (*parms[0].p.i && *parms[1].p.i ||
- ! *parms[0].p.i && ! *parms[1].p.i ) ;
- break ;
- }
-
- parms[0].type = T_LOG ;
- parms[0].len = sizeof(int) ;
- *parms[0].p.i = rc ;
- }
-
- void e4equal( E4PARM *parms )
- {
- e4not_equal( parms ) ;
- *parms[0].p.i = ! *parms[0].p.i ;
- }
-
- void e4greater( E4PARM *parms )
- {
- e4not_equal( parms ) ;
- *parms[0].p.i = *parms[0].p.i > 0 ;
- }
-
- void e4less( E4PARM *parms )
- {
- e4not_equal( parms ) ;
- *parms[0].p.i = *parms[0].p.i < 0 ;
- }
-
- void e4greater_eq( E4PARM *parms )
- {
- e4not_equal( parms ) ;
- *parms[0].p.i = *parms[0].p.i >= 0 ;
- }
-
- void e4less_eq( E4PARM *parms )
- {
- e4not_equal( parms ) ;
- *parms[0].p.i = *parms[0].p.i <= 0 ;
- }
-
- void e4not( E4PARM *parms )
- {
- *parms[0].p.i = ! *parms[0].p.i ;
- }
-
- void e4or( E4PARM *parms )
- {
- *parms[0].p.i = *parms[0].p.i || *parms[1].p.i ;
- }
-
- void e4and( E4PARM *parms )
- {
- *parms[0].p.i = *parms[0].p.i && *parms[1].p.i ;
- }
-
- void e4stod( E4PARM *parms )
- {
- parms[0].type = T_DATE_DOUB ;
-
- if ( c4dt_julian( parms[0].p.c, parms[0].p.d ) < 0 )
- {
- u4error( E_DATE, parms[0].p.c, (char *) 0 ) ;
- parms[0].len = -1 ;
- }
- }
-
- void e4dtos( E4PARM *parms )
- {
- double start_date ;
-
- if ( parms[0].type == T_DATE_DOUB )
- {
- start_date = *parms[0].p.d ;
- c4dt_str( parms[0].p.c, &start_date ) ;
- }
- parms[0].type = T_STR ;
- }
-
- void e4ctod( E4PARM *parms )
- {
- char *ptr ;
-
- if ( e4return_len(parms, sizeof(double)) < 0 ) return ;
-
- parms[0].type = T_DATE_DOUB ;
-
- ptr = c4dt_unformat( parms[0].p.c, "MM/DD/YY" ) ;
- if ( c4dt_julian( ptr, parms[0].p.d ) < 0 )
- {
- u4error( E_DATE, parms[0].p.c, (char *) 0 ) ;
- parms[0].len = -1 ;
- }
- else
- parms[0].len = sizeof(double) ;
- }
-
- void e4dtoc( E4PARM *parms )
- {
- char *ptr ;
- e4dtos( parms ) ;
-
- /* Now reformat from CCYYMMDD to MM/DD/YY */
- ptr = c4dt_format( parms[0].p.c, "MM/DD/YY" ) ;
- memcpy( parms[0].p.c, ptr, (size_t) 8 ) ;
- }
-
- void e4date( E4PARM *parms )
- {
- long time_val ;
- struct tm *tm_ptr ;
- char dt[10] ;
-
- if ( e4return_len(parms, 8) < 0 ) return ;
-
- time ( (time_t *) &time_val) ;
- tm_ptr = localtime( (time_t *) &time_val) ;
- c4ltoa( 1900L+ tm_ptr->tm_year, dt, -4 ) ;
- c4ltoa( (long) tm_ptr->tm_mon+1, dt+4, -2 ) ;
- c4ltoa( (long) tm_ptr->tm_mday, dt+6, -2 ) ;
- c4dt_julian( dt, parms[0].p.d ) ;
-
- parms[0].len = sizeof(double) ;
- parms[0].type = T_DATE_DOUB ;
- }
-
- void e4day( E4PARM *parms )
- {
- e4dtos( parms ) ;
- *parms[0].p.d = c4atod( parms[0].p.c+6, 2 ) ;
- parms[0].type = T_NUM_DOUB ;
- }
-
- void e4month( E4PARM *parms )
- {
- e4dtos( parms ) ;
- *parms[0].p.d = c4atod( parms[0].p.c+4, 2 ) ;
- parms[0].type = T_NUM_DOUB ;
- }
-
- void e4year( E4PARM *parms )
- {
- e4dtos( parms ) ;
- *parms[0].p.d = c4atod( parms[0].p.c, 4 ) ;
- parms[0].type = T_NUM_DOUB ;
- }
-
- void e4del( E4PARM *parms )
- {
- if ( e4return_len(parms, sizeof(int)) < 0 ) return ;
- *parms[0].p.c = *v4base[v4original_base_ref].buffer ;
- parms[0].len = 1 ;
- parms[0].type = T_STR ;
- }
-
- void e4deleted( E4PARM *parms )
- {
- if ( e4return_len(parms, sizeof(int)) < 0 ) return ;
- *parms[0].p.i = *v4base[v4original_base_ref].buffer == '*' ;
- parms[0].len = sizeof(int) ;
- parms[0].type = T_LOG ;
- }
-
- void e4iif( E4PARM *parms )
- {
- E4PARM *ptr ;
-
- if ( *parms[0].p.i )
- ptr = parms+1 ;
- else
- ptr = parms+2 ;
-
- memmove( parms[0].p.c, ptr->p.c, (size_t) ptr->len ) ;
-
- parms[0].type = ptr->type ;
- parms[0].len = ptr->len ;
- }
-
- void e4reccount( E4PARM *parms )
- {
- int save_ref ;
-
- save_ref = v4cur_base ;
- v4cur_base = v4original_base_ref ;
-
- if ( e4return_len( parms, sizeof(double)) < 0 ) return ;
- *parms[0].p.d = (double) d4reccount() ;
- parms[0].type = T_NUM_DOUB ;
- parms[0].len = sizeof(double) ;
-
- v4cur_base = save_ref ;
- }
-
- void e4recno( E4PARM *parms )
- {
- if ( e4return_len( parms, sizeof(double)) < 0 ) return ;
- *parms[0].p.d = (double) v4base[v4original_base_ref].rec_num ;
- parms[0].type = T_NUM_DOUB ;
- parms[0].len = sizeof(double) ;
- }
-
- void e4str( E4PARM *parms )
- {
- char *ptr ;
- int len ;
-
- len = (int) *parms[1].p.d ;
- if ( e4return_len( parms, len) < 0 ) return ;
-
- ptr = c4dtoa( *parms[0].p.d, len, (int) *parms[2].p.d ) ;
- parms[0].type = T_STR ;
- parms[0].len = len ;
- memcpy( parms[0].p.c, ptr, (size_t) len ) ;
- }
-
- void e4substr( E4PARM *parms )
- {
- int start_pos, len ;
-
- start_pos = (int) *parms[1].p.d - 1 ;
- if ( start_pos < 0 ) start_pos = 0 ;
- if ( start_pos > parms[0].len )
- {
- e4return_len( parms, 0 ) ;
- return ;
- }
- len = (int) *parms[2].p.d ;
-
- if ( len > parms[0].len - start_pos )
- len = parms[0].len - start_pos ;
-
- e4return_len( parms, len ) ;
-
- memmove( parms[0].p.c, parms[0].p.c+start_pos, (size_t) len ) ;
- parms[0].len = len ;
- }
-
- void e4time( E4PARM *parms )
- {
- long time_val ;
- struct tm *tm_ptr ;
- char *r_ptr ;
-
- parms[0].type = T_STR ;
- parms[0].len = 8 ;
- e4return_len( parms, 8 ) ;
-
- r_ptr = parms[0].p.c ;
-
- time ( (time_t *) &time_val) ;
- tm_ptr = localtime( (time_t *) &time_val) ;
-
- c4ltoa( (long) tm_ptr->tm_hour, r_ptr, -2) ;
- r_ptr+= 2 ;
- *r_ptr++ = ':' ;
- c4ltoa( (long) tm_ptr->tm_min, r_ptr, -2) ;
- r_ptr+= 2;
- *r_ptr++ = ':' ;
- c4ltoa( (long) tm_ptr->tm_sec, r_ptr, -2) ;
- r_ptr+= 2 ;
- }
-
- void e4upper( E4PARM *parms )
- {
- if ( e4return_len( parms, parms[0].len+1 ) < 0 ) return ;
-
- parms[0].p.c[parms[0].len] = '\000' ;
- u4upper( parms[0].p.c ) ;
- }
-
- void e4val( E4PARM *parms )
- {
- if ( e4return_len(parms, (int) sizeof(double)) < 0 ) return ;
- *parms[0].p.d = c4atod( parms[0].p.c, (int) parms[0].len ) ;
- parms[0].len = sizeof(double) ;
- parms[0].type = T_NUM_DOUB ;
- }
-
- /* Is the first string contained in the second */
- void e4contain( E4PARM *parms )
- {
- int a_len, comp_len, i ;
- char first_char, *b_ptr ;
-
- parms[0].type = T_LOG ;
- e4return_len( parms, (int) sizeof(int) ) ;
-
- a_len = parms[0].len ;
- first_char = *parms[0].p.c ;
- comp_len = parms[1].len - a_len ;
- b_ptr = parms[1].p.c ;
-
- /* See if there is a match */
- for ( i=0; i <= comp_len; i++ )
- if ( first_char == b_ptr[i] )
- if ( memcmp( parms[0].p.c, b_ptr+i, (size_t) a_len ) == 0 )
- {
- *parms[0].p.i = 1 ;
- return ;
- }
-
- *parms[0].p.i = 0 ;
- parms[0].len = sizeof(int) ;
- }
-