home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / EMXLIB8F.ZIP / EMX / LIB / TIME / STRFTIME.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-02  |  6.2 KB  |  261 lines

  1. /* strftime.c (emx+gcc) -- Copyright (c) 1992-1993 by Eberhard Mattes */
  2.  
  3. #include <sys/emx.h>
  4. #include <time.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. struct loc_date_time
  9. {
  10.   char *months1[12];
  11.   char *months2[12];
  12.   char *wdays1[7];
  13.   char *wdays2[7];
  14.   char *date_time_fmt;
  15.   char *date_fmt;
  16.   char *time_fmt;
  17.   char *am, *pm;
  18. };
  19.  
  20. static struct loc_date_time const def_loc =
  21. {
  22.   {
  23.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  24.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" },
  25.   {
  26.     "January", "February", "March", "April", "May", "June",
  27.     "July", "August", "September", "October", "November", "December" },
  28.   {
  29.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" },
  30.   {
  31.     "Sunday", "Monday", "Tuesday", "Wednesday",
  32.     "Thursday", "Friday", "Saturday" },
  33.   "%a %b %d %H:%M:%S %Y",
  34.   "%m/%d/%y",
  35.   "%H:%M:%S",
  36.   "AM", "PM"
  37.   };
  38.  
  39.  
  40.  
  41. static int ins (char *string, size_t *n, size_t size, const char *s,
  42.     size_t len);
  43. static int num2 (char *string, size_t *n, size_t size, int x);
  44. static int num3 (char *string, size_t *n, size_t size, int x);
  45. static int week (const struct tm *t, int first);
  46.  
  47. #define INS(STR,LEN) if (!ins (string, &n, size, (STR), (LEN))) return (0);
  48. #define NUM2(X) if (!num2 (string, &n, size, (X))) return (0);
  49. #define NUM3(X) if (!num3 (string, &n, size, (X))) return (0);
  50. #define FMT(F) \
  51.     i = strftime (string + n, size - n, (F), t); \
  52.     if (i == 0) \
  53.       return (0); \
  54.     else \
  55.       n += i;
  56. #define CHR(C) \
  57.     if (n < size) \
  58.       string[n++] = C; \
  59.     else \
  60.       return (0);
  61.  
  62.  
  63. static int ins (char *string, size_t *n, size_t size, const char *s,
  64.                 size_t len)
  65. {
  66.   size_t i;
  67.  
  68.   i = *n;
  69.   if (len < size - i)
  70.     {
  71.       memcpy (string + i, s, len);
  72.       *n += len;
  73.       return (1);
  74.     }
  75.   else
  76.     return (0);
  77. }
  78.  
  79.  
  80. static int num2 (char *string, size_t *n, size_t size, int x)
  81. {
  82.   int i;
  83.  
  84.   i = *n;
  85.   if (2 < size - i)
  86.     {
  87.       string[i++] = (char)('0' + (x / 10) % 10);
  88.       string[i++] = (char)('0' + (x % 10));
  89.       *n = i;
  90.       return (1);
  91.     }
  92.   else
  93.     return (0);
  94. }
  95.  
  96.  
  97. static int num3 (char *string, size_t *n, size_t size, int x)
  98. {
  99.   int i;
  100.  
  101.   i = *n;
  102.   if (3 < size - i)
  103.     {
  104.       string[i++] = (char)('0' + (x / 100) % 10);
  105.       string[i++] = (char)('0' + (x / 10) % 10);
  106.       string[i++] = (char)('0' + (x % 10));
  107.       *n = i;
  108.       return (1);
  109.     }
  110.   else
  111.     return (0);
  112. }
  113.  
  114.  
  115. static int week (const struct tm *t, int first)
  116. {
  117.   int wd, tmp;
  118.  
  119.   wd = t->tm_wday - first;    /* wd = relative day in week (w.r.t. first) */
  120.   if (wd < 0) wd += 7;
  121.   tmp = t->tm_yday - wd;      /* Start of current week */
  122.   if (tmp <= 0) return (0);   /* In partial first week */
  123.   return ((tmp + 6) / 7);     /* Week number */
  124. }
  125.  
  126.  
  127. size_t strftime (char *string, size_t size, const char *format,
  128.                  const struct tm *t)
  129. {
  130.   size_t i, n;
  131.   char *p, tmp[40];
  132.   const struct loc_date_time *lp;
  133.  
  134.   lp = &def_loc; n = 0;
  135.   while (*format != 0)
  136.     {
  137.       if (format[0] == '%')
  138.         {
  139.           ++format; p = NULL;
  140.           switch (*format)
  141.             {
  142.             case 0:
  143.             case '%':
  144.               CHR ('%');
  145.               if (*format == 0)
  146.                 --format;
  147.               break;
  148.             case 'a':
  149.               p = lp->wdays1[t->tm_wday];
  150.               INS (p, strlen (p));
  151.               break;
  152.             case 'A':
  153.               p = lp->wdays2[t->tm_wday];
  154.               INS (p, strlen (p));
  155.               break;
  156.             case 'b':
  157.             case 'h':
  158.               p = lp->months1[t->tm_mon];
  159.               INS (p, strlen (p));
  160.               break;
  161.             case 'B':
  162.               p = lp->months2[t->tm_mon];
  163.               INS (p, strlen (p));
  164.               break;
  165.             case 'c':
  166.               FMT (lp->date_time_fmt);
  167.               break;
  168.             case 'd':
  169.               NUM2 (t->tm_mday);
  170.               break;
  171.             case 'D':
  172.               FMT ("%m/%d/%y");
  173.               break;
  174.             case 'e':
  175.               NUM2 (t->tm_mday);
  176.               if (string[n-2] == '0')
  177.                 string[n-2] = ' ';
  178.               break;
  179.             case 'H':
  180.               NUM2 (t->tm_hour);
  181.               break;
  182.             case 'I':
  183.               NUM2 ((t->tm_hour + 11) % 12 + 1);
  184.               break;
  185.             case 'j':
  186.               NUM3 (t->tm_yday);
  187.               break;
  188.             case 'm':
  189.               NUM2 (t->tm_mon + 1);
  190.               break;
  191.             case 'M':
  192.               NUM2 (t->tm_min);
  193.               break;
  194.             case 'n':
  195.               CHR ('\n');
  196.               break;
  197.             case 'p':
  198.               p = (t->tm_hour >= 12 ? lp->pm : lp->am);
  199.               INS (p, strlen (p));
  200.               break;
  201.             case 'r':
  202.               FMT ("%I:%M:%S %p");
  203.               break;
  204.             case 'S':
  205.               NUM2 (t->tm_sec);
  206.               break;
  207.             case 't':
  208.               CHR ('\t');
  209.               break;
  210.             case 'T':
  211.               FMT ("%H:%M:%S");
  212.               break;
  213.             case 'U':
  214.               NUM2 (week (t, 0));
  215.               break;
  216.             case 'w':
  217.               NUM2 (t->tm_wday);
  218.               break;
  219.             case 'W':
  220.               NUM2 (week (t, 1));
  221.               break;
  222.             case 'x':
  223.               FMT (lp->date_fmt);
  224.               break;
  225.             case 'X':
  226.               FMT (lp->time_fmt);
  227.               break;
  228.             case 'y':
  229.               NUM2 (t->tm_year % 100);
  230.               break;
  231.             case 'Y':
  232.               p = _itoa (t->tm_year + 1900, tmp, 10);
  233.               INS (p, strlen (p));
  234.               break;
  235.             case 'Z':
  236.               if (!_tzset_flag) tzset ();
  237.               if (t->tm_isdst >= 0)
  238.                 {
  239.                   p = tzname[(t->tm_isdst ? 1 : 0)];
  240.                   INS (p, strlen (p));
  241.                 }
  242.               break;
  243.             default:
  244.               break;
  245.             }
  246.         }
  247.       else if (n < size)
  248.         string[n++] = *format;
  249.       else
  250.         return (0);
  251.       ++format;
  252.     }
  253.   if (n < size)
  254.     {
  255.       string[n] = 0;
  256.       return (n);
  257.     }
  258.   else
  259.     return (0);
  260. }
  261.