123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /*
- * strftime - convert a structure to a string, controlled by an argument
- */
- /* $Id$ */
- #include <time.h>
- #include "loc_time.h"
- /* The width can be -1 in both s_prnt() as in u_prnt(). This
- * indicates that as many characters as needed should be printed.
- */
- static char *
- s_prnt(char *s, size_t maxsize, const char *str, int width)
- {
- while (width > 0 || (width < 0 && *str)) {
- if (!maxsize) break;
- *s++ = *str++;
- maxsize--;
- width--;
- }
- return s;
- }
- static char *
- u_prnt(char *s, size_t maxsize, unsigned val, int width)
- {
- int c;
- c = val % 10;
- val = val / 10;
- if (--width > 0 || (width < 0 && val != 0))
- s = u_prnt(s, (maxsize ? maxsize - 1 : 0), val, width);
- if (maxsize) *s++ = c + '0';
- return s;
- }
- size_t
- strftime(char *s, size_t maxsize,
- const char *format, const struct tm *timeptr)
- {
- size_t n;
- char *firsts, *olds;
- if (!format) return 0;
- _tzset(); /* for %Z conversion */
- firsts = s;
- while (maxsize && *format) {
- while (maxsize && *format && *format != '%') {
- *s++ = *format++;
- maxsize--;
- }
- if (!maxsize || !*format) break;
- format++;
- olds = s;
- switch (*format++) {
- case 'a':
- s = s_prnt(s, maxsize,
- _days[timeptr->tm_wday], ABB_LEN);
- maxsize -= s - olds;
- break;
- case 'A':
- s = s_prnt(s, maxsize, _days[timeptr->tm_wday], -1);
- maxsize -= s - olds;
- break;
- case 'b':
- s = s_prnt(s, maxsize,
- _months[timeptr->tm_mon], ABB_LEN);
- maxsize -= s - olds;
- break;
- case 'B':
- s = s_prnt(s, maxsize, _months[timeptr->tm_mon], -1);
- maxsize -= s - olds;
- break;
- case 'c':
- n = strftime(s, maxsize,
- "%a %b %d %H:%M:%S %Y", timeptr);
- if (n) maxsize -= n;
- else maxsize = 0;
- s += n;
- break;
- case 'd':
- s = u_prnt(s, maxsize, timeptr->tm_mday, 2);
- maxsize -= s - olds;
- break;
- case 'H':
- s = u_prnt(s, maxsize, timeptr->tm_hour, 2);
- maxsize -= s - olds;
- break;
- case 'I':
- s = u_prnt(s, maxsize,
- (timeptr->tm_hour + 11) % 12 + 1, 2);
- maxsize -= s - olds;
- break;
- case 'j':
- s = u_prnt(s, maxsize, timeptr->tm_yday + 1, 3);
- maxsize -= s - olds;
- break;
- case 'm':
- s = u_prnt(s, maxsize, timeptr->tm_mon + 1, 2);
- maxsize -= s - olds;
- break;
- case 'M':
- s = u_prnt(s, maxsize, timeptr->tm_min, 2);
- maxsize -= s - olds;
- break;
- case 'p':
- s = s_prnt(s, maxsize,
- (timeptr->tm_hour < 12) ? "AM" : "PM", 2);
- maxsize -= s - olds;
- break;
- case 'S':
- s = u_prnt(s, maxsize, timeptr->tm_sec, 2);
- maxsize -= s - olds;
- break;
- case 'U':
- s = u_prnt(s, maxsize, /* ??? */
- (timeptr->tm_yday + 7 - timeptr->tm_wday) / 7, 2);
- maxsize -= s - olds;
- break;
- case 'w':
- s = u_prnt(s, maxsize, timeptr->tm_wday, 1);
- maxsize -= s - olds;
- break;
- case 'W':
- s = u_prnt(s, maxsize, /* ??? */
- (timeptr->tm_yday+7-(timeptr->tm_wday+6)%7)/7,2);
- maxsize -= s - olds;
- break;
- case 'x':
- n = strftime(s, maxsize, "%a %b %d %Y", timeptr);
- if (n) maxsize -= n;
- else maxsize = 0;
- s += n;
- break;
- case 'X':
- n = strftime(s, maxsize, "%H:%M:%S", timeptr);
- if (n) maxsize -= n;
- else maxsize = 0;
- s += n;
- break;
- case 'y':
- s = u_prnt(s, maxsize, timeptr->tm_year % 100, 2);
- maxsize -= s - olds;
- break;
- case 'Y':
- s = u_prnt(s, maxsize, timeptr->tm_year + YEAR0, -1);
- maxsize -= s - olds;
- break;
- case 'Z':
- s = s_prnt(s, maxsize,
- _tzname[(timeptr->tm_isdst > 0)], -1);
- maxsize -= s - olds;
- break;
- case '%':
- *s++ = '%';
- maxsize--;
- break;
- default:
- /* A conversion error. Leave the loop. */
- while (*format) format++;
- break;
- }
- }
- if (maxsize) {
- *s = '\0';
- return s - firsts;
- }
- return 0; /* The buffer is full */
- }
|