]> git.sur5r.net Git - cc65/commitdiff
Added strftime
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 13 Nov 2002 13:08:46 +0000 (13:08 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 13 Nov 2002 13:08:46 +0000 (13:08 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1512 b7a2c559-68d2-44c3-8de9-860c34a00d81

include/stddef.h
include/time.h
libsrc/common/Makefile
libsrc/common/strftime.c [new file with mode: 0644]

index 236feb9fd6f82d514040096568044d1c65309ad4..bb86299cd2903a0cfd50c52a5b7a7137962cb01e 100644 (file)
 
 
 /* Standard data types */
+#ifndef _PTRDIFF_T
+#define _PTRDIFF_T
 typedef int ptrdiff_t;
+#endif
+#ifndef _WCHAR_T
+#define _WCHAR_T
 typedef char wchar_t;
+#endif
+#ifndef _SIZE_T
+#define _SIZE_T
 typedef unsigned size_t;
+#endif
 
 /* NULL pointer */
 #ifdef NULL
@@ -59,4 +68,4 @@ typedef unsigned size_t;
 
 
 
-                    
+
index 535b2d49c8d9b90b02c5543106204d861651e120..fd3a0d06837ebc2a27fb906c278351da9a119891 100644 (file)
 #endif
 #define NULL   0
 
+/* size_t is needed */
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef unsigned size_t;
+#endif
+
 typedef unsigned long time_t;
 typedef unsigned long clock_t;
 
@@ -91,7 +97,7 @@ unsigned _clocks_per_sec (void);
 
 
 time_t _systime (void);
-/* Similar to time(), but:                 
+/* Similar to time(), but:
  *   - Is not ISO C
  *   - Does not take the additional pointer
  *   - Does not set errno when returning -1
@@ -104,6 +110,7 @@ char* __fastcall__ ctime (const time_t* timep);
 struct tm* __fastcall__ gmtime (const time_t* timep);
 struct tm* __fastcall__ localtime (const time_t* timep);
 time_t __fastcall__ mktime (struct tm* timep);
+size_t __fastcall__ strftime (char* buf, size_t bufsize, const char* format, const struct tm* tm);
 time_t __fastcall__ time (time_t* t);
 
 
index 11c209dd15082a915945c351b1cd228395895c3c..a6daff361b76d5031a07be581a2c080f3e8469a3 100644 (file)
@@ -46,6 +46,7 @@ C_OBJS =      _afailed.o      \
                realloc.o       \
                rewind.o        \
                sscanf.o        \
+                strftime.o      \
                strxfrm.o       \
                strtok.o        \
                 timezone.o      \
diff --git a/libsrc/common/strftime.c b/libsrc/common/strftime.c
new file mode 100644 (file)
index 0000000..979f40c
--- /dev/null
@@ -0,0 +1,233 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                strftime.c                                 */
+/*                                                                           */
+/*      Convert broken down time to a string in a user specified format      */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2002      Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+
+
+
+/* Use static local variables for speed */
+#pragma staticlocals (on);
+
+
+
+/*****************************************************************************/
+/*                                   Code                                    */
+/*****************************************************************************/
+
+
+
+size_t __fastcall__ strftime (char* buf, size_t bufsize, const char* format,
+                              const struct tm* tm)
+{
+    static const char* days[7] = {
+        "Sunday",   "Monday", "Tuesday", "Wednesday",
+        "Thursday", "Friday", "Saturday"
+    };
+    static const char* months[12] = {
+        "January", "February", "March", "April", "May", "June",
+        "July", "August", "September", "October", "November", "December"
+    };
+
+    unsigned    count;
+    unsigned    len;
+    char        c;
+    char        arg[40];
+    const char* argptr;
+    unsigned    week;
+
+    /* Copy until we reach the end of the format string or a format specifier */
+    count = 0;
+    while (1) {
+        if (count >= bufsize) {
+            /* Not enough buffer space available */
+            return 0;
+        }
+        if ((c = *format++) == '\0') {
+            /* End of format string reached */
+            *buf = '\0';
+            return count;
+        }
+        if (c == '%') {
+            /* Format specifier */
+            argptr = arg;
+            switch (*format++) {
+
+                case '%':
+                    arg[0] = '%';
+                    arg[1] = '\0';
+                    break;
+
+                case 'A':
+                    argptr = days[tm->tm_wday];
+                    break;
+
+                case 'B':
+                    argptr = months[tm->tm_mon];
+                    break;
+
+                case 'D':
+                    sprintf (arg, "%02d/%02d/%02d", tm->tm_mon + 1,
+                             tm->tm_mday, tm->tm_year % 100);
+                    break;
+
+                case 'F':
+                    /* C99 */
+                    sprintf (arg, "%04d-%02d-%02d", tm->tm_year + 1900,
+                             tm->tm_mon + 1, tm->tm_mday);
+                    break;
+
+                case 'H':
+                    sprintf (arg, "%02d", tm->tm_hour);
+                    break;
+
+                case 'I':
+                    sprintf (arg, "%02d", tm->tm_hour % 12);
+                    break;
+
+                case 'M':
+                    sprintf (arg, "%02d", tm->tm_min);
+                    break;
+
+                case 'P':
+                    /* GNU extension */
+                    argptr = (tm->tm_hour >= 12)? "pm" : "am";
+                    break;
+
+                case 'S':
+                    sprintf (arg, "%02d", tm->tm_sec);
+                    break;
+
+                case 'U':
+                    week = tm->tm_yday / 7;
+                    if (tm->tm_mday % 7 > tm->tm_wday) {
+                        ++week;
+                    }
+                    sprintf (arg, "%02u", week);
+                    break;
+
+                case 'W':
+                    /* ### This one is buggy */
+                    week = tm->tm_yday / 7;
+                    if (tm->tm_mday % 7 > tm->tm_wday) {
+                        ++week;
+                    }
+                    sprintf (arg, "%2u", week);
+                    break;
+
+                case 'X':
+                    sprintf (arg, "%02d:%02d:%02d", tm->tm_hour,
+                             tm->tm_min, tm->tm_sec);
+                    break;
+
+                case 'Y':
+                    sprintf (arg, "%4d", tm->tm_year + 1900);
+                    break;
+
+                case 'Z':
+                    argptr = tm->tm_isdst? _tz.dstname : _tz.tzname;
+                    break;
+
+                case 'a':
+                    sprintf (arg, "%.3s", days[tm->tm_wday]);
+                    break;
+
+                case 'b':
+                    sprintf (arg, "%.3s", months[tm->tm_mday]);
+                    break;
+
+                case 'c':
+                    sprintf (arg, "%.3s %.3s%3d %02d:%02d:%02d %d",
+                            days[tm->tm_wday], months[tm->tm_mon],
+                            tm->tm_mday, tm->tm_hour, tm->tm_min,
+                            tm->tm_sec, tm->tm_year + 1900);
+                    break;
+
+                case 'd':
+                    sprintf (arg, "%02d", tm->tm_mday);
+                    break;
+
+                case 'j':
+                    sprintf (arg, "%03d", tm->tm_yday + 1);
+                    break;
+
+                case 'm':
+                    sprintf (arg, "%02d", tm->tm_mon + 1);
+                    break;
+
+                case 'p':
+                    argptr = (tm->tm_hour >= 12)? "PM" : "AM";
+                    break;
+
+                case 'w':
+                    sprintf (arg, "%d", tm->tm_wday);
+                    break;
+
+                case 'x':
+                    sprintf (arg, "%04d-%02d-%02d", tm->tm_year + 1900,
+                             tm->tm_mon + 1, tm->tm_mday);
+                    break;
+
+                case 'y':
+                    sprintf (arg, "%02d", tm->tm_year % 100);
+                    break;
+
+                default:
+                    /* Unknown format specifier, convert to empty string */
+                    arg[0] = '\0';
+                    break;
+            }
+
+            /* Check if we have enough space to copy the argument string */
+            len = strlen (argptr);
+            count += len;
+            if (count < bufsize) {
+                memcpy (buf, argptr, len);
+                buf += len;
+            }
+
+        } else {
+
+            /* No format character, just copy */
+            *buf++ = c;
+            ++count;
+
+        }
+    }
+}
+
+
+