/* i4init.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */ #include "d4all.h" #ifndef S4UNIX #ifdef __TURBOC__ #pragma hdrstop #endif #endif #ifndef N4OTHER #ifndef S4FOX int S4CALL t4cmp_doub( S4CMP_PARM data_ptr, S4CMP_PARM search_ptr, size_t len ) { double dif ; #ifdef S4UNIX double d1, d2 ; memcpy( (void *)&d1, data_ptr, sizeof(double) ) ; memcpy( (void *)&d2, search_ptr, sizeof(double) ) ; dif = d1 - d2 ; #else dif = *((double *)data_ptr) - *((double *)search_ptr) ; #endif if ( dif > E4ACCURACY ) return r4after ; if ( dif < -E4ACCURACY ) return -1 ; return r4success ; } int S4CALL t4desc_cmp_doub( S4CMP_PARM data_ptr, S4CMP_PARM search_ptr, size_t len ) { return -1 * t4cmp_doub( data_ptr, search_ptr, 0 ) ; } int S4CALL t4desc_bcd_cmp( S4CMP_PARM data_ptr, S4CMP_PARM search_ptr, size_t len ) { return -1 * c4bcd_cmp( data_ptr, search_ptr, 0 ) ; } int S4CALL t4desc_memcmp( S4CMP_PARM data_ptr, S4CMP_PARM search_ptr, size_t len ) { return -1 * u4memcmp( data_ptr, search_ptr, len ) ; } void t4str_to_date_mdx( char *result, char *input, int dummy ) { double d ; d = (double) date4long(input) ; memcpy( result, (void *)&d, sizeof(double) ) ; } void t4no_change_double( char *result, double d ) { memcpy( result, (void *)&d, sizeof(double) ) ; } void t4no_change_str( char *a, char *b, int l) { memcpy(a,b,l) ; } #ifndef S4INDEX_OFF int S4FUNCTION t4init( TAG4 *t4, INDEX4 *i4, T4DESC *tag_info ) { CODE4 *c4 ; FILE4SEQ_READ seqread ; char buffer[1024], garbage_buffer[518], expr_buf[I4MAX_EXPR_SIZE+1], *ptr ; int len ; #ifdef S4DEBUG if ( i4 == 0 || t4 == 0 || tag_info == 0 ) e4severe( e4parm, E4_T4INIT ) ; #endif c4 = i4->code_base ; if ( c4->error_code < 0 ) return -1 ; t4->index = i4 ; t4->code_base = c4 ; t4->unique_error = c4->default_unique_error ; t4->cmp = (S4CMP_FUNCTION *)u4memcmp ; t4->header_offset = tag_info->header_pos * 512 ; file4seq_read_init( &seqread, &i4->file, t4->header_offset, buffer, sizeof(buffer) ) ; if ( file4seq_read_all( &seqread, &t4->header, sizeof(T4HEADER)) < 0 ) return -1 ; #ifdef S4BYTE_SWAP t4->header.key_len = x4reverse_short( (void *)&t4->header.key_len ) ; t4->header.keys_max = x4reverse_short( (void *)&t4->header.keys_max ) ; t4->header.group_len = x4reverse_short( (void *)&t4->header.group_len ) ; t4->header.unique = x4reverse_short( (void *)&t4->header.unique ) ; #endif t4->header.root = -1 ; u4ncpy( t4->alias, tag_info->tag, sizeof(t4->alias) ) ; c4trim_n( t4->alias, sizeof(t4->alias) ) ; #ifndef S4UNIX c4upper( t4->alias ) ; #endif file4seq_read_all( &seqread, expr_buf, sizeof(expr_buf)-1 ) ; c4trim_n( expr_buf, sizeof(expr_buf) ) ; t4->expr = expr4parse( i4->data, expr_buf ) ; if ( !t4->expr ) return -1 ; len = expr4key_len( t4->expr ) ; if ( len < 0 ) return -1 ; if ( t4->header.key_len != (short)len ) { #ifdef S4DEBUG_DEV e4describe( c4, e4index, i4->file.name, "t4init()", "Expression length doesn't match tag length" ) ; #endif return e4( c4, e4index, i4->file.name ) ; } t4init_seek_conv( t4, t4->header.type ) ; file4seq_read_all( &seqread, garbage_buffer, sizeof(garbage_buffer) ) ; file4seq_read_all( &seqread, expr_buf, sizeof(expr_buf)-1 ) ; c4trim_n( expr_buf, sizeof(expr_buf) ) ; if ( garbage_buffer[1] == 1 ) /* Q&E support ... has filter */ { if ( expr_buf[0] != 0 ) { if ( garbage_buffer[2] == 1 ) t4->has_keys = t4->had_keys = 1 ; else t4->has_keys = t4->had_keys = 0 ; t4->filter = expr4parse( i4->data, expr_buf ) ; if ( t4->filter == 0 ) return -1 ; len = expr4key( t4->filter, &ptr ) ; if ( len < 0 ) return -1 ; if ( expr4type( t4->filter ) != 'L' ) { #ifdef S4DEBUG_DEV e4describe( c4, e4index, i4->file.name, "t4init()", "Filter type not expected logical" ) ; #endif return e4describe( c4, e4index, E4_INDEX_FIL, i4->file.name, (char *) 0 ) ; } } } return 0 ; } void S4FUNCTION t4init_seek_conv( TAG4 *t4, int key_type ) { int is_desc ; is_desc = t4->header.type_code & 8 ; switch( key_type ) { case r4num: if ( is_desc ) t4->cmp = t4desc_bcd_cmp ; else t4->cmp = c4bcd_cmp ; t4->stok = c4bcd_from_a ; t4->dtok = c4bcd_from_d ; break ; case r4date: if ( is_desc ) t4->cmp = t4desc_cmp_doub ; else t4->cmp = t4cmp_doub ; t4->stok = t4str_to_date_mdx ; t4->dtok = t4no_change_double ; break ; case r4str: if ( is_desc ) t4->cmp = t4desc_memcmp ; else t4->cmp = (S4CMP_FUNCTION *)u4memcmp ; t4->stok = t4no_change_str ; t4->dtok = 0 ; break ; default: #ifdef S4DEBUG e4severe( e4info, E4_INFO_INV ) ; #else e4( t4->code_base, e4info, E4_INFO_INV ) ; #endif } #ifdef S4UNIX switch( key_type ) { case r4num: t4->key_type = r4num ; break ; case r4date: t4->key_type = r4date ; break ; case r4str: t4->key_type = r4str ; break ; } #endif } #endif /* ifndef S4INDEX_OFF */ #endif /* ifndef S4FOX */ #ifdef S4FOX #ifndef S4INDEX_OFF #ifdef S4LANGUAGE extern unsigned char v4map[256]; #else #ifdef S4ANSI extern unsigned char v4map[256]; #endif #endif int S4CALL t4cdx_cmp( S4CMP_PARM data_ptr, S4CMP_PARM search_ptr, size_t len ) { unsigned char *data = (unsigned char *)data_ptr ; unsigned char *search = (unsigned char *)search_ptr ; unsigned on ; for( on = 0 ; on < len ; on++ ) { if ( data[on] != search[on] ) { #ifdef S4VMAP if ( v4map[data[on]] > v4map[search[on]] ) return -1 ; /* gone too far */ #else if ( data[on] > search[on] ) return -1 ; /* gone too far */ #endif break ; } } return on ; } void t4no_change_str( char *a, char *b, int l ) { memcpy(a,b,l) ; } void t4str_to_log( char *b, char *a, int l ) { int pos = 0 ; for ( ; l != pos ; pos++ ) switch( a[pos] ) { case 't': case 'T': case 'y': case 'Y': b[0] = 'T' ; return ; case 'f': case 'F': case 'n': case 'N': b[0] = 'F' ; return ; default: break ; } b[0] = 'F' ; } int S4FUNCTION t4init( TAG4 *t4, INDEX4 *i4, long file_pos, char *name ) { CODE4 *c4 ; char expr_buf[I4MAX_EXPR_SIZE+1], *ptr ; int len ; char top_size ; #ifdef S4DEBUG if ( i4 == 0 || t4 == 0 || name == 0 || file_pos < 0 ) e4severe( e4parm, E4_T4INIT ) ; #endif c4 = i4->code_base ; if ( c4->error_code < 0 ) return -1 ; t4->index = i4 ; t4->code_base = c4 ; t4->unique_error = c4->default_unique_error ; t4->header_offset = file_pos ; t4->header.root = -1 ; t4->cmp = t4cdx_cmp ; top_size = 2 * sizeof(long) + 4*sizeof(char) + sizeof(short) + 2 * sizeof(unsigned char) ; if ( file4read_all( &i4->file, file_pos, &t4->header, top_size ) < 0 ) return 0 ; if ( file4read_all( &i4->file, file_pos + (long)top_size + 486L, &t4->header.descending, ( 5 * sizeof(short) ) ) < 0 ) return 0 ; #ifdef S4BYTE_SWAP t4->header.root = x4reverse_long( (void *)&t4->header.root ) ; t4->header.free_list = x4reverse_long( (void *)&t4->header.free_list ) ; t4->header.version = x4reverse_long( (void *)&t4->header.version ) ; t4->header.key_len = x4reverse_short( (void *)&t4->header.key_len ) ; t4->header.descending = x4reverse_short( (void *)&t4->header.descending ) ; t4->header.filter_pos = x4reverse_short( (void *)&t4->header.filter_pos ) ; t4->header.filter_len = x4reverse_short( (void *)&t4->header.filter_len ) ; t4->header.expr_pos = x4reverse_short( (void *)&t4->header.expr_pos ) ; t4->header.expr_len = x4reverse_short( (void *)&t4->header.expr_len ) ; #endif u4ncpy( t4->alias, name, sizeof(t4->alias) ) ; c4trim_n( t4->alias, sizeof(t4->alias) ) ; #ifndef S4UNIX c4upper( t4->alias ) ; #endif if ( t4->header.type_code < 0x80 ) /* non-compound header; so expression */ { #ifdef S4DEBUG if ( t4->header.expr_len+1 > sizeof( expr_buf ) ) e4severe( e4info, E4_INFO_EXP ) ; #endif file4read_all( &i4->file, file_pos+B4BLOCK_SIZE, expr_buf, t4->header.expr_len ) ; expr_buf[t4->header.expr_len] = '\0' ; t4->expr = expr4parse( i4->data, expr_buf ) ; if ( t4->expr == 0 ) return -1 ; len = expr4key_len( t4->expr ) ; if ( len < 0 ) return -1 ; if ( t4->header.key_len != len ) { #ifdef S4DEBUG_DEV e4describe( c4, e4index, i4->file.name, "t4init()", "Expression length doesn't match tag length" ) ; #endif return e4( c4, e4index, i4->file.name ) ; } t4init_seek_conv(t4, t4->expr->type ) ; if ( t4->header.type_code & 0x08 ) /* For clause (filter) exists */ { file4read_all( &i4->file, file_pos+B4BLOCK_SIZE+t4->header.expr_len, expr_buf, t4->header.filter_len ) ; expr_buf[t4->header.filter_len] = '\0' ; t4->filter = expr4parse( i4->data, expr_buf ) ; if ( t4->filter == 0 ) return -1 ; len = expr4key( t4->filter, &ptr ) ; if ( len < 0 ) return -1 ; if ( expr4type( t4->filter ) != 'L' ) { #ifdef S4DEBUG_DEV e4describe( c4, e4index, i4->file.name, "t4init()", "Filter type not expected logical" ) ; #endif return e4describe( c4, e4index, E4_INDEX_FIL, i4->file.name, (char *) 0 ) ; } } } return 0 ; } void S4FUNCTION t4init_seek_conv( TAG4 *t4, int type ) { t4->cmp = t4cdx_cmp ; switch( type ) { case r4date: case r4date_doub: t4->stok = t4dtstr_to_fox ; t4->dtok = t4dbl_to_fox ; t4->p_char = '\0' ; break ; case r4num: case r4num_doub: t4->stok = t4str_to_fox ; t4->dtok = t4dbl_to_fox ; t4->p_char = '\0' ; break ; case r4str: t4->stok = t4no_change_str ; t4->dtok = 0 ; t4->p_char = ' ' ; break ; case r4log: t4->stok = t4str_to_log ; t4->dtok = 0 ; break ; default: #ifdef S4DEBUG e4severe( e4info, E4_INFO_INV ) ; #else e4( t4->code_base, e4info, E4_INFO_INV ) ; #endif } #ifdef S4UNIX switch( type ) { case r4num: case r4num_doub: t4->key_type = r4num ; break ; case r4date: case r4date_doub: t4->key_type = r4date ; break ; case r4str: t4->key_type = r4str ; break ; case r4log: t4->key_type = r4log ; break ; } #endif } #endif /* ifdef S4FOX */ #endif /* ifndef S4INDEX_OFF */ #endif /* ifndef N4OTHER */ #ifdef N4OTHER int S4CALL t4cmp_doub( S4CMP_PARM data_ptr, S4CMP_PARM search_ptr, size_t len ) { #ifdef S4UNIX double d1, d2 ; memcpy( &d1, data_ptr, sizeof(double) ) ; memcpy( &d2, search_ptr, sizeof(double) ) ; double dif = d1 - d2 ; #else double dif = *((double *)data_ptr) - *((double *)search_ptr) ; #endif if ( dif > E4ACCURACY ) return r4after ; if ( dif < -E4ACCURACY ) return -1 ; return r4success ; } void t4str_to_doub( char *result, char *input, int dummy ) { double d ; d = c4atod( input, strlen( input )) ; memcpy( result, &d, sizeof(double) ) ; } void t4str_to_date_mdx( char *result, char *input, int dummy ) { double d = (double) date4long(input) ; memcpy( result, &d, sizeof(double) ) ; } void t4no_change_double( char *result, double d ) { memcpy( result, &d, sizeof(double) ) ; } void t4no_change_str( char *a, char *b, int l) { memcpy(a,b,l) ; } #ifdef S4CLIPPER void t4str_to_clip( char *result, char *input, int dummy ) { memcpy ( result, input, strlen( input ) ) ; c4clip( result, strlen( result ) ) ; } #endif void t4date_doub_to_str( char *result, double d ) { long l ; l = (long) d ; date4assign( result, l ) ; } #ifndef S4INDEX_OFF void S4FUNCTION t4init_seek_conv( TAG4 *t4, int key_type ) { switch( key_type ) { #ifdef S4NDX case r4num: case r4num_doub: t4->cmp = t4cmp_doub ; t4->stok = t4str_to_doub ; t4->dtok = t4no_change_double ; break ; case r4date: case r4date_doub: t4->cmp = t4cmp_doub ; t4->stok = t4str_to_date_mdx ; t4->dtok = t4no_change_double ; break ; #else case r4date: case r4date_doub: t4->cmp = (S4CMP_FUNCTION *)u4memcmp ; t4->stok = t4no_change_str ; t4->dtok = t4date_doub_to_str ; break ; case r4num: case r4num_doub: t4->cmp = (S4CMP_FUNCTION *)u4memcmp ; t4->stok = t4str_to_clip ; t4->dtok = 0 ; break ; #endif case r4str: t4->cmp = (S4CMP_FUNCTION *)u4memcmp ; t4->stok = t4no_change_str ; t4->dtok = 0 ; break ; default: #ifdef S4DEBUG e4severe( e4info, E4_INFO_INV ) ; #else e4( t4->code_base, e4info, E4_INFO_INV ) ; #endif } #ifdef S4UNIX switch( key_type ) { case r4num: case r4num_doub: t4->key_type = r4num ; break ; case r4date: case r4date_doub: t4->key_type = r4date ; break ; case r4str: t4->key_type = r4str ; break ; } #endif } #endif /* N4OTHER */ #endif /* S4INDEX_OFF */