home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / 7plus202.zip / 7PL2SRC.LZH / UNIX.C < prev    next >
Text File  |  1992-06-11  |  14KB  |  515 lines

  1. /*--------------------------------*\
  2. | Additions for UNIX-compatibility |
  3. \*--------------------------------*/
  4. #ifdef __unix__
  5.  
  6.  #include "7plus.h"
  7.  
  8.  /*
  9.  * mktime function from GNU C library V1.03; modified:
  10.  * - expanded DEFUN and CONST macros from ansidecl.h
  11.  * - inserted __isleap macro from time.h
  12.  * - inserted __mon_lengths array and __offtime function from offtime.c
  13.  * - inserted gmtime function from gmtime.c
  14.  * - commented out call of localtime function
  15.  * Be aware of the following copyright message for mktime !!!
  16.  */
  17.  
  18.  /* Copyright (C) 1991 Free Software Foundation, Inc.
  19.  This file is part of the GNU C Library.
  20.  
  21.  The GNU C Library is free software; you can redistribute it and/or
  22.  modify it under the terms of the GNU Library General Public License as
  23.  published by the Free Software Foundation; either version 2 of the
  24.  License, or (at your option) any later version.
  25.  
  26.  The GNU C Library is distributed in the hope that it will be useful,
  27.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  28.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  29.  Library General Public License for more details.
  30.  
  31.  You should have received a copy of the GNU Library General Public
  32.  License along with the GNU C Library; see the file COPYING.LIB.  If
  33.  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  34.  Cambridge, MA 02139, USA.  */
  35.  
  36.  #include <errno.h>
  37.  #include <limits.h>
  38.  #include <time.h>
  39.  
  40.  
  41.  /* How many days are in each month.  */
  42.  const unsigned short int __mon_lengths[2][12] =
  43.    {
  44.      /* Normal years.  */
  45.      { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
  46.      /* Leap years.  */
  47.      { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
  48.    };
  49.  
  50.  #define  __isleap(year)  \
  51.    ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
  52.  
  53.  #define  invalid()  return (time_t) -1
  54.  
  55.  
  56.  #define  SECS_PER_HOUR  (60 * 60)
  57.  #define  SECS_PER_DAY  (SECS_PER_HOUR * 24)
  58.  
  59.  /* Returns the `struct tm' representation of *T,
  60.     offset OFFSET seconds east of UCT.  */
  61.  struct tm *
  62.  __offtime (const time_t *t, long int offset)
  63.  {
  64.    static struct tm tbuf;
  65.    register long int days, rem;
  66.    register int y;
  67.    register const unsigned short int *ip;
  68.  
  69.    if (t == NULL)
  70.      return NULL;
  71.  
  72.    days = *t / SECS_PER_DAY;
  73.    rem = *t % SECS_PER_DAY;
  74.    rem += offset;
  75.    while (rem < 0)
  76.    {
  77.      rem += SECS_PER_DAY;
  78.      --days;
  79.    }
  80.    while (rem >= SECS_PER_DAY)
  81.    {
  82.      rem -= SECS_PER_DAY;
  83.      ++days;
  84.    }
  85.    tbuf.tm_hour = rem / SECS_PER_HOUR;
  86.    rem %= SECS_PER_HOUR;
  87.    tbuf.tm_min = rem / 60;
  88.    tbuf.tm_sec = rem % 60;
  89.    /* January 1, 1970 was a Thursday.  */
  90.    tbuf.tm_wday = (4 + days) % 7;
  91.    if (tbuf.tm_wday < 0)
  92.      tbuf.tm_wday += 7;
  93.    y = 1970;
  94.    while (days >= (rem = __isleap(y) ? 366 : 365))
  95.    {
  96.      ++y;
  97.      days -= rem;
  98.    }
  99.    while (days < 0)
  100.    {
  101.      --y;
  102.      days += __isleap(y) ? 366 : 365;
  103.    }
  104.    tbuf.tm_year = y - 1900;
  105.    tbuf.tm_yday = days;
  106.    ip = __mon_lengths[__isleap(y)];
  107.    for (y = 0; days >= ip[y]; ++y)
  108.      days -= ip[y];
  109.    tbuf.tm_mon = y;
  110.    tbuf.tm_mday = days + 1;
  111.    tbuf.tm_isdst = -1;
  112.  
  113.    return &tbuf;
  114.  }
  115.  
  116.  
  117.  /* Return the `struct tm' representation of *T in UTC.  */
  118.  struct tm *
  119.  gmtime (const time_t *t)
  120.  {
  121.    return __offtime(t, 0L);
  122.  }
  123.  
  124.  
  125.  /* Return the `time_t' representation of TP and normalizes TP.
  126.     Return (time_t) -1 if TP is not representable as a `time_t'.
  127.     Note that 31 Dec 1969 23:59:59 is not representable
  128.     because it is represented as (time_t) -1.  */
  129.  time_t mktime (register struct tm *tp)
  130.  {
  131.    static struct tm min, max;
  132.    static char init = 0;
  133.  
  134.    register time_t result;
  135.    register time_t t;
  136.    register int i;
  137.    register const unsigned short *l;
  138.    register struct tm *new;
  139.    time_t end;
  140.  
  141.    if (tp == NULL)
  142.    {
  143.      errno = EINVAL;
  144.      invalid();
  145.    }
  146.  
  147.    if (!init)
  148.    {
  149.      init = 1;
  150.      end = (time_t) LONG_MIN;
  151.      new = gmtime(&end);
  152.      if (new != NULL)
  153.        min = *new;
  154.      else
  155.        min.tm_sec = min.tm_min = min.tm_hour =
  156.      min.tm_mday = min.tm_mon = min.tm_year = INT_MIN;
  157.  
  158.      end = (time_t) LONG_MAX;
  159.      new = gmtime(&end);
  160.      if (new != NULL)
  161.        max = *new;
  162.      else
  163.        max.tm_sec = max.tm_min = max.tm_hour =
  164.      max.tm_mday = max.tm_mon = max.tm_year = INT_MAX;
  165.    }
  166.  
  167.    /* Make all the elements of TP that we pay attention to
  168.       be within the ranges of reasonable values for those things.  */
  169.    #define  normalize(elt, min, max, nextelt)\
  170.    while (tp->elt < min)                     \
  171.    {                                         \
  172.      --tp->nextelt;                          \
  173.      tp->elt += max + 1;                     \
  174.    }                                         \
  175.    while (tp->elt > max)                     \
  176.    {                                         \
  177.      ++tp->nextelt;                          \
  178.      tp->elt -= max + 1;                     \
  179.    }
  180.  
  181.    normalize (tm_sec, 0, 59, tm_min);
  182.    normalize (tm_min, 0, 59, tm_hour);
  183.    normalize (tm_hour, 0, 24, tm_mday);
  184.  
  185.    /* Normalize the month first so we can use
  186.       it to figure the range for the day.  */
  187.    normalize (tm_mon, 0, 11, tm_year);
  188.    normalize (tm_mday, 1, __mon_lengths[__isleap (tp->tm_year)][tp->tm_mon],
  189.      tm_mon);
  190.  
  191.    /* Normalize the month again, since normalizing
  192.       the day may have pushed it out of range.  */
  193.    normalize (tm_mon, 0, 11, tm_year);
  194.  
  195.    /* Normalize the day again, because normalizing
  196.       the month may have changed the range.  */
  197.    normalize (tm_mday, 1, __mon_lengths[__isleap (tp->tm_year)][tp->tm_mon],
  198.      tm_mon);
  199.  
  200.   /* Check for out-of-range values.  */
  201.   #define  lowhigh(field, minmax, cmp)  (tp->field cmp minmax.field)
  202.   #define  low(field)                   lowhigh(field, min, <)
  203.   #define  high(field)                  lowhigh(field, max, >)
  204.   #define  oor(field)                   (low(field) || high(field))
  205.   #define  lowbound(field)              (tp->field == min.field)
  206.   #define  highbound(field)             (tp->field == max.field)
  207.   if (oor(tm_year))
  208.     invalid();
  209.   else
  210.     if (lowbound(tm_year))
  211.     {
  212.       if (low(tm_mon))
  213.         invalid();
  214.       else
  215.         if (lowbound(tm_mon))
  216.         {
  217.           if (low(tm_mday))
  218.             invalid();
  219.           else
  220.             if (lowbound(tm_mday))
  221.             {
  222.               if (low(tm_hour))
  223.                 invalid();
  224.               else
  225.                 if (lowbound(tm_hour))
  226.                 {
  227.                   if (low(tm_min))
  228.                     invalid();
  229.                   else
  230.                     if (lowbound(tm_min))
  231.                     {
  232.                       if (low(tm_sec))
  233.                       invalid();
  234.                     }
  235.                 }
  236.             }
  237.         }
  238.     }
  239.     else
  240.       if (highbound(tm_year))
  241.       {
  242.         if (high(tm_mon))
  243.           invalid();
  244.         else
  245.           if (highbound(tm_mon))
  246.           {
  247.             if (high(tm_mday))
  248.               invalid();
  249.             else
  250.               if (highbound(tm_mday))
  251.               {
  252.                 if (high(tm_hour))
  253.                   invalid();
  254.                 else
  255.                   if (highbound(tm_hour))
  256.                   {
  257.                     if (high(tm_min))
  258.                       invalid();
  259.                     else
  260.                       if (highbound(tm_min))
  261.                       {
  262.                         if (high(tm_sec))
  263.                         invalid();
  264.                       }
  265.                   }
  266.               }
  267.           }
  268.       }
  269.    t = 0;
  270.    for (i = 1970; i > 1900 + tp->tm_year; --i)
  271.      t -= __isleap(i) ? 366 : 365;
  272.    for (i = 1970; i < 1900 + tp->tm_year; ++i)
  273.      t += __isleap(i) ? 366 : 365;
  274.    l = __mon_lengths[__isleap(1900 + tp->tm_year)];
  275.    for (i = 0; i < tp->tm_mon; ++i)
  276.      t += l[i];
  277.    t += tp->tm_mday - 1;
  278.    result = ((t * 60 * 60 * 24) +
  279.             (tp->tm_hour * 60 * 60) +
  280.             (tp->tm_min * 60) +
  281.              tp->tm_sec);
  282.  
  283.    end = result;
  284.   #if 0
  285.    if (tp->tm_isdst < 0)
  286.      new = localtime(&end);
  287.    else
  288.   #endif
  289.      new = gmtime(&end);
  290.    if (new == NULL)
  291.      invalid();
  292.    new->tm_isdst = tp->tm_isdst;
  293.    *tp = *new;
  294.  
  295.    return result;
  296.  }
  297.  
  298.  #ifdef __vax__
  299.   char *strdup (const char *s1)
  300.   { char *s;
  301.  
  302.     s = malloc (strlen(s1) + 1);
  303.     strcpy (s , s1);
  304.     return (s);
  305.   }
  306.  #endif /* __vax__ */
  307.  
  308.  static int first = 1;
  309.  
  310.  int my_getch()
  311.  {
  312.    unsigned char c;
  313.    int fd;
  314.  
  315.    fd = fileno (stdin);
  316.    if (first)
  317.    {
  318.      first = 0;
  319.     #ifdef SYSV
  320.      (void) ioctl(fd, TCGETA, (char *) &sg[OFF]);
  321.     #else
  322.      (void) gtty(fd, &sg[OFF]);
  323.     #endif
  324.      sg[ON] = sg[OFF];
  325.  
  326.     #ifdef SYSV
  327.      sg[ON].c_lflag &= ~(ICANON|ECHO);
  328.      sg[ON].c_cc[VMIN] = 1;
  329.      sg[ON].c_cc[VTIME] = 0;
  330.     #else
  331.      sg[ON].sg_flags &= ~(ECHO | CRMOD);
  332.      sg[ON].sg_flags |= CBREAK;
  333.     #endif
  334.    }
  335.  
  336.   #ifdef SYSV
  337.    (void) ioctl(fd, TCSETAW, (char *) &sg[ON]);
  338.   #else
  339.    (void) stty(fd, &sg[ON]);
  340.   #endif
  341.  
  342.    read(fd, &c, 1);
  343.  
  344.   #ifdef SYSV
  345.    (void) ioctl(fd, TCSETAW, (char *) &sg[OFF]);
  346.   #else
  347.    (void) stty(fd, &sg[OFF]);
  348.   #endif
  349.  
  350.    return (int) c;
  351.  }
  352.  
  353.  #ifdef __i386__
  354.   #define MAXCMD 1024
  355.  
  356.   int rename (const char *s1, const char *s2)
  357.   {
  358.     char tmp[MAXCMD];
  359.  
  360.     (void) sprintf(tmp, "mv %s %s", s1, s2);
  361.     return (system(tmp));
  362.   }
  363.  
  364.   /*
  365.     strstr - public-domain implementation of standard C library function
  366.  
  367.     last edit:  02-Sep-1990  D A Gwyn
  368.  
  369.     This is an original implementation based on an idea by D M Sunday,
  370.     essentially the "quick search" algorithm described in CACM V33 N8.
  371.     Unlike Sunday's implementation, this one does not wander past the
  372.     ends of the strings (which can cause malfunctions under certain
  373.     circumstances), nor does it require the length of the searched
  374.     text to be determined in advance.  There are numerous other subtle
  375.     improvements too.  The code is intended to be fully portable, but in
  376.     environments that do not conform to the C standard, you should check
  377.     the sections below marked "configure as required".  There are also
  378.     a few compilation options, as follows:
  379.  
  380.     #define ROBUST  to obtain sane behavior when invoked with a null
  381.         pointer argument, at a miniscule cost in speed
  382.     #define ZAP  to use memset() to zero the shift[] array; this may
  383.         be faster in some implementations, but could fail on
  384.         unusual architectures
  385.     #define DEBUG  to enable assertions (bug detection)
  386.   */
  387.   #define ROBUST
  388.   #define ZAP
  389.  
  390.   #ifdef __STDC__
  391.    #include  <limits.h>    /* defines UCHAR_MAX */
  392.  
  393.    #ifdef ZAP
  394.     typedef void  *pointer;
  395.     extern pointer  memset( pointer, int, size_t );
  396.    #endif
  397.  
  398.   #else  /* normal UNIX-like C environment assumed; configure as required: */
  399.  
  400.    typedef unsigned  size_t;  /* type of result of sizeof */
  401.  
  402.    #ifndef NULL
  403.     #define  NULL    0    /* null pointer constant */
  404.    #endif
  405.  
  406.    #define  UCHAR_MAX  255    /* largest value of unsigned char */
  407.                               /* 255 @ 8 bits, 65535 @ 16 bits  */
  408.  
  409.    #ifdef ZAP
  410.     typedef char  *pointer;
  411.     extern pointer  memset();
  412.    #endif
  413.  
  414.    #define const  /* nothing */
  415.  
  416.   #endif  /* __STDC__ */
  417.  
  418.   #ifndef DEBUG
  419.    #define  NDEBUG
  420.   #endif
  421.  
  422.   #include <assert.h>
  423.  
  424.   typedef const unsigned char  cuc;  /* char variety used in algorithm */
  425.  
  426.   #define EOS  '\0'      /* C string terminator */
  427.  
  428.   char *          /* returns -> leftmost occurrence,
  429.                      or null pointer if not present */
  430.   strstr( s1, s2 )
  431.     const char  *s1;       /* -> string to be searched */
  432.     const char  *s2;       /* -> search-pattern string */
  433.   {
  434.     register cuc  *t;      /* -> text character being tested */
  435.     register cuc  *p;      /* -> pattern char being tested */
  436.     register cuc  *tx;     /* -> possible start of match */
  437.     register size_t  m;    /* -> length of pattern */
  438.     register cuc  *top;    /* -> high water mark in text */
  439.   #if UCHAR_MAX > 255      /* too large for auto allocation */
  440.     static        /* not malloc()ed; that can fail! */
  441.   #endif          /* else allocate shift[] on stack */
  442.       size_t  shift[UCHAR_MAX + 1];  /* pattern shift table */
  443.  
  444.   #ifdef ROBUST        /* not required by C standard */
  445.     if ( s1 == NULL || s2 == NULL )
  446.       return NULL;    /* certainly, no match is found! */
  447.   #endif
  448.  
  449.     /* Precompute shift intervals based on the pattern;
  450.        the length of the pattern is determined as a side effect: */
  451.  
  452.   #ifdef ZAP
  453.     (void)memset( (pointer)&shift[1], 0, UCHAR_MAX * sizeof(size_t) );
  454.   #else
  455.     {
  456.     register unsigned char  c;
  457.  
  458.     c = UCHAR_MAX;
  459.     do
  460.       shift[c] = 0;
  461.     while ( --c > 0 );
  462.     }
  463.   #endif /* ZAP */
  464.     /* Note: shift[0] is undefined at this point (fixed later). */
  465.  
  466.     for ( m = 1, p = (cuc *)s2; *p != EOS; ++m, ++p )
  467.       shift[(cuc)*p] = m;
  468.  
  469.     assert(s2[m - 1] == EOS);
  470.  
  471.     {
  472.     register unsigned char  c;
  473.  
  474.     c = UCHAR_MAX;
  475.     do
  476.       shift[c] = m - shift[c];
  477.     while ( --c > 0 );
  478.  
  479.     /* Note: shift[0] is still undefined at this point. */
  480.     }
  481.  
  482.     shift[0] = --m;    /* shift[EOS]; important details! */
  483.  
  484.     assert(s2[m] == EOS);
  485.  
  486.     /* Try to find the pattern in the text string: */
  487.  
  488.     for ( top = tx = (cuc *)s1; ; tx += shift[*(top = t)] )
  489.     {
  490.       for ( t = tx, p = (cuc *)s2; ; ++t, ++p )
  491.       {
  492.         if ( *p == EOS )       /* entire pattern matched */
  493.           return (char *)tx;
  494.  
  495.         if ( *p != *t )
  496.           break;
  497.       }
  498.  
  499.       if ( t < top )    /* idea due to ado@elsie.nci.nih.gov */
  500.         t = top;  /* already scanned this far for EOS */
  501.  
  502.       do
  503.       {
  504.         assert(m > 0);
  505.         assert(t - tx < m);
  506.  
  507.         if ( *t == EOS )
  508.           return NULL;  /* no match */
  509.       }
  510.       while ( ++t - tx != m );  /* < */
  511.     }
  512.   }
  513.  #endif /* __i386__ */
  514. #endif /* __unix__ */
  515.