home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / CODE4-1.ZIP / SOURCE.ZIP / C4.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-12  |  16.3 KB  |  779 lines

  1.  
  2. /*  c4.c   Conversion Routines
  3.        (c)Copyright Sequiter Software Inc., 1987, 1988, 1989.  All rights reserved.
  4. */
  5.  
  6. #include "d4base.h"
  7. #include <string.h>
  8. #include "u4error.h"
  9.  
  10. #include <ctype.h>
  11. #include <stdlib.h>
  12.  
  13. extern    INDEX    *v4index ;
  14.  
  15. #define  JULIAN_ADJUSTMENT    1721425L
  16.  
  17.  
  18. static    char  buffer[130] ;
  19. #ifdef GERMAN 
  20. static    char  month[][9]= { "         ",
  21.                 "Januar   ",
  22.                 "Februar  ",
  23.                 "Mrz     ",
  24.                 "April    ",
  25.                 "Mai      ",
  26.                 "Juni     ",
  27.                 "Juli     ",
  28.                 "August   ",
  29.                 "September",
  30.                 "Oktober  ",
  31.                 "November ",
  32.                 "Dezember "
  33.               } ;
  34.  
  35. #else
  36. static    char  month[][9]= { "         ",
  37.                 "January  ",
  38.                 "Febuary  ",
  39.                 "March    ",
  40.                 "April    ",
  41.                 "May      ",
  42.                 "June     ",
  43.                 "July     ",
  44.                 "August   ",
  45.                 "September",
  46.                 "October  ",
  47.                 "November ",
  48.                 "December "
  49.               } ;
  50. #endif
  51.  
  52. /*  c4dt_format
  53.  
  54.     Formats a date from   CCYYMMDD  (Century, Year, Month, Day)
  55.     format to any date format.
  56.  
  57.     The length of 'picture' must be 32 or less.
  58.  
  59.     If there are more than 2 'M' characters in the picture, the
  60.     month will be in character form.
  61. */
  62.  
  63. char  *c4dt_format( dbf_date,    picture )
  64. char    *dbf_date, *picture ;
  65. {
  66.    char *ptr, *ptr_end ;
  67.    int     rest, len, m_num    ;
  68.  
  69.    memset( buffer, (int) ' ', (size_t) sizeof(buffer) ) ;
  70.  
  71.    c4encode( buffer, dbf_date, picture, "CCYYMMDD") ;
  72.  
  73.    ptr_end  =  strchr( picture, 'M' ) ;
  74.    if ( ptr_end  !=  (char *) 0 )
  75.    {
  76.       ptr =  buffer+  (int) (ptr_end-picture) ;
  77.       len     =  0 ;
  78.       while ( *(ptr_end++) == 'M' )  len++ ;
  79.  
  80.       if ( len > 2)
  81.       {
  82.      /* Convert from a numeric form to character format for month */
  83.  
  84.      m_num =  c4atoi( dbf_date+4, 2) ;
  85.      if ( m_num < 0)  m_num =  1 ;
  86.      if ( m_num > 12) m_num = 12 ;
  87.  
  88.      rest =  len - 9 ;
  89.      if (len > 9) len = 9 ;
  90.  
  91.      memcpy( ptr, month[m_num], len ) ;
  92.      if (rest > 0)    memset( ptr+len, (int) ' ', (size_t) rest ) ;
  93.       }
  94.    }
  95.    return( buffer );
  96. }
  97.  
  98.  
  99. /* Converts from formatted Date Data into '.DBF' (CCYYMMDD) format */
  100.  
  101. char  *c4dt_unformat( date_data, picture )
  102. char    *date_data, *picture ;
  103. {
  104.    char  *month_start, month_data[10] ;
  105.    int     year_count, month_count, day_count, century_count, i, len ;
  106.  
  107.    day_count    =  5 ;
  108.    month_count    =  3 ;
  109.    year_count    =  1 ;
  110.    century_count= -1 ;
  111.  
  112.    memset( buffer, (int) ' ', (size_t) 8 ) ;
  113.    buffer[8] =    '\0' ;
  114.  
  115.    for ( i=0; picture[i] != '\0'; i++ )
  116.    {
  117.       switch( picture[i] )
  118.       {
  119.      case 'D':
  120.         if ( ++day_count >= 8) break ;
  121.         buffer[day_count] =  date_data[i] ;
  122.         break ;
  123.  
  124.      case 'M':
  125.         if ( ++month_count >=6) break ;
  126.         buffer[month_count] =  date_data[i] ;
  127.         break ;
  128.  
  129.      case 'Y':
  130.         if ( ++year_count >= 4) break ;
  131.         buffer[year_count] =  date_data[i] ;
  132.         break ;
  133.  
  134.      case 'C':
  135.         if ( ++century_count >= 2) break ;
  136.         buffer[century_count] =  date_data[i] ;
  137.         break ;
  138.       }
  139.    }
  140.  
  141.    if ( strcmp( buffer, "        " ) == 0 )  return( buffer ) ;
  142.  
  143.    if ( century_count ==  -1 )    memcpy( buffer,   "19", 2 ) ;
  144.    if ( year_count    ==   1 )    memcpy( buffer+2, "01", 2 ) ;
  145.    if ( month_count   ==   3 )    memcpy( buffer+4, "01", 2 ) ;
  146.    if ( day_count     ==   5 )    memcpy( buffer+6, "01", 2 ) ;
  147.  
  148.    if ( month_count >= 6 )
  149.    {
  150.       /* Convert the Month from Character Form to Date Format */
  151.       month_start =  strchr( picture, 'M' ) ;
  152.  
  153.       len =  month_count - 3 ;    /* Number of 'M' characters in picture */
  154.  
  155.       memcpy( buffer+4, "  ", 2 ) ;
  156.  
  157.       if ( len > 3 ) len = 3 ;
  158.       memcpy( month_data, date_data+ (int) (month_start-picture), len) ;
  159.       while ( len > 0 )
  160.      if ( month_data[len-1] == ' ' )
  161.         len-- ;
  162.      else
  163.         break ;
  164.  
  165.       month_data[len] =  '\0' ;
  166.  
  167.       strlwr( month_data ) ;
  168.       month_data[0] =  (char) toupper( (int) month_data[0] ) ;
  169.  
  170.       if ( len > 0 )
  171.      for( i=1; i<= 12; i++ )
  172.      {
  173.         if ( memcmp( month[i], month_data, len) == 0 )
  174.         {
  175.            c4ltoa( (long) i, buffer+4, 2 ) ;  /* Found Month Match */
  176.            break ;
  177.         }
  178.      }
  179.    }
  180.  
  181.    for ( i=0; i< 8; i++ )
  182.       if ( buffer[i] == ' ' )  buffer[i] =  '0' ;
  183.  
  184.    return ( buffer) ;
  185. }
  186.  
  187.  
  188. /* c4atod
  189.  
  190.    Converts a string to a double
  191. */
  192.  
  193. double c4atod( char_string, string_len )
  194. char   *char_string ;
  195. int    string_len  ;
  196. {
  197.    char buffer[50] ;
  198.    int    len ;
  199.  
  200.    len =  (string_len >= 50 )  ?  49 : string_len ;
  201.    memcpy( buffer, char_string, len ) ;
  202.    buffer[len] = '\0' ;
  203.  
  204.    return( strtod( buffer, (char **) 0)   ) ;
  205. }
  206.  
  207. /* c4atoi.c  */
  208.  
  209. int c4atoi(ptr,  n)
  210. char * ptr ; int n  ;
  211. {
  212.    char buf[128] ;
  213.    if ( n >= sizeof(buf) )  n= sizeof(buf) -1 ;
  214.    memcpy(buf, ptr, n) ;
  215.    buf[n] = '\0' ;
  216.    return (atoi(buf) ) ;
  217. }
  218.  
  219. /* c4atol  */
  220.  
  221. long c4atol(ptr,  n)
  222. char * ptr ; int n  ;
  223. {
  224.    char buf[128] ;
  225.    if ( n >= sizeof(buf) )  n= sizeof(buf) -1 ;
  226.    memcpy(buf, ptr, n) ;
  227.    buf[n] = '\0' ;
  228.    return (atol(buf) ) ;
  229. }
  230.  
  231. /*  c4ltoa
  232.  
  233.     Converts a RECNUM to a string.  Fill with '0's rather than blanks if
  234.     'num' is less than zero.
  235. */
  236.  
  237. char *c4ltoa(l_val, ptr, num)    /* num <0;  0 filled */
  238. long  l_val ;
  239. char *ptr ;
  240. int   num ;
  241. {
  242.    int     n, num_pos ;
  243.    long  i_long ;
  244.  
  245.    i_long =  (l_val>0) ? l_val : -l_val ;
  246.    num_pos =  n =  (num > 0) ? num : -num ;
  247.  
  248.    while (n-- > 0)
  249.    {
  250.       ptr[n] = (char) ('0'+ i_long%10) ;
  251.       i_long = i_long/10 ;
  252.    }
  253.  
  254.    if ( i_long > 0 )
  255.    {
  256.      memset( ptr, (int) '*', (size_t) num_pos ) ;
  257.      return ptr ;
  258.    }
  259.  
  260.    num--;
  261.    for (n=0; n<num; n++)
  262.       if (ptr[n]=='0')
  263.      ptr[n]= ' ';
  264.       else
  265.      break ;
  266.  
  267.    if (l_val < 0)
  268.    {
  269.       if ( ptr[0] != ' ' )
  270.       {
  271.      memset( ptr, (int) '*', (size_t) num_pos ) ;
  272.      return ptr ;
  273.       }
  274.       for (n=num; n>=0; n--)
  275.      if (ptr[n]==' ')
  276.      {
  277.         ptr[n]= '-' ;
  278.         break ;
  279.      }
  280.    }
  281.  
  282.    return(ptr) ;
  283. }
  284.  
  285.  
  286. /* c4encode
  287.  
  288.    - From CCYYMMDD to CCYY.MM.DD
  289.  
  290.    Ex.    c4encode( to, from, "CCYY.MM.DD", "CCYYMMDD" ) ;
  291. */
  292.  
  293. void  c4encode( to, from, t_to, t_from)
  294. char *to, *from, *t_to, *t_from ;
  295. {
  296.    int    pos ;
  297.    char chr ;
  298.    char * chr_pos ;
  299.  
  300.    strcpy( to, t_to ) ;
  301.  
  302.    while ( (chr=*t_from++)  != 0)
  303.    {
  304.       if (  (chr_pos= strchr(t_to,chr)) ==0)
  305.       {
  306.      from++;
  307.      continue ;
  308.       }
  309.  
  310.       pos = (int) (chr_pos - t_to) ;
  311.       to[pos++] = *from++ ;
  312.  
  313.       while (chr== *t_from)
  314.       {
  315.      if (chr== t_to[pos])
  316.         to[pos++] = *from ;
  317.      t_from++ ;
  318.      from++ ;
  319.       }
  320.    }
  321. }
  322.  
  323. /* c4dtoa( doub_val, len, dec)
  324.  
  325.    - formats a double to a string
  326.    - if there is an overflow, '*' are returned
  327.  
  328.    Return
  329.  
  330.       Pointer to the Formatted String
  331. */
  332.  
  333. extern char  *fcvt() ;
  334.  
  335. char * c4dtoa( doub_val, len, dec)
  336. double doub_val ;
  337. int    len, dec ;
  338. {
  339.    int     dec_val, sign_val ;
  340.    int     pre_len, post_len, sign_pos ; /* pre and post decimal point lengths */
  341.    char *result, *out_string ;
  342.  
  343.    if ( len < 0 )    len = -len  ;
  344.    if ( len > 128 )  len =  128 ;
  345.  
  346.    memset( buffer, (int) '0', (size_t) len) ;
  347.    out_string =  buffer ;
  348.  
  349.    if (dec > 0)
  350.    {
  351.       post_len =  dec ;
  352.       if (post_len > 15)     post_len =  15 ;
  353.       if (post_len > len-1)  post_len =  len-1 ;
  354.       pre_len  =  len -post_len -1 ;
  355.  
  356.       out_string[ pre_len] = '.' ;
  357.    }
  358.    else
  359.    {
  360.       pre_len  =  len ;
  361.       post_len = 0 ;
  362.    }
  363.  
  364.    result =  fcvt( doub_val, post_len, &dec_val, &sign_val) ;
  365.  
  366.    if (dec_val > 0)
  367.       sign_pos =   pre_len-dec_val -1 ;
  368.    else
  369.    {
  370.       sign_pos =   pre_len - 2 ;
  371.       if ( pre_len == 1) sign_pos = 0 ;
  372.    }
  373.  
  374.    if ( dec_val > pre_len ||  pre_len<0  ||  sign_pos< 0 && sign_val)
  375.    {
  376.       /* overflow */
  377.       memset( out_string, (int) '*', (size_t) len) ;
  378.       return( buffer) ;
  379.    }
  380.  
  381.    if (dec_val > 0)
  382.    {
  383.       memset( out_string, (int) ' ', (size_t) pre_len- dec_val) ;
  384.       memmove( out_string+ pre_len- dec_val, result, dec_val) ;
  385.    }
  386.    else
  387.    {
  388.       if (pre_len> 0)  memset( out_string, (int) ' ', (size_t) (pre_len-1)) ;
  389.    }
  390.    if ( sign_val)  out_string[sign_pos] = '-' ;
  391.  
  392.  
  393.    out_string += pre_len+1 ;
  394.    if (dec_val >= 0)
  395.    {
  396.       result+= dec_val ;
  397.    }
  398.    else
  399.    {
  400.       out_string    -= dec_val ;
  401.       post_len += dec_val ;
  402.    }
  403.  
  404.    if ( post_len > strlen(result) )
  405.       post_len =  strlen( result) ;
  406.  
  407.    /*  - out_string   points to where the digits go to
  408.        - result       points to where the digits are to be copied from
  409.        - post_len     is the number to be copied
  410.    */
  411.  
  412.    if (post_len > 0)   memmove( out_string, result, post_len) ;
  413.  
  414.    buffer[len] =  '\0' ;
  415.  
  416.    return( buffer ) ;
  417. }
  418.  
  419.  
  420. extern double floor( double ) ;
  421.  
  422. /*  static c4julian
  423.  
  424.        Returns an (int) day of the year starting from 1.
  425.        Ex.    Jan 1, returns  1
  426.  
  427.        Returns    -1  if it is an illegal date.
  428.  
  429. */
  430.  
  431. static int  month_tot[]=
  432.     { 0, 0,  31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 } ;
  433.      /* Jan Feb Mar  Apr  May  Jun    Jul  Aug  Sep  Oct  Nov  Dec
  434.          31  28  31   30   31   30     31   31   30    31   30   31
  435.      */
  436.  
  437. int c4julian( year, month, day )
  438. int year, month, day ;
  439. {
  440.    int    is_leap, month_days ;
  441.  
  442.    is_leap =   ( year%4 == 0 && year%100 != 0 || year%400 == 0 ) ?  1 : 0 ;
  443.  
  444.    month_days =  month_tot[ month+1 ] -  month_tot[ month] ;
  445.    if ( month == 2 )  month_days += is_leap ;
  446.  
  447.    if ( year  < 0  ||
  448.     month < 1  ||  month > 12  ||
  449.     day   < 1  ||  day   > month_days )
  450.     return( -1 ) ;    /* Illegal Date */
  451.  
  452.    if ( month <= 2 )  is_leap = 0 ;
  453.  
  454.    return(  month_tot[month] + day + is_leap ) ;
  455. }
  456.  
  457. /*   c4ytoj -  Calculates the number of days to the year */
  458. static long  c4ytoj( int ) ;
  459.  
  460. static long  c4ytoj( yr )
  461. int yr ;
  462. {
  463.    /*
  464.        This calculation takes into account the fact that
  465.       1)  Years divisible by 400 are always leap years.
  466.       2)  Years divisible by 100 but not 400 are not leap years.
  467.       3)  Otherwise, years divisible by four are leap years.
  468.  
  469.        Since we do not want to consider the current year, we will
  470.        subtract the year by 1 before doing the calculation.
  471.    */
  472.  
  473.    yr-- ;
  474.    return( yr*365L +  yr/4L - yr/100L + yr/400L ) ;
  475. }
  476.  
  477.  
  478. /*   c4dt_index
  479.  
  480.      Converts from database to index file date format.
  481.  
  482.      Can be used for checking the validity of a date.
  483.  
  484.      Returns
  485.     0 -  Valid Date
  486.        -1 -  Illegal Date
  487.        -2 -  NULL Date (dbf_date is all blank; converts to 1.0E100)
  488. */
  489.  
  490. int  c4dt_index( dbf_date, index_date)
  491. char    dbf_date[8] ;
  492. double *index_date  ;
  493. {
  494.    int     year, month, day, day_year ;
  495.    long  total ;
  496.  
  497.    /* A dBASE III index file date is stored as a julian day.  That is the
  498.       number of days since the date  Jan 1, 4713 BC
  499.       Ex.  Jan 1, 1981 is  2444606
  500.    */
  501.  
  502.    year   =  c4atoi( dbf_date,     4) ;
  503.    if ( year == 0)
  504.    {
  505.       if ( memcmp( dbf_date, "        ", 8 ) == 0)
  506.       {
  507.     *index_date =  1.0E100 ;
  508.      return( -2) ;
  509.       }
  510.    }
  511.  
  512.    month  =  c4atoi( dbf_date+4, 2) ;
  513.    day      =  c4atoi( dbf_date+6, 2) ;
  514.  
  515.    day_year    =  c4julian( year, month, day) ;
  516.    if (day_year < 1)  return( -1) ;  /* Illegal Date */
  517.  
  518.    total =  c4ytoj(year) ;
  519.    total+=  day_year ;
  520.    total+=  JULIAN_ADJUSTMENT ;
  521.   *index_date  = (double) total ;
  522.  
  523.    return( 0) ;
  524. }
  525.  
  526.  
  527. /* c4key */
  528.  
  529. void c4key( in_key, out_str, type_key )
  530. char *in_key, *out_str, type_key ;
  531. {
  532.    #ifdef CLIPPER
  533.       int   negative, i ;
  534.       char *ptr ;
  535.  
  536.       strncpy( out_str, in_key, 64 ) ;
  537.       out_str[63] =  '\0' ;
  538.  
  539.       if ( type_key == 'N' || type_key == 'F' )
  540.       {
  541.      ptr      =  out_str ;
  542.      negative =  0 ;
  543.  
  544.      if ( *ptr < '0' )
  545.      {
  546.         negative = 1 ;
  547.         while (*ptr != '\0' )
  548.         {
  549.            *ptr =  0x5c -  *ptr ;
  550.            ptr++ ;
  551.         }
  552.         ptr =  out_str ;
  553.      }
  554.  
  555.      while (*ptr == '0')  *ptr++ =  ' ' ;
  556.      ptr-- ;
  557.      if (ptr[1] == '\0' || ptr[1] == '.' )
  558.      {
  559.         if ( ptr >= out_str )   *ptr =  '0' ;
  560.      }
  561.      if ( negative )
  562.      {
  563.         ptr-- ;
  564.         if ( ptr >= out_str )   *ptr =  '-' ;
  565.      }
  566.       }
  567.    #else
  568.       char *ptr ;
  569.       int   len ;
  570.  
  571.       if ( in_key == (char *) 0  ||  out_str == (char *) 0 ) return ;
  572.  
  573.       if ( type_key == 'C' )   strncpy( out_str, in_key, 64 ) ;
  574.       if ( type_key == 'D' )
  575.       {
  576.      c4dt_dbf( out_str, (double *) in_key ) ;
  577.      out_str[8] = '\0' ;
  578.       }
  579.  
  580.       if ( type_key == 'N' || type_key == 'F' )
  581.       {
  582.      ptr  =  c4dtoa( *((double *)in_key), 34, 16 ) ;
  583.      len   =  strlen( ptr ) ;
  584.      while ( ptr[--len] == '0' ) if (len>=0) ptr[len] = '\0' ;
  585.      while ( *ptr == ' ' ) ptr++ ;
  586.      strcpy( out_str, ptr ) ;
  587.       }
  588.    #endif
  589.  
  590.    return ;
  591. }
  592.  
  593.  
  594. /*  c4mon_dy
  595.  
  596.        Given the year and the day of the year, returns the
  597.     month and day of month.
  598. */
  599. static  int    c4mon_dy( int, int, int *, int *) ;
  600.  
  601. static int  c4mon_dy( year, days,  month_ptr,  day_ptr )
  602. int  year, days, *month_ptr, *day_ptr ;
  603. {
  604.    int is_leap, i ;
  605.  
  606.    is_leap =  ( year%4 == 0 && year%100 != 0 || year%400 == 0 ) ?  1 : 0 ;
  607.    if ( days <= 59 )  is_leap = 0 ;
  608.  
  609.    for( i = 2; i <= 13; i++)
  610.    {
  611.       if ( days <=  month_tot[i] + is_leap )
  612.       {
  613.      *month_ptr =  --i ;
  614.      if ( i <= 2) is_leap = 0 ;
  615.  
  616.      *day_ptr   =  days - month_tot[ i] - is_leap ;
  617.      return( 0) ;
  618.       }
  619.    }
  620.    *day_ptr   =  0 ;
  621.    *month_ptr =  0 ;
  622.  
  623.    return( -1 ) ;
  624. }
  625.  
  626.  
  627. /*   c4dt_dbf
  628.  
  629.      Converts from the index file date format to the dbf file date format.
  630. */
  631.  
  632. void  c4dt_dbf( dbf_date, index_date)
  633. char    dbf_date[8] ;
  634. double *index_date  ;
  635. {
  636.    int     year, month, day, n_days, max_days ;
  637.    long  tot_days ;
  638.  
  639.    /* A dBASE III index file date is stored as a julian day.  That is the
  640.       number of days since the date  Jan 1, 4713 BC
  641.       Ex.  Jan 1, 1981 is  2444606
  642.    */
  643.  
  644.    if ( *index_date == 1.0E100 )
  645.    {
  646.       strcpy( dbf_date, "        " ) ;
  647.       return ;
  648.    }
  649.  
  650.    tot_days    =  (long) (*index_date) - JULIAN_ADJUSTMENT ;
  651.  
  652.    year        =  (int) ((double)tot_days/365.2425) + 1 ;
  653.    n_days      =  (int) (tot_days -  c4ytoj(year)) ;
  654.    if ( n_days <= 0 )
  655.    {
  656.       year-- ;
  657.       n_days   =  (int) (tot_days - c4ytoj(year)) ;
  658.    }
  659.    if (year%4 == 0 && year%100 != 0 || year%400 == 0)
  660.       max_days =  366 ;
  661.    else
  662.       max_days =  365 ;
  663.  
  664.    if ( n_days > max_days )
  665.    {
  666.       year++ ;
  667.       n_days -= max_days ;
  668.    }
  669.  
  670.    if ( c4mon_dy( year, n_days, &month, &day ) < 0 )
  671.     u4error( E_INTERNAL,"C3DT_DBF", (char *) 0 ) ;
  672.  
  673.    c4ltoa( (long) year,  dbf_date,   -4 ) ;
  674.    c4ltoa( (long) month, dbf_date+4, -2 ) ;
  675.    c4ltoa( (long) day,     dbf_date+6, -2 ) ;
  676. }
  677.  
  678.  
  679. /* Conversion from Double to format suitable for Index File Search
  680.  
  681.    Parameters:
  682.  
  683.    index_ref -    A reference to the Index File
  684.    doub_val  -    The key to search for.
  685.    key_val   -    A pointer to a character buffer to store the converted
  686.         result.  The buffer length should be greater than the
  687.         index file key length. (32 characters should do it !) .
  688. */
  689.  
  690. c4dtok( index_ref, doub_val, key_val )
  691. int    index_ref ;
  692. double    doub_val ;
  693. char   *key_val ;
  694. {
  695.    #ifdef CLIPPER
  696.       INDEX *index_ptr ;
  697.       char  *ptr ;
  698.       index_ptr =  v4index + index_ref ;
  699.       if ( index_ptr->key_len > 31 )   return -1 ;
  700.       ptr =  c4dtoa( doub_val, index_ptr->key_len, index_ptr->key_dec ) ;
  701.       memcpy( key_val, ptr, index_ptr->key_len ) ;
  702.       c4clip( key_val, index_ptr->key_len ) ;
  703.    #else
  704.       *((double *)key_val) =  doub_val ;  /* No translation for dBASE */
  705.    #endif
  706.    return 0 ;
  707. }
  708.  
  709.  
  710. #ifdef CLIPPER
  711.  
  712. /* Numeric Key Database Output is Converted to Numeric Key Index File format */
  713. c4clip(ptr, len)
  714. char *ptr ;
  715. int   len ;
  716. {
  717.    int     i, negative ;
  718.    char *p ;
  719.  
  720.    for ( i= negative= 0, p= ptr; i< len; i++, p++ )
  721.    {
  722.       if ( *p == ' ' )
  723.       {
  724.      *p =  '0' ;
  725.       }
  726.       else
  727.       {
  728.      if ( *p == '-' )
  729.      {
  730.         *p =  '0' ;
  731.         negative =    1 ;
  732.      }
  733.      else
  734.         break ;
  735.       }
  736.    }
  737.  
  738.    if ( negative )
  739.    {
  740.       for ( i= 0, p= ptr; i< len; i++, p++ )
  741.      *p =  0x5c - *p ;
  742.    }
  743.  
  744.    return 0 ;
  745. }
  746. #endif
  747.  
  748.  
  749. void c4trim_n( ptr, num_chars )
  750. char *ptr ;
  751. int   num_chars ;
  752. {
  753.    int    len ;
  754.  
  755.    if ( num_chars <= 0 )  return ;
  756.  
  757.    /* Count the Length */
  758.    len =  0 ;
  759.    while ( len< num_chars )
  760.    {
  761.       len++ ;
  762.       if ( *ptr++ == '\0' )  break ;
  763.    }
  764.  
  765.    if ( len < num_chars )  num_chars =    len ;
  766.  
  767.  
  768.    *(--ptr) =  '\0' ;
  769.  
  770.    while( --num_chars >= 0 )
  771.    {
  772.       ptr-- ;
  773.       if ( *ptr == '\0' ||  *ptr == ' ' )
  774.      *ptr =  '\0' ;
  775.       else
  776.      break ;
  777.    }
  778. }
  779.