diff options
Diffstat (limited to 'apps/plugins/lua/strftime.c')
-rw-r--r-- | apps/plugins/lua/strftime.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/apps/plugins/lua/strftime.c b/apps/plugins/lua/strftime.c new file mode 100644 index 0000000000..df230f7bd0 --- /dev/null +++ b/apps/plugins/lua/strftime.c | |||
@@ -0,0 +1,130 @@ | |||
1 | #include <sys/types.h> | ||
2 | #include <time.h> | ||
3 | #include "plugin.h" | ||
4 | |||
5 | static const char sweekdays [7] [4] = { | ||
6 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" | ||
7 | }; | ||
8 | static const char weekdays [7] [10] = { | ||
9 | "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" | ||
10 | }; | ||
11 | static const char smonths [12] [4] = { | ||
12 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", | ||
13 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" | ||
14 | }; | ||
15 | static const char* months [12] = { | ||
16 | "January", "February", "March", "April", smonths[5-1], "June", | ||
17 | "July", "August", "September", "October", "November", "December" | ||
18 | }; | ||
19 | static const char ampm [4] [3] = { | ||
20 | "am", "pm", | ||
21 | "AM", "PM" | ||
22 | }; | ||
23 | |||
24 | static void i2a ( char* dest,unsigned long x ) | ||
25 | { | ||
26 | int div = 10; | ||
27 | *dest++ = x/div + '0'; | ||
28 | *dest++ = x%div + '0'; | ||
29 | *dest++ = '\0'; | ||
30 | } | ||
31 | |||
32 | size_t strftime ( char* dst, size_t max, const char* format, const struct tm* tm ) | ||
33 | { | ||
34 | char* p = dst; | ||
35 | const char* src; | ||
36 | unsigned long no; | ||
37 | char buf [5]; | ||
38 | |||
39 | if (!max) return 0; | ||
40 | for ( ; *format != '\0'; format++ ) { | ||
41 | if (*format == '%') { | ||
42 | if (*++format == '%') { | ||
43 | *p++ = '%'; | ||
44 | } | ||
45 | else | ||
46 | again: | ||
47 | switch (*format) { | ||
48 | // case '%': *p++ = '%'; break; // reduce size of jump table | ||
49 | case 'n': *p++ = '\n'; break; | ||
50 | case 't': *p++ = '\t'; break; | ||
51 | case 'O': case 'E': ++format; goto again; | ||
52 | case 'c': src = "%b %a %d %k:%M:%S %Z %Y"; goto _strf; | ||
53 | case 'r': src = "%I:%M:%S %p"; goto _strf; | ||
54 | case 'R': src = "%H:%M"; goto _strf; | ||
55 | case 'x': src = "%b %a %d"; goto _strf; | ||
56 | case 'X': src = "%k:%M:%S"; goto _strf; | ||
57 | case 'D': src = "%m/%d/%y"; goto _strf; | ||
58 | case 'T': src = "%H:%M:%S"; | ||
59 | _strf: p += strftime (p, (size_t)(dst+max-p), src, tm); break; | ||
60 | case 'a': src = sweekdays [tm->tm_wday]; goto _str; | ||
61 | case 'A': src = weekdays [tm->tm_wday]; goto _str; | ||
62 | case 'h': | ||
63 | case 'b': src = smonths [tm->tm_mon]; goto _str; | ||
64 | case 'B': src = months [tm->tm_mon]; goto _str; | ||
65 | case 'p': src = ampm [tm->tm_hour > 12 ? 3 : 2]; goto _str; | ||
66 | case 'P': src = ampm [tm->tm_hour > 12 ? 1 : 0]; goto _str; | ||
67 | case 'C': no = tm->tm_year/100 + 19; goto _no; | ||
68 | case 'd': no = tm->tm_mday; goto _no; | ||
69 | case 'e': no = tm->tm_mday; goto _nos; | ||
70 | case 'H': no = tm->tm_hour; goto _no; | ||
71 | case 'I': no = tm->tm_hour % 12; goto _no; | ||
72 | case 'j': no = tm->tm_yday; goto _no; | ||
73 | case 'k': no = tm->tm_hour; goto _nos; | ||
74 | case 'l': no = tm->tm_hour % 12; goto _nos; | ||
75 | case 'm': no = tm->tm_mon + 1; goto _no; | ||
76 | case 'M': no = tm->tm_min; goto _no; | ||
77 | case 'S': no = tm->tm_sec; goto _no; | ||
78 | case 'u': no = tm->tm_wday ? tm->tm_wday : 7; goto _no; | ||
79 | case 'w': no = tm->tm_wday; goto _no; | ||
80 | case 'U': no = (tm->tm_yday - tm->tm_wday + 7) / 7; goto _no; | ||
81 | case 'W': no = (tm->tm_yday - (tm->tm_wday - 1 + 7) % 7 + 7) / 7; goto _no; | ||
82 | case 's': { | ||
83 | time_t t = rb->mktime((struct tm*)tm); | ||
84 | char buf[101]; | ||
85 | char* c; | ||
86 | buf[100]=0; | ||
87 | for (c=buf+99; c>buf; --c) { | ||
88 | *c=(t%10)+'0'; | ||
89 | t/=10; | ||
90 | if (!t) break; | ||
91 | } | ||
92 | src=c; | ||
93 | goto _str; | ||
94 | } | ||
95 | case 'Z': | ||
96 | #ifdef WANT_TZFILE_PARSER | ||
97 | tzset(); src = tzname[0]; | ||
98 | #else | ||
99 | src = "[unknown timezone]"; | ||
100 | #endif | ||
101 | goto _str; | ||
102 | case 'Y': i2a ( buf+0, (unsigned int)(tm->tm_year / 100 + 19) ); | ||
103 | i2a ( buf+2, (unsigned int)(tm->tm_year % 100) ); | ||
104 | src = buf; | ||
105 | goto _str; | ||
106 | case 'y': no = tm->tm_year % 100; goto _no; | ||
107 | _no: i2a ( buf, no ); /* append number 'no' */ | ||
108 | src = buf; | ||
109 | goto _str; | ||
110 | _nos: i2a ( buf, no ); /* the same, but '0'->' ' */ | ||
111 | if (buf[0] == '0') | ||
112 | buf[0] = ' '; | ||
113 | src = buf; | ||
114 | _str: while (*src && p < dst+max) /* append string */ | ||
115 | *p++ = *src++; | ||
116 | break; | ||
117 | }; | ||
118 | } else { | ||
119 | *p++ = *format; | ||
120 | } | ||
121 | |||
122 | if (p >= dst+max) | ||
123 | break; | ||
124 | } | ||
125 | |||
126 | *p = '\0'; | ||
127 | return p - dst; | ||
128 | } | ||
129 | |||
130 | |||