summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/libugly/strftime.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/libugly/strftime.c')
-rw-r--r--mdk-stage1/dietlibc/libugly/strftime.c284
1 files changed, 110 insertions, 174 deletions
diff --git a/mdk-stage1/dietlibc/libugly/strftime.c b/mdk-stage1/dietlibc/libugly/strftime.c
index b7e750ab1..365d0c84f 100644
--- a/mdk-stage1/dietlibc/libugly/strftime.c
+++ b/mdk-stage1/dietlibc/libugly/strftime.c
@@ -1,182 +1,118 @@
#include <sys/types.h>
#include <time.h>
-
-static char *sweekdays[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
-static char *weekdays[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
-static char *smonths[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
-static char *months[]={"January","February","March","April","May","June","July","August","September","October","November","December"};
-static char *ampm[]={"am","pm","AM","PM"};
-
-static int i2a(char* dest,unsigned int x) {
- register unsigned int tmp=x;
- register int len=0;
- *dest++=tmp/10+'0'; tmp=tmp%10; ++len;
- *dest++=tmp+'0';
- return 2;
+#include "dietfeatures.h"
+
+static const char sweekdays [7] [4] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
+static const char weekdays [7] [10] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+};
+static const char smonths [12] [4] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+static const char* months [12] = {
+ "January", "February", "March", "April", smonths[5-1], "June",
+ "July", "August", "September", "October", "November", "December"
+};
+static const char ampm [4] [3] = {
+ "am", "pm",
+ "AM", "PM"
+};
+
+static int i2a ( char* dest,unsigned int x )
+{
+ int div = 10;
+ *dest++ = x/div + '0';
+ *dest++ = x%div + '0';
+ *dest++ = '\0';
+ return 2;
}
-static int i2as(char* dest,unsigned int x) {
- int len=i2a(dest,x);
- if (*dest=='0') *dest=' ';
- return len;
-}
-
-size_t strftime(char *s, size_t max, const char *format, const struct tm *tm) {
- char *t=s;
- const char *src;
- char buf[5];
- while (*format) {
- switch (*format) {
- case 0: break;
- case '%':
- switch (*++format) {
- case '%': *t='%'; ++t; break;
- case 'a': src=sweekdays[tm->tm_wday]; goto append;
- case 'A': src=weekdays[tm->tm_wday]; goto append;
- case 'h':
- case 'b': src=smonths[tm->tm_mon]; goto append;
- case 'B': src=months[tm->tm_mon]; goto append;
- case 'c': t+=strftime(t,max-(t-s),"%b %a %d %k:%M:%S %Z %Y",tm); break;
- case 'C': buf[i2a(buf,(tm->tm_year+1900)/100)]=0; src=buf; goto append;
- case 'd': buf[i2a(buf,tm->tm_mday)]=0; src=buf; goto append;
- case 'e': buf[i2as(buf,tm->tm_mday)]=0; src=buf; goto append;
- case 'H': buf[i2a(buf,tm->tm_hour)]=0; src=buf; goto append;
- case 'I': buf[i2a(buf,tm->tm_hour%12)]=0; src=buf; goto append;
- case 'j': buf[i2a(buf,tm->tm_yday)]=0; src=buf; goto append;
- case 'k': buf[i2as(buf,tm->tm_hour)]=0; src=buf; goto append;
- case 'l': buf[i2as(buf,tm->tm_hour%12)]=0; src=buf; goto append;
- case 'm': buf[i2a(buf,tm->tm_mon+1)]=0; src=buf; goto append;
- case 'M': buf[i2a(buf,tm->tm_min)]=0; src=buf; goto append;
- case 'n': *t='\n'; break;
- case 'p': src=ampm[tm->tm_hour>11?3:2]; goto append;
- case 'P': src=ampm[tm->tm_hour>11?1:0]; goto append;
- case 'r': t+=strftime(t,max-(t-s),"%I:%M:%S %p",tm); break;
- case 'R': t+=strftime(t,max-(t-s),"%H:%M",tm); break;
- case 'S': buf[i2a(buf,tm->tm_sec)]=0; src=buf; goto append;
- case 't': *t='\t'; break;
- case 'T': t+=strftime(t,max-(t-s),"%H:%M:%S",tm); break;
- case 'u': buf[i2a(buf,tm->tm_wday?tm->tm_wday:7)]=0; src=buf; goto append;
- case 'w': buf[i2a(buf,tm->tm_wday)]=0; src=buf; goto append;
- case 'x': t+=strftime(t,max-(t-s),"%b %a %d",tm); break;
- case 'X': t+=strftime(t,max-(t-s),"%k:%M:%S",tm); break;
- case 'y': buf[i2a(buf,tm->tm_year%100)]=0; src=buf; goto append;
- case 'Y': i2a(buf,(tm->tm_year+1900)/100); buf[i2a(buf+2,(tm->tm_year%100))+2]=0; src=buf; goto append;
- case 'Z': src="GMT"; goto append; /* hehe */
-append:
- while (*src && t<s+max) { *t=*src; ++t; ++src; }
- };
- break;
- default:
- *t=*format; ++t;
+size_t strftime ( char* dst, size_t max, const char* format, const struct tm* tm )
+{
+ char* p = dst;
+ const char* src;
+ unsigned int no;
+ char buf [5];
+
+
+ for ( ; *format != '\0'; format++ ) {
+ if (*format == '%') {
+ if (*++format == '%') {
+ *p++ = '%';
+ }
+ else
+again:
+ switch (*format) {
+// case '%': *p++ = '%'; break; // reduce size of jump table
+ case 'n': *p++ = '\n'; break;
+ case 't': *p++ = '\t'; break;
+ case 'O': case 'E': ++format; goto again;
+ case 'c': src = "%b %a %d %k:%M:%S %Z %Y"; goto _strf;
+ case 'r': src = "%I:%M:%S %p"; goto _strf;
+ case 'R': src = "%H:%M"; goto _strf;
+ case 'x': src = "%b %a %d"; goto _strf;
+ case 'X': src = "%k:%M:%S"; goto _strf;
+ case 'D': src = "%m/%d/%y"; goto _strf;
+ case 'T': src = "%H:%M:%S";
+ _strf: p += strftime (p, (size_t)(dst+max-p), src, tm); break;
+ case 'a': src = sweekdays [tm->tm_wday]; goto _str;
+ case 'A': src = weekdays [tm->tm_wday]; goto _str;
+ case 'h':
+ case 'b': src = smonths [tm->tm_mon]; goto _str;
+ case 'B': src = months [tm->tm_mon]; goto _str;
+ case 'p': src = ampm [tm->tm_hour > 12 ? 3 : 2]; goto _str;
+ case 'P': src = ampm [tm->tm_hour > 12 ? 1 : 0]; goto _str;
+ case 'C': no = tm->tm_year/100 + 19; goto _no;
+ case 'd': no = tm->tm_mday; goto _no;
+ case 'e': no = tm->tm_mday; goto _nos;
+ case 'H': no = tm->tm_hour; goto _no;
+ case 'I': no = tm->tm_hour % 12; goto _no;
+ case 'j': no = tm->tm_yday; goto _no;
+ case 'k': no = tm->tm_hour; goto _nos;
+ case 'l': no = tm->tm_hour % 12; goto _nos;
+ case 'm': no = tm->tm_mon + 1; goto _no;
+ case 'M': no = tm->tm_min; goto _no;
+ case 'S': no = tm->tm_sec; goto _no;
+ case 'u': no = tm->tm_wday ? tm->tm_wday : 7; goto _no;
+ case 'w': no = tm->tm_wday; goto _no;
+ case 'U': no = (tm->tm_yday - tm->tm_wday + 7) / 7; goto _no;
+ case 'W': no = (tm->tm_yday - (tm->tm_wday - 1 + 7) % 7 + 7) / 7; goto _no;
+ case 'Z':
+#ifdef WANT_TZFILE_PARSER
+ tzset(); src = tzname[0];
+#else
+ src = "[unknown timezone]";
+#endif
+ goto _str;
+ case 'Y': i2a ( buf+0, (unsigned int)(tm->tm_year / 100 + 19) );
+ i2a ( buf+2, (unsigned int)(tm->tm_year % 100) );
+ src = buf;
+ goto _str;
+ case 'y': no = tm->tm_year % 100; goto _no;
+ _no: i2a ( buf, no ); /* append number 'no' */
+ src = buf;
+ goto _str;
+ _nos: i2a ( buf, no ); /* the same, but '0'->' ' */
+ if (buf[0] == '0')
+ buf[0] = ' ';
+ src = buf;
+ _str: while (*src && p < dst+max) /* append string */
+ *p++ = *src++;
+ break;
+ };
+ } else {
+ *p++ = *format;
+ }
+
+ if (p >= dst+max)
+ break;
}
- ++format;
- if (t>=s+max) break;
- continue;
- }
- *t=0; return t-s;
+
+ *p = '\0';
+ return p - dst;
}
-
-/*
- %u The day of the week as a decimal, range 1 to 7,
- Monday being 1. See also %w. (SU)
-
- %U The week number of the current year as a decimal
- number, range 00 to 53, starting with the first
- Sunday as the first day of week 01. See also %V and
- %W.
-
- %V The ISO 8601:1988 week number of the current year
- as a decimal number, range 01 to 53, where week 1
- is the first week that has at least 4 days in the
- current year, and with Monday as the first day of
- the week. See also %U and %W. (SU)
-
- %w The day of the week as a decimal, range 0 to 6,
- Sunday being 0. See also %u.
-
- %W The week number of the current year as a decimal
- number, range 00 to 53, starting with the first
- Monday as the first day of week 01.
-
- %x The preferred date representation for the current
- locale without the time.
-
- %X The preferred time representation for the current
- locale without the date.
-
- %y The year as a decimal number without a century
- (range 00 to 99).
-
- %Y The year as a decimal number including the century.
-
- %z The time-zone as hour offset from GMT. Required to
- emit RFC822-conformant dates (using "%a, %d %b %Y
- %H:%M:%S %z"). (GNU)
-
- %Z The time zone or name or abbreviation.
-
- %+ The date and time in date(1) format. (TZ)
-
- %% A literal `%' character.
-
- Some conversion specifiers can be modified by preceding
- them by the E or O modifier to indicate that an alterna­
- tive format should be used. If the alternative format or
- specification does not exist for the current locale, the
- behaviour will be as if the unmodified conversion specifi­
- cation were used. (SU) The Single Unix Specification men­
- tions %Ec, %EC, %Ex, %EX, %Ry, %EY, %Od, %Oe, %OH, %OI,
- %Om, %OM, %OS, %Ou, %OU, %OV, %Ow, %OW, %Oy, where the
- effect of the O modifier is to use alternative numeric
- symbols (say, roman numerals), and that of the E modifier
-
-
-
-GNU 29 March 1999 3
-
-
-
-
-
-STRFTIME(3) Linux Programmer's Manual STRFTIME(3)
-
-
- is to use a locale-dependent alternative representation.
-
- The broken-down time structure tm is defined in <time.h>.
- See also ctime(3).
-
-
-RETURN VALUE
- The strftime() function returns the number of characters
- placed in the array s, not including the terminating NUL
- character, provided the string, including the terminating
- NUL, fits. Otherwise, it returns 0, and the contents of
- the array is undefined. (Thus at least since libc 4.4.4;
- very old versions of libc, such as libc 4.4.1, would
- return max if the array was too small.)
-
- Note that the return value 0 does not necessarily indicate
- an error; for example, in many locales %p yields an empty
- string.
-
-ENVIRONMENT
- The environment variables TZ and LC_TIME are used.
-
-CONFORMING TO
- ANSI C, SVID 3, ISO 9899. There are strict inclusions
- between the set of conversions given in ANSI C (unmarked),
- those given in the Single Unix Specification (marked SU),
- those given in Olson's timezone package (marked TZ), and
- those given in glibc (marked GNU), except that %+ is not
- supported in glibc2. On the other hand glibc2 has several
- more extensions. POSIX.1 only refers to ANSI C; POSIX.2
- describes under date(1) several extensions that could
- apply to strftime as well.
-
-SEE ALSO
- date(1), time(2), ctime(3), setlocale(3), sprintf(3)
-
-*/