home *** CD-ROM | disk | FTP | other *** search
- /* strftime.c (emx+gcc) -- Copyright (c) 1992-1993 by Eberhard Mattes */
-
- #include <sys/emx.h>
- #include <time.h>
- #include <stdlib.h>
- #include <string.h>
-
- struct loc_date_time
- {
- char *months1[12];
- char *months2[12];
- char *wdays1[7];
- char *wdays2[7];
- char *date_time_fmt;
- char *date_fmt;
- char *time_fmt;
- char *am, *pm;
- };
-
- static struct loc_date_time const def_loc =
- {
- {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" },
- {
- "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December" },
- {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" },
- {
- "Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday" },
- "%a %b %d %H:%M:%S %Y",
- "%m/%d/%y",
- "%H:%M:%S",
- "AM", "PM"
- };
-
-
-
- static int ins (char *string, size_t *n, size_t size, const char *s,
- size_t len);
- static int num2 (char *string, size_t *n, size_t size, int x);
- static int num3 (char *string, size_t *n, size_t size, int x);
- static int week (const struct tm *t, int first);
-
- #define INS(STR,LEN) if (!ins (string, &n, size, (STR), (LEN))) return (0);
- #define NUM2(X) if (!num2 (string, &n, size, (X))) return (0);
- #define NUM3(X) if (!num3 (string, &n, size, (X))) return (0);
- #define FMT(F) \
- i = strftime (string + n, size - n, (F), t); \
- if (i == 0) \
- return (0); \
- else \
- n += i;
- #define CHR(C) \
- if (n < size) \
- string[n++] = C; \
- else \
- return (0);
-
-
- static int ins (char *string, size_t *n, size_t size, const char *s,
- size_t len)
- {
- size_t i;
-
- i = *n;
- if (len < size - i)
- {
- memcpy (string + i, s, len);
- *n += len;
- return (1);
- }
- else
- return (0);
- }
-
-
- static int num2 (char *string, size_t *n, size_t size, int x)
- {
- int i;
-
- i = *n;
- if (2 < size - i)
- {
- string[i++] = (char)('0' + (x / 10) % 10);
- string[i++] = (char)('0' + (x % 10));
- *n = i;
- return (1);
- }
- else
- return (0);
- }
-
-
- static int num3 (char *string, size_t *n, size_t size, int x)
- {
- int i;
-
- i = *n;
- if (3 < size - i)
- {
- string[i++] = (char)('0' + (x / 100) % 10);
- string[i++] = (char)('0' + (x / 10) % 10);
- string[i++] = (char)('0' + (x % 10));
- *n = i;
- return (1);
- }
- else
- return (0);
- }
-
-
- static int week (const struct tm *t, int first)
- {
- int wd, tmp;
-
- wd = t->tm_wday - first; /* wd = relative day in week (w.r.t. first) */
- if (wd < 0) wd += 7;
- tmp = t->tm_yday - wd; /* Start of current week */
- if (tmp <= 0) return (0); /* In partial first week */
- return ((tmp + 6) / 7); /* Week number */
- }
-
-
- size_t strftime (char *string, size_t size, const char *format,
- const struct tm *t)
- {
- size_t i, n;
- char *p, tmp[40];
- const struct loc_date_time *lp;
-
- lp = &def_loc; n = 0;
- while (*format != 0)
- {
- if (format[0] == '%')
- {
- ++format; p = NULL;
- switch (*format)
- {
- case 0:
- case '%':
- CHR ('%');
- if (*format == 0)
- --format;
- break;
- case 'a':
- p = lp->wdays1[t->tm_wday];
- INS (p, strlen (p));
- break;
- case 'A':
- p = lp->wdays2[t->tm_wday];
- INS (p, strlen (p));
- break;
- case 'b':
- case 'h':
- p = lp->months1[t->tm_mon];
- INS (p, strlen (p));
- break;
- case 'B':
- p = lp->months2[t->tm_mon];
- INS (p, strlen (p));
- break;
- case 'c':
- FMT (lp->date_time_fmt);
- break;
- case 'd':
- NUM2 (t->tm_mday);
- break;
- case 'D':
- FMT ("%m/%d/%y");
- break;
- case 'e':
- NUM2 (t->tm_mday);
- if (string[n-2] == '0')
- string[n-2] = ' ';
- break;
- case 'H':
- NUM2 (t->tm_hour);
- break;
- case 'I':
- NUM2 ((t->tm_hour + 11) % 12 + 1);
- break;
- case 'j':
- NUM3 (t->tm_yday);
- break;
- case 'm':
- NUM2 (t->tm_mon + 1);
- break;
- case 'M':
- NUM2 (t->tm_min);
- break;
- case 'n':
- CHR ('\n');
- break;
- case 'p':
- p = (t->tm_hour >= 12 ? lp->pm : lp->am);
- INS (p, strlen (p));
- break;
- case 'r':
- FMT ("%I:%M:%S %p");
- break;
- case 'S':
- NUM2 (t->tm_sec);
- break;
- case 't':
- CHR ('\t');
- break;
- case 'T':
- FMT ("%H:%M:%S");
- break;
- case 'U':
- NUM2 (week (t, 0));
- break;
- case 'w':
- NUM2 (t->tm_wday);
- break;
- case 'W':
- NUM2 (week (t, 1));
- break;
- case 'x':
- FMT (lp->date_fmt);
- break;
- case 'X':
- FMT (lp->time_fmt);
- break;
- case 'y':
- NUM2 (t->tm_year % 100);
- break;
- case 'Y':
- p = _itoa (t->tm_year + 1900, tmp, 10);
- INS (p, strlen (p));
- break;
- case 'Z':
- if (!_tzset_flag) tzset ();
- if (t->tm_isdst >= 0)
- {
- p = tzname[(t->tm_isdst ? 1 : 0)];
- INS (p, strlen (p));
- }
- break;
- default:
- break;
- }
- }
- else if (n < size)
- string[n++] = *format;
- else
- return (0);
- ++format;
- }
- if (n < size)
- {
- string[n] = 0;
- return (n);
- }
- else
- return (0);
- }
-