home *** CD-ROM | disk | FTP | other *** search
-
- /* c4.c Conversion Routines
- (c)Copyright Sequiter Software Inc., 1987-1990. All rights reserved.
- */
-
- #include "d4all.h"
- #include "u4error.h"
- #include "p4misc.h"
-
- #include <string.h>
- #include <ctype.h>
- #include <stdlib.h>
-
- #define JULIAN_ADJUSTMENT 1721425L
-
-
- static char buffer[130] ;
- #ifdef LANGUAGE
- static char month[][10]= {" ",
- "Januar ",
- "Februar ",
- "März ",
- "April ",
- "Mai ",
- "Juni ",
- "Juli ",
- "August ",
- "September",
- "Oktober ",
- "November ",
- "Dezember "
- } ;
-
- #else
- static char month[][10]= {" ",
- "January ",
- "February ",
- "March ",
- "April ",
- "May ",
- "June ",
- "July ",
- "August ",
- "September",
- "October ",
- "November ",
- "December "
- } ;
- #endif
-
- /* c4dt_format
-
- Formats a date from CCYYMMDD (Century, Year, Month, Day)
- format to any date format.
-
- The length of 'picture' must be 32 or less.
-
- If there are more than 2 'M' characters in the picture, the
- month will be in character form.
- */
-
- char *c4dt_format( char *dbf_date, char *picture )
- {
- char *ptr, *ptr_end ;
- int rest, len, m_num ;
-
- memset( buffer, (int) ' ', (size_t) sizeof(buffer) ) ;
-
- c4encode( buffer, dbf_date, picture, "CCYYMMDD") ;
-
- ptr_end = strchr( picture, 'M' ) ;
- if ( ptr_end != (char *) 0 )
- {
- ptr = buffer+ (int) (ptr_end-picture) ;
- len = 0 ;
- while ( *(ptr_end++) == 'M' ) len++ ;
-
- if ( len > 2)
- {
- /* Convert from a numeric form to character format for month */
-
- m_num = c4atoi( dbf_date+4, 2) ;
- if ( m_num < 0) m_num = 1 ;
- if ( m_num > 12) m_num = 12 ;
-
- rest = len - 9 ;
- if (len > 9) len = 9 ;
-
- memcpy( ptr, month[m_num], (size_t) len ) ;
- if (rest > 0) memset( ptr+len, (int) ' ', (size_t) rest ) ;
- }
- }
- return( buffer );
- }
-
-
- /* Converts from formatted Date Data into '.DBF' (CCYYMMDD) format */
-
- char *c4dt_unformat( char *date_data, char *picture )
- {
- char *month_start, month_data[10] ;
- int year_count, month_count, day_count, century_count, i, len ;
-
- day_count = 5 ;
- month_count = 3 ;
- year_count = 1 ;
- century_count= -1 ;
-
- memset( buffer, (int) ' ', (size_t) 8 ) ;
- buffer[8] = '\000' ;
-
- for ( i=0; picture[i] != '\000'; i++ )
- {
- switch( picture[i] )
- {
- case 'D':
- if ( ++day_count >= 8) break ;
- buffer[day_count] = date_data[i] ;
- break ;
-
- case 'M':
- if ( ++month_count >=6) break ;
- buffer[month_count] = date_data[i] ;
- break ;
-
- case 'Y':
- if ( ++year_count >= 4) break ;
- buffer[year_count] = date_data[i] ;
- break ;
-
- case 'C':
- if ( ++century_count >= 2) break ;
- buffer[century_count] = date_data[i] ;
- break ;
- }
- }
-
- if ( strcmp( buffer, " " ) == 0 ) return( buffer ) ;
-
- if ( century_count == -1 ) memcpy( buffer, "19", (size_t) 2 ) ;
- if ( year_count == 1 ) memcpy( buffer+2, "01", (size_t) 2 ) ;
- if ( month_count == 3 ) memcpy( buffer+4, "01", (size_t) 2 ) ;
- if ( day_count == 5 ) memcpy( buffer+6, "01", (size_t) 2 ) ;
-
- if ( month_count >= 6 )
- {
- /* Convert the Month from Character Form to Date Format */
- month_start = strchr( picture, 'M' ) ;
-
- len = month_count - 3 ; /* Number of 'M' characters in picture */
-
- memcpy( buffer+4, " ", (size_t) 2 ) ;
-
- if ( len > 3 ) len = 3 ;
- memcpy( month_data, date_data+ (int) (month_start-picture), (size_t) len) ;
- while ( len > 0 )
- if ( month_data[len-1] == ' ' )
- len-- ;
- else
- break ;
-
- month_data[len] = '\000' ;
-
- u4lower( month_data ) ;
- month_data[0] = (char) u4toupper( (int) month_data[0] ) ;
-
- if ( len > 0 )
- for( i=1; i<= 12; i++ )
- {
- if ( memcmp( month[i], month_data, (size_t) len) == 0 )
- {
- c4ltoa( (long) i, buffer+4, 2 ) ; /* Found Month Match */
- break ;
- }
- }
- }
-
- for ( i=0; i< 8; i++ )
- if ( buffer[i] == ' ' ) buffer[i] = '0' ;
-
- return ( buffer) ;
- }
-
-
- /* c4atod
-
- Converts a string to a double
- */
-
- double c4atod( char *char_string, int string_len )
- {
- char buffer[50] ;
- int len ;
-
- len = (string_len >= 50 ) ? 49 : string_len ;
- memcpy( buffer, char_string, (size_t) len ) ;
- buffer[len] = '\000' ;
-
- return( strtod( buffer, (char **) 0) ) ;
- }
-
- /* c4atoi.c */
-
- int c4atoi( char *ptr, int n)
- {
- char buf[128] ;
- if ( n >= sizeof(buf) ) n= sizeof(buf) -1 ;
- memcpy(buf, ptr, (size_t) n) ;
- buf[n] = '\000' ;
- return (atoi(buf) ) ;
- }
-
- /* c4atol */
-
- long c4atol( char *ptr, int n)
- {
- char buf[128] ;
- if ( n >= sizeof(buf) ) n= sizeof(buf) -1 ;
- memcpy(buf, ptr, (size_t) n) ;
- buf[n] = '\000' ;
- return (atol(buf) ) ;
- }
-
- /* c4ltoa
-
- Converts a RECNUM to a string. Fill with '0's rather than blanks if
- 'num' is less than zero.
- */
-
- char *c4ltoa( long l_val, char *ptr, int num)
- {
- int n, num_pos ;
- long i_long ;
-
- i_long = (l_val>0) ? l_val : -l_val ;
- num_pos = n = (num > 0) ? num : -num ;
-
- while (n-- > 0)
- {
- ptr[n] = (char) ('0'+ i_long%10) ;
- i_long = i_long/10 ;
- }
-
- if ( i_long > 0 )
- {
- memset( ptr, (int) '*', (size_t) num_pos ) ;
- return ptr ;
- }
-
- num--;
- for (n=0; n<num; n++)
- if (ptr[n]=='0')
- ptr[n]= ' ';
- else
- break ;
-
- if (l_val < 0)
- {
- if ( ptr[0] != ' ' )
- {
- memset( ptr, (int) '*', (size_t) num_pos ) ;
- return ptr ;
- }
- for (n=num; n>=0; n--)
- if (ptr[n]==' ')
- {
- ptr[n]= '-' ;
- break ;
- }
- }
-
- return(ptr) ;
- }
-
-
- /* c4encode
-
- - From CCYYMMDD to CCYY.MM.DD
-
- Ex. c4encode( to, from, "CCYY.MM.DD", "CCYYMMDD" ) ;
- */
-
- void c4encode( char *to, char *from, char *t_to, char *t_from)
- {
- int pos ;
- char chr ;
- char * chr_pos ;
-
- strcpy( to, t_to ) ;
-
- while ( (chr=*t_from++) != 0)
- {
- if ( (chr_pos= strchr(t_to,chr)) ==0)
- {
- from++;
- continue ;
- }
-
- pos = (int) (chr_pos - t_to) ;
- to[pos++] = *from++ ;
-
- while (chr== *t_from)
- {
- if (chr== t_to[pos])
- to[pos++] = *from ;
- t_from++ ;
- from++ ;
- }
- }
- }
-
- /* c4dtoa( doub_val, len, dec)
-
- - formats a double to a string
- - if there is an overflow, '*' are returned
-
- Return
-
- Pointer to the Formatted String
- */
-
- char * c4dtoa( double doub_val, int len, int dec)
- {
- int dec_val, sign_val ;
- int pre_len, post_len, sign_pos ; /* pre and post decimal point lengths */
- char *result, *out_string ;
-
- if ( len < 0 ) len = -len ;
- if ( len > 128 ) len = 128 ;
-
- memset( buffer, (int) '0', (size_t) len) ;
- out_string = buffer ;
-
- if (dec > 0)
- {
- post_len = dec ;
- if (post_len > 15) post_len = 15 ;
- if (post_len > len-1) post_len = len-1 ;
- pre_len = len -post_len -1 ;
-
- out_string[ pre_len] = '.' ;
- }
- else
- {
- pre_len = len ;
- post_len = 0 ;
- }
-
- result = fcvt( doub_val, post_len, &dec_val, &sign_val) ;
-
- if (dec_val > 0)
- sign_pos = pre_len-dec_val -1 ;
- else
- {
- sign_pos = pre_len - 2 ;
- if ( pre_len == 1) sign_pos = 0 ;
- }
-
- if ( dec_val > pre_len || pre_len<0 || sign_pos< 0 && sign_val)
- {
- /* overflow */
- memset( out_string, (int) '*', (size_t) len) ;
- return( buffer) ;
- }
-
- if (dec_val > 0)
- {
- memset( out_string, (int) ' ', (size_t) pre_len- dec_val) ;
- memmove( out_string+ pre_len- dec_val, result, (size_t) dec_val) ;
- }
- else
- {
- if (pre_len> 0) memset( out_string, (int) ' ', (size_t) (pre_len-1)) ;
- }
- if ( sign_val) out_string[sign_pos] = '-' ;
-
-
- out_string += pre_len+1 ;
- if (dec_val >= 0)
- {
- result+= dec_val ;
- }
- else
- {
- out_string -= dec_val ;
- post_len += dec_val ;
- }
-
- if ( post_len > (int) strlen(result) )
- post_len = (int) strlen( result) ;
-
- /* - out_string points to where the digits go to
- - result points to where the digits are to be copied from
- - post_len is the number to be copied
- */
-
- if (post_len > 0) memmove( out_string, result, (size_t) post_len) ;
-
- buffer[len] = '\000' ;
-
- return( buffer ) ;
- }
-
-
- extern double floor( double ) ;
-
- /* static c4julian
-
- Returns an (int) day of the year starting from 1.
- Ex. Jan 1, returns 1
-
- Returns -1 if it is an illegal date.
-
- */
-
- static int month_tot[]=
- { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 } ;
- /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
- 31 28 31 30 31 30 31 31 30 31 30 31
- */
-
- int c4julian( int year, int month, int day )
- {
- int is_leap, month_days ;
-
- is_leap = ( year%4 == 0 && year%100 != 0 || year%400 == 0 ) ? 1 : 0 ;
-
- month_days = month_tot[ month+1 ] - month_tot[ month] ;
- if ( month == 2 ) month_days += is_leap ;
-
- if ( year < 0 ||
- month < 1 || month > 12 ||
- day < 1 || day > month_days )
- return( -1 ) ; /* Illegal Date */
-
- if ( month <= 2 ) is_leap = 0 ;
-
- return( month_tot[month] + day + is_leap ) ;
- }
-
- /* c4ytoj - Calculates the number of days to the year */
- static long c4ytoj( int ) ;
-
- static long c4ytoj( int yr )
- {
- /*
- This calculation takes into account the fact that
- 1) Years divisible by 400 are always leap years.
- 2) Years divisible by 100 but not 400 are not leap years.
- 3) Otherwise, years divisible by four are leap years.
-
- Since we do not want to consider the current year, we will
- subtract the year by 1 before doing the calculation.
- */
-
- yr-- ;
- return( yr*365L + yr/4L - yr/100L + yr/400L ) ;
- }
-
-
- /* c4dt_julian
-
- Converts from database to index file date format.
-
- Can be used for checking the validity of a date.
-
- Returns
- 0 - Valid Date
- -1 - Illegal Date
- -2 - NULL Date (dbf_date is all blank; converts to 1.0E100)
- */
-
- int c4dt_julian( char *dbf_date, double *index_date)
- {
- int year, month, day, day_year ;
- long total ;
-
- /* A dBASE III index file date is stored as a julian day. That is the
- number of days since the date Jan 1, 4713 BC
- Ex. Jan 1, 1981 is 2444606
- */
-
- year = c4atoi( dbf_date, 4) ;
- if ( year == 0)
- {
- if ( memcmp( dbf_date, " ", 8 ) == 0)
- {
- *index_date = 1.0E100 ;
- return( -2) ;
- }
- }
-
- month = c4atoi( dbf_date+4, 2) ;
- day = c4atoi( dbf_date+6, 2) ;
-
- day_year = c4julian( year, month, day) ;
- if (day_year < 1) return( -1) ; /* Illegal Date */
-
- total = c4ytoj(year) ;
- total+= day_year ;
- total+= JULIAN_ADJUSTMENT ;
- *index_date = (double) total ;
-
- return( 0) ;
- }
-
-
- /* c4mon_dy
-
- Given the year and the day of the year, returns the
- month and day of month.
- */
- static int c4mon_dy( int, int, int *, int *) ;
-
- static int c4mon_dy( int year, int days, int *month_ptr, int *day_ptr )
- {
- int is_leap, i ;
-
- is_leap = ( year%4 == 0 && year%100 != 0 || year%400 == 0 ) ? 1 : 0 ;
- if ( days <= 59 ) is_leap = 0 ;
-
- for( i = 2; i <= 13; i++)
- {
- if ( days <= month_tot[i] + is_leap )
- {
- *month_ptr = --i ;
- if ( i <= 2) is_leap = 0 ;
-
- *day_ptr = days - month_tot[ i] - is_leap ;
- return( 0) ;
- }
- }
- *day_ptr = 0 ;
- *month_ptr = 0 ;
-
- return( -1 ) ;
- }
-
-
- /* c4dt_str
-
- Converts from the index file date format to the dbf file date format.
- */
-
- void c4dt_str( char *dbf_date, double *index_date)
- {
- int year, month, day, n_days, max_days ;
- long tot_days ;
-
- /* A dBASE III index file date is stored as a julian day. That is the
- number of days since the date Jan 1, 4713 BC
- Ex. Jan 1, 1981 is 2444606
- */
-
- if ( *index_date == 1.0E100 )
- {
- strcpy( dbf_date, " " ) ;
- return ;
- }
-
- tot_days = (long) (*index_date) - JULIAN_ADJUSTMENT ;
-
- year = (int) ((double)tot_days/365.2425) + 1 ;
- n_days = (int) (tot_days - c4ytoj(year)) ;
- if ( n_days <= 0 )
- {
- year-- ;
- n_days = (int) (tot_days - c4ytoj(year)) ;
- }
- if (year%4 == 0 && year%100 != 0 || year%400 == 0)
- max_days = 366 ;
- else
- max_days = 365 ;
-
- if ( n_days > max_days )
- {
- year++ ;
- n_days -= max_days ;
- }
-
- if ( c4mon_dy( year, n_days, &month, &day ) < 0 )
- u4error( E_INTERNAL,"C3DT_DBF", (char *) 0 ) ;
-
- c4ltoa( (long) year, dbf_date, -4 ) ;
- c4ltoa( (long) month, dbf_date+4, -2 ) ;
- c4ltoa( (long) day, dbf_date+6, -2 ) ;
- }
-
- #ifdef CLIPPER
- /* Numeric Key Database Output is Converted to Numeric Key Index File format */
- c4clip( char *ptr, int len)
- {
- int i, negative ;
- char *p ;
-
- for ( i= negative= 0, p= ptr; i< len; i++, p++ )
- {
- if ( *p == ' ' )
- {
- *p = '0' ;
- }
- else
- {
- if ( *p == '-' )
- {
- *p = '0' ;
- negative = 1 ;
- }
- else
- break ;
- }
- }
-
- if ( negative )
- {
- for ( i= 0, p= ptr; i< len; i++, p++ )
- *p = (char) 0x5c - *p ;
- }
-
- return 0 ;
- }
- #endif
-
- void c4trim_n( char *ptr, int num_chars )
- {
- int len ;
-
- if ( num_chars <= 0 ) return ;
-
- /* Count the Length */
- len = 0 ;
- while ( len< num_chars )
- {
- len++ ;
- if ( *ptr++ == '\000' ) break ;
- }
-
- if ( len < num_chars ) num_chars = len ;
-
-
- *(--ptr) = '\000' ;
-
- while( --num_chars >= 0 )
- {
- ptr-- ;
- if ( *ptr == '\000' || *ptr == ' ' )
- *ptr = '\000' ;
- else
- break ;
- }
-
- }
-