Usermode/libc - Improved strerror, added some basic time functions
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / time.c
1 /*
2  * Acess2 C Library
3  * - By John Hodge (thePowersGang)
4  *
5  * time.c
6  * - POSIX/stdc time functions
7  */
8 #include <time.h>
9 #include <acess/sys.h>
10 #include <string.h>
11
12 clock_t clock(void)
13 {
14         return _SysTimestamp();
15 }
16
17 time_t time(time_t *t)
18 {
19         time_t ret = _SysTimestamp() / 1000;
20         if(t)
21                 *t = ret;
22         return ret;
23 }
24
25 static struct tm        static_tm;
26
27 struct tm *localtime(const time_t *timer)
28 {
29         struct tm *ret = &static_tm;
30
31         // TODO: This breaks on negative timestamps
32
33         int64_t day = *timer / (1000*60*60*24);
34         int64_t iday = *timer % (1000*60*60*24);        
35
36         ret->tm_sec = (iday / 1000) % 60;;
37         ret->tm_min = (iday / (1000*60)) % 60;
38         ret->tm_hour = (iday / (1000*60*60));
39         ret->tm_year = 0;
40         ret->tm_mon = 0;
41         ret->tm_mday = 0;
42         ret->tm_wday = (day + 6) % 7;   // 1 Jan 2000 was a saturday
43         ret->tm_yday = 0;
44         ret->tm_isdst = 0;      // Fuck DST
45         return ret;
46 }
47
48 static inline size_t MIN(size_t a, size_t b) { return a < b ? a : b; }
49 static size_t _puts(char * restrict s, size_t maxsize, size_t ofs, const char *str, size_t len)
50 {
51         if( s && ofs < maxsize ) {
52                 size_t  addlen = MIN(len, maxsize-1-ofs);
53                 memcpy(s+ofs, str, addlen);
54         }
55         return len;
56 }
57
58 size_t strftime(char*restrict s, size_t maxsize, const char*restrict format, const struct tm*restrict timeptr)
59 {
60         size_t  ofs = 0;
61
62         while( *format )
63         {
64                 const char *restrict start = format;
65                 while( *format && *format != '%' )
66                         format ++;
67                 if( format != start )
68                         ofs += _puts(s, maxsize, ofs, start, format-start);
69                 if( *format == 0 )
70                         break;
71                 format ++;
72                 switch(*format++)
73                 {
74                 case 0: format--;       break;
75                 case '%':       ofs += _puts(s, maxsize, ofs, format-1, 1);     break;
76                 case 'd':       // The day of the month as a decimal number (range 01 to 31).
77                         {
78                         char tmp[2] = {'0','0'};
79                         tmp[0] += (timeptr->tm_mday / 10) % 10;
80                         tmp[1] += timeptr->tm_mday % 10;
81                         ofs += _puts(s, maxsize, ofs, tmp, 2);
82                         }
83                         break;
84                 default:
85                         _SysDebug("TODO: strftime('...%%%c...')", format[-1]);
86                         break;
87                 }
88         }
89         
90         return ofs;
91 }

UCC git Repository :: git.ucc.asn.au