home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / TIMEXSRC.ZIP / MISC.C < prev    next >
Text File  |  1990-03-29  |  13KB  |  678 lines

  1. /* misc.c -- Miscellaneous routines
  2.  
  3.         February 1990   Mark E. Mallett, Personal Workstation Magazine
  4.  
  5. This file contains misc routines for the TIMEX program.  Most, if not all,
  6. were lifted from code in previous columns.
  7.  
  8. Included are:
  9.  
  10.     atonum        Convert ASCII to LONG number
  11.         emalloc         malloc() with error message
  12.     erealloc    realloc() with error message.
  13.     error        Handle error message
  14.     getline        Input a line of text from a file.
  15.     gettkline    Input a line of text && tokenize it
  16.     nextonum    Convert ASCII hex to LONG number
  17.     prtdat        Print date
  18.     prtdtm        Print date and time
  19.     prttim        Print time
  20.     prtndat        Print date as a number string
  21.     prtndtm        Print date and time as a number string
  22.     prtntim        Print time as a number string
  23.     warning        Handle warning message.
  24.  
  25. */
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <malloc.h>
  30. #include <sys/types.h>
  31. #include <ctype.h>
  32. #include <time.h>
  33. #include <os2.h>
  34.  
  35. #include "timex.h"
  36.  
  37.  
  38. /* Local Definitions */
  39.  
  40. #ifndef NUL
  41. #define NUL     '\0'
  42. #endif  /* NUL */
  43.  
  44. /* External data referenced */
  45.  
  46.  
  47. /* External routines used */
  48.  
  49. extern  struct tm *xlocaltime( time_t * );
  50.  
  51. /* Local data publicly available */
  52.  
  53.  
  54. /* Local routines and forward references */
  55.  
  56.         LONG    atonum( char *bufP );
  57.         void    bufdat( char *bufP, time_t timeval );
  58.         void    bufdtm( char *bufP, time_t timeval );
  59.         void    buftim( char *bufP, time_t timeval );
  60.         int     getline( FILE *fP, char *bufP, int bufsize );
  61.         int     gettkline( FILE *fP, char *bufP, int bufsize,
  62.                                 int *tokCP, char **tokV, int tokmax );
  63.         LONG    hextonum( char *bufP );
  64.         void    prtdat( FILE *fP, time_t timeval );
  65.         void    prtdtm( FILE *fP, time_t timeval );
  66.         void    prtndat( FILE *fP, time_t timeval );
  67.         void    prtndtm( FILE *fP, time_t timeval );
  68.         void    prtntim( FILE *fP, time_t timeval );
  69.         void    prttim( FILE *fP, time_t timeval );
  70.  
  71. /* Private data */
  72.  
  73. static  char    Errbuf[100];            /* Scratch buffer for errors */
  74.  
  75. static    char    *Months[] = {
  76.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  77.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  78.                  };
  79.  
  80. /*
  81.  
  82. *//* atonum( bufP )
  83.  
  84.     Convert ASCII string to a LONG number
  85.  
  86. Accepts :
  87.  
  88.     bufP        Ptr to string
  89.  
  90. Returns :
  91.  
  92.     < value >    The number
  93.  
  94. Notes :
  95.  
  96.     knows about prefixes and suffixes, particularly K.
  97. */
  98.  
  99. LONG
  100. atonum( bufP )
  101.     char        *bufP;        /* The string */
  102. {
  103.     char        ch;        /* Next char */
  104.         int             neg;            /* Negative */
  105.     LONGINT        val;        /* Accumulated value */
  106.  
  107.     /* Check +/- */
  108.     neg = FALSE;
  109.     if ( *bufP == '+' )
  110.     ++bufP;
  111.     else if ( *bufP == '-' ) {
  112.     neg = TRUE;
  113.     ++bufP;
  114.     }
  115.  
  116.     /* Accumulate the value */
  117.     for( val = 0L; ( ch = *bufP++ ) != NUL; ) {
  118.     if ( !isdigit( ch ) )
  119.         break;
  120.     val = ( val * 10 ) + ( ch - '0' );
  121.     }
  122.  
  123.     /* Check suffix */
  124.     if ( ( ch == 'K' ) || ( ch == 'k' ) )
  125.         val = val * 1024;
  126.  
  127.     /* Apply sign if negative */
  128.     if ( neg )
  129.     val = val;
  130.  
  131.     return( val );
  132. }
  133. /*
  134.  
  135. *//* hextonum( bufP )
  136.  
  137.     Convert ASCII hex string to a LONG number
  138.  
  139. Accepts :
  140.  
  141.     bufP        Ptr to string
  142.  
  143. Returns :
  144.  
  145.     < value >    The number
  146.  
  147. */
  148.  
  149. LONG
  150. hextonum( bufP )
  151.     char        *bufP;        /* The string */
  152. {
  153.     char        ch;        /* Next char */
  154.     int        neg;        /* Negative */
  155.     LONGINT        val;        /* Accumulated value */
  156.  
  157.     /* Check +/- */
  158.     neg = FALSE;
  159.     if ( *bufP == '+' )
  160.     ++bufP;
  161.     else if ( *bufP == '-' ) {
  162.     neg = TRUE;
  163.     ++bufP;
  164.     }
  165.  
  166.     /* Accumulate the value */
  167.     for( val = 0L; ( ch = *bufP++ ) != NUL; ) {
  168.     if ( ( ch >= '0' ) && ( ch <= '9' ) )
  169.         ch -= '0';
  170.     else if ( ( ch >= 'a' ) && ( ch <= 'f' ) )
  171.         ch = ( ch - 'a' ) + 10;
  172.     else if ( ( ch >= 'A' ) && ( ch <= 'F' ) )
  173.         ch = ( ch - 'A' ) + 10;
  174.     else
  175.         break;
  176.  
  177.     val = ( val * 16 ) + ch;
  178.     }
  179.  
  180.     /* Apply sign if negative */
  181.     if ( neg )
  182.     val = val;
  183.  
  184.     return( val );
  185. }
  186. /*
  187.  
  188. *//* emalloc( facP, nameP, size )
  189.  
  190.     Allocate memory, give error if failure.
  191.  
  192. Accepts :
  193.  
  194.     facP        Name of facility (e.g., subroutine name)
  195.     nameP        Name of item being allocated
  196.     size        Desired size
  197.  
  198. Returns :
  199.  
  200.     < value >    Ptr to thing.
  201.  
  202. Notes :
  203.  
  204.     error return is taken if allocation fails.
  205. */
  206.  
  207. void *
  208. emalloc( facP, nameP, size )
  209.     char        *facP;        /* Ptr to facility name */
  210.     char        *nameP;        /* Ptr to name of thing */
  211.     int        size;        /* Number of bytes */
  212. {
  213.     char        *newP;        /* Ptr to memory */
  214.  
  215.     if ( ( newP = malloc( size ) ) == NULL )
  216.     error( EC_MEMORY, "%s: Error allocating %d bytes for %s",
  217.          facP, size, nameP );
  218.  
  219.     return( (void *)newP );
  220. }
  221. /*
  222.  
  223. *//* erealloc( facP, nameP, oldP, size )
  224.  
  225.     Reallocate memory, give error if failure.
  226.  
  227. Accepts :
  228.  
  229.     facP        Name of facility (e.g., subroutine name)
  230.     nameP        Name of item being allocated
  231.     oldP        Ptr to old thing (may be NULL)
  232.     size        Desired size
  233.  
  234. Returns :
  235.  
  236.     < value >    Ptr to thing.
  237.  
  238. Notes :
  239.  
  240.     error return is taken if allocation fails.
  241. */
  242.  
  243. void *
  244. erealloc( facP, nameP, oldP, size )
  245.     char        *facP;        /* Ptr to facility name */
  246.     char        *nameP;        /* Ptr to name of thing */
  247.     char        *oldP;        /* Ptr to existing thing */
  248.     int        size;        /* Number of bytes */
  249. {
  250.     char        *newP;        /* Ptr to memory */
  251.  
  252.     if ( oldP == NULL )
  253.     newP = malloc( size );
  254.     else
  255.     newP = realloc( oldP, size );
  256.  
  257.     if ( newP == NULL )
  258.     error( EC_MEMORY, "%s: Error re-allocating %d bytes for %s",
  259.          facP, size, nameP );
  260.  
  261.     return( (void *)newP );
  262. }
  263. /*
  264.  
  265. *//* gettkline( fP, bufP, bufsize, tokcP, tokv, tokmax )
  266.  
  267.     Input a line of text and tokenize it.
  268.  
  269. Accepts :
  270.  
  271.     fP        Stream for input file
  272.     bufP        Buffer for line
  273.     bufsize        Size of the buffer
  274.     tokcP        Ptr to tokc variable -- # of tokens
  275.     tokv        Ptr to tokv array -- ptrs to tokens
  276.     tokmax        Maximum number of tokens to return
  277.     
  278. Returns :
  279.  
  280.     <value>        Number of characters read (-1 if EOF)
  281.     *tokcP        Number of tokens received
  282.     *tokv        Ptrs to tokens
  283.  
  284. Notes :
  285.  
  286.     Excess input (up to a newline) is ignored.
  287.  
  288.     The line buffer is used for the token buffer as well.
  289.  
  290. */
  291.  
  292. int
  293. gettkline( fP, bufP, bufsize, tokcP, tokv, tokmax )
  294.     FILE        *fP;        /* Input file ptr */
  295.     char        *bufP;        /* Buffer ptr */
  296.     int        bufsize;    /* Room in buffer */
  297.     int        *tokcP;        /* Variable to hold token count */
  298.     char        **tokv;        /* Arg vectors */
  299.     int        tokmax;        /* Max # tokens */
  300. {
  301.     int        cC;        /* Characters */
  302.  
  303.     /* Input the line */
  304.     cC = getline( fP, ++bufP, bufsize-1 );
  305.  
  306.     /* Use tkline() to tokenize it */
  307.     *tokcP = tkline( bufP, bufP-1, tokv, tokmax, "", " \t,;:" );
  308.  
  309.     return( cC );
  310. }    
  311. /*
  312.  
  313. *//* getline( fP, bufP, bufsize )
  314.  
  315.     Inputs a line of text from a file.
  316.  
  317. Accepts :
  318.  
  319.     fP        Stream for input file
  320.     bufP        Buffer for line
  321.     bufsize        Size of the buffer
  322.     
  323. Returns :
  324.  
  325.     <value>        Number of characters read (-1 if EOF)
  326.  
  327. Notes :
  328.  
  329.     Excess input (up to a newline) is ignored.
  330.  
  331. */
  332.  
  333. getline( fP, bufP, bufsize )
  334.     FILE        *fP;        /* Input file ptr */
  335.     char        *bufP;        /* Buffer ptr */
  336.     int        bufsize;    /* Room in buffer */
  337. {
  338.     int        cC;        /* Characters */
  339.     int        ch;        /* Character */
  340.  
  341.     for( --bufsize, cC = 0; ( ( ch = getc( fP ) ) != '\n' ) && ( ch != EOF ); )
  342.     if ( cC < bufsize )
  343.             bufP[cC++] = (char)ch;
  344.  
  345.     bufP[cC] = NUL;
  346.     if ( ( cC == 0 ) && ( ch == EOF ) )
  347.     cC = -1;
  348.  
  349.     return( cC );
  350. }
  351. /*
  352.  
  353. *//* bufdtm( bufP, timeval )
  354.  
  355.         Print date and time of a time value into a buffer
  356.  
  357. Accepts :
  358.  
  359.         bufP            Destination buffer
  360.         timeval         Time value
  361.  
  362. Returns :
  363.  
  364.         <nothing>
  365.  
  366. */
  367.  
  368. void
  369. bufdtm( bufP, timeval )
  370.         char            *bufP;          /* Destination buffer */
  371.         time_t          timeval;        /* The time */
  372. {
  373.     bufdat( bufP, timeval );
  374.     bufP += strlen( bufP );
  375.     *bufP++ = ' ';
  376.     buftim( bufP, timeval );
  377. }
  378. /*
  379.  
  380. *//* bufdat( bufP, timeval )
  381.  
  382.         Print date portion of a time value into a buffer
  383.  
  384. Accepts :
  385.  
  386.         bufP            Destination buffer
  387.         timeval         Time value
  388.  
  389. Returns :
  390.  
  391.         <nothing>
  392.  
  393. */
  394.  
  395. void
  396. bufdat( bufP, timeval )
  397.         char            *bufP;          /* Buffer ptr */
  398.         time_t          timeval;        /* The time */
  399. {
  400.         struct tm       *tmP;           /* Time components struct */
  401.  
  402.     tmP = xlocaltime( &timeval );
  403.  
  404.     sprintf( bufP, "%02d-%s-%02d", tmP->tm_mday, Months[tmP->tm_mon],
  405.                                  tmP->tm_year + 1900 );
  406. }
  407. /*
  408.  
  409. *//* buftim( bufP, timeval )
  410.  
  411.         Print time portion of a time value into a buffer
  412.  
  413. Accepts :
  414.  
  415.         bufP            Destination buffer
  416.         timeval         Time value
  417.  
  418. Returns :
  419.  
  420.         <nothing>
  421.  
  422. */
  423.  
  424. void
  425. buftim( bufP, timeval )
  426.         char            *bufP;          /* Destination buffer */
  427.         time_t          timeval;        /* The time */
  428. {
  429.         struct tm       *tmP;           /* Time components struct */
  430.  
  431.     tmP = xlocaltime( &timeval );
  432.  
  433.     sprintf( bufP, "%02d:%02d:%02d", tmP->tm_hour, tmP->tm_min,
  434.                                    tmP->tm_sec );
  435. }
  436. /*
  437.  
  438. *//* prtdtm( fP, timeval )
  439.  
  440.     Print date and time of a time value
  441.  
  442. Accepts :
  443.  
  444.     fP        FILE block ptr
  445.     timeval        Time value
  446.  
  447. Returns :
  448.  
  449.     <nothing>
  450.  
  451. */
  452.  
  453. void
  454. prtdtm( fP, timeval )
  455.     FILE        *fP;        /* File to print to */
  456.     time_t        timeval;    /* The time */
  457. {
  458.     prtdat( fP, timeval );
  459.     fprintf( fP, " " );
  460.     prttim( fP, timeval );
  461. }
  462. /*
  463.  
  464. *//* prtdat( fP, timeval )
  465.  
  466.     Print date portion of a time value
  467.  
  468. Accepts :
  469.  
  470.     fP        FILE block ptr
  471.     timeval        Time value
  472.  
  473. Returns :
  474.  
  475.     <nothing>
  476.  
  477. */
  478.  
  479. void
  480. prtdat( fP, timeval )
  481.     FILE        *fP;        /* File to print to */
  482.     time_t        timeval;    /* The time */
  483. {
  484.     struct tm    *tmP;        /* Time components struct */
  485.  
  486.     tmP = xlocaltime( &timeval );
  487.  
  488.     fprintf( fP, "%02d-%s-%02d", tmP->tm_mday, Months[tmP->tm_mon],
  489.                  tmP->tm_year + 1900 );
  490. }
  491. /*
  492.  
  493. *//* prttim( fP, timeval )
  494.  
  495.     Print time portion of a time value
  496.  
  497. Accepts :
  498.  
  499.     fP        FILE block ptr
  500.     timeval        Time value
  501.  
  502. Returns :
  503.  
  504.     <nothing>
  505.  
  506. */
  507.  
  508. void
  509. prttim( fP, timeval )
  510.     FILE        *fP;        /* File to print to */
  511.     time_t        timeval;    /* The time */
  512. {
  513.     struct tm    *tmP;        /* Time components struct */
  514.  
  515.     tmP = xlocaltime( &timeval );
  516.  
  517.     fprintf( fP, "%02d:%02d:%02d", tmP->tm_hour, tmP->tm_min,
  518.                    tmP->tm_sec );
  519. }
  520. /*
  521.  
  522. *//* prtndtm( fP, timeval )
  523.  
  524.     Print date and time of a time value as a single number string
  525.  
  526. Accepts :
  527.  
  528.     fP        FILE block ptr
  529.     timeval        Time value
  530.  
  531. Returns :
  532.  
  533.     <nothing>
  534.  
  535. */
  536.  
  537. void
  538. prtndtm( fP, timeval )
  539.     FILE        *fP;        /* File to print to */
  540.     time_t        timeval;    /* The time */
  541. {
  542.     prtndat( fP, timeval );
  543.     prtntim( fP, timeval );
  544. }
  545. /*
  546.  
  547. *//* prtndat( fP, timeval )
  548.  
  549.     Print date portion of a time value as a single number string
  550.  
  551. Accepts :
  552.  
  553.     fP        FILE block ptr
  554.     timeval        Time value
  555.  
  556. Returns :
  557.  
  558.     <nothing>
  559.  
  560. Notes :
  561.  
  562.     Prints the date as yyyymmdd format
  563.  
  564. */
  565.  
  566. void
  567. prtndat( fP, timeval )
  568.     FILE        *fP;        /* File to print to */
  569.     time_t        timeval;    /* The time */
  570. {
  571.     struct tm    *tmP;        /* Time components struct */
  572.  
  573.     tmP = xlocaltime( &timeval );
  574.  
  575.     fprintf( fP, "%04d%02d%02d", tmP->tm_year + 1900, 
  576.                 tmP->tm_mon +1,
  577.                 tmP->tm_mday );
  578. }
  579. /*
  580.  
  581. *//* prtntim( fP, timeval )
  582.  
  583.     Print time portion of a time value as a digit string
  584.  
  585. Accepts :
  586.  
  587.     fP        FILE block ptr
  588.     timeval        Time value
  589.  
  590. Returns :
  591.  
  592.     <nothing>
  593.  
  594. Notes :
  595.  
  596.     Prints the time in hhmmss format
  597. */
  598.  
  599. void
  600. prtntim( fP, timeval )
  601.     FILE        *fP;        /* File to print to */
  602.     time_t        timeval;    /* The time */
  603. {
  604.     struct tm    *tmP;        /* Time components struct */
  605.  
  606.     tmP = xlocaltime( &timeval );
  607.  
  608.     fprintf( fP, "%02d%02d%02d", tmP->tm_hour, tmP->tm_min,
  609.                    tmP->tm_sec );
  610. }
  611. /*
  612.  
  613. *//* error( code, fmtP, args... )
  614.  
  615.     One-up interface to return_error
  616.  
  617. Accepts :
  618.  
  619.     code        Status code
  620.     fmtP        printf-style format string
  621.     args        printf arguments.  Quantity is limited.
  622.  
  623. Returns :
  624.  
  625.     Nothing.  Formats the string and calls return_error.
  626.  
  627. Notes :
  628.  
  629.     Handling of the arguments is kludgy.
  630.  
  631. */
  632.  
  633. void
  634. error( code, fmtP, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 )
  635.     int        code;        /* Status code */
  636.     char        *fmtP;        /* message format string */
  637.     int        a1, a2, a3,    /* Like I said... */
  638.             a4, a5, a6,    /*  ... it's a kludge. */
  639.             a7, a8, a9, a10;
  640. {
  641.     sprintf( &Errbuf[0], fmtP, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 );
  642.     return_error( code, &Errbuf[0] );
  643. }
  644. /*
  645.  
  646. *//* warning( code, fmtP, args... )
  647.  
  648.     Issue a warning (a la error(), but using note_error)
  649.  
  650. Accepts :
  651.  
  652.     code        Status code
  653.     fmtP        printf-style format string
  654.     args        printf arguments.  Quantity is limited.
  655.  
  656. Returns :
  657.  
  658.     Nothing; calls note_error and returns.
  659.  
  660. Notes :
  661.  
  662.     Handling of the arguments is kludgy.
  663.  
  664. */
  665.  
  666. void
  667. warning( code, fmtP, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 )
  668.     int        code;        /* Status code */
  669.     char        *fmtP;        /* message format string */
  670.     int        a1, a2, a3,    /* Like I said... */
  671.             a4, a5, a6,    /*  ... it's a kludge. */
  672.             a7, a8, a9, a10;
  673. {
  674.     sprintf( &Errbuf[0], fmtP, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 );
  675.  
  676.     note_error( code, &Errbuf[0] );
  677. }
  678.