From 5dba4740302fc43d0ae9c37d8de8037b875303b2 Mon Sep 17 00:00:00 2001 From: cuz Date: Wed, 13 Nov 2002 13:08:46 +0000 Subject: [PATCH] Added strftime git-svn-id: svn://svn.cc65.org/cc65/trunk@1512 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- include/stddef.h | 11 +- include/time.h | 9 +- libsrc/common/Makefile | 1 + libsrc/common/strftime.c | 233 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 libsrc/common/strftime.c diff --git a/include/stddef.h b/include/stddef.h index 236feb9fd..bb86299cd 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -39,9 +39,18 @@ /* 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; - + diff --git a/include/time.h b/include/time.h index 535b2d49c..fd3a0d068 100644 --- a/include/time.h +++ b/include/time.h @@ -44,6 +44,12 @@ #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); diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index 11c209dd1..a6daff361 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -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 index 000000000..979f40c2a --- /dev/null +++ b/libsrc/common/strftime.c @@ -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 +#include +#include + + + +/* 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; + + } + } +} + + + -- 2.39.5