Added:
trunk/t/asctime64.t.c
Modified:
trunk/Makefile
trunk/t/tap.c
trunk/time64.c
trunk/time64.h
Log:
Implement asctime64() and asctime64_r()
Add make_tm() convenience function to quickly make TM structs.
Add is_str() to test strings.
Modified: trunk/Makefile
==============================================================================
--- trunk/Makefile (original)
+++ trunk/Makefile Wed Jan 7 11:05:07 2009
@@ -45,6 +45,9 @@
t/mktime64.t : t/tap.c t/mktime64.t.c time64.o
$(LINK) time64.o t/mktime64.t.c -o $@
+t/asctime64.t : t/tap.c t/asctime64.t.c time64.o
+ $(LINK) time64.o t/asctime64.t.c -o $@
+
t/seconds_between_years.t : t/tap.c t/seconds_between_years.t.c time64.c
$(LINK) t/seconds_between_years.t.c -o $@
Added: trunk/t/asctime64.t.c
==============================================================================
--- (empty file)
+++ trunk/t/asctime64.t.c Wed Jan 7 11:05:07 2009
@@ -0,0 +1,64 @@
+#include "time64.h"
+#include "t/tap.c"
+
+int main(void) {
+ struct TM date;
+ char * asctime_return1;
+ char * asctime_return2;
+ char asctime_r_buf1[35];
+ char asctime_r_buf2[35];
+ char * asctime_r_ret1;
+ char * asctime_r_ret2;
+
+ date = make_tm( 1, 2, 3, 4, 5, 234567LL );
+ date.tm_wday = 1; /* It's a Monday */
+
+ /* The asctime() function shall convert the broken-down time in the
structure pointed
+ to by timeptr into a string in the form: (ISO)
+ Sun Sep 16 01:03:52 1973\n\0
+ */
+ asctime_return1 = asctime64(&date);
+ is_str( asctime_return1, "Mon May 4 03:02:01 234567\n", "asctime64()"
);
+
+ /* The asctime(), ctime(), gmtime(), and localtime() functions shall
return values in
+ one of two static objects: a broken-down time structure and an
array of type char.
+ Execution of any of the functions may overwrite the information
returned in either
+ of these objects by any of the other functions. (POSIX)
+ */
+ date.tm_sec = 42;
+ asctime_return2 = asctime64(&date);
+ is_str( asctime_return2, "Mon May 4 03:02:42 234567\n", "asctime64()
again" );
+ is_str( asctime_return1, asctime_return2, " return is static" );
+
+ /* The asctime_r() function shall convert the broken-down time in the
structure pointed
+ to by tm into a string (of the same form as that returned by
asctime()) that is placed
+ in the user-supplied buffer pointed to by buf (which shall contain
at least 26 bytes)
+ and then return buf. (POSIX)
+ It'll have to be 35 bytes to hold the year -292,000,000,000
+ */
+ asctime_r_ret1 = asctime64_r( &date, asctime_r_buf1 );
+ is_str( asctime_r_buf1, "Mon May 4 03:02:42
234567\n", "asctime64_r()" );
+ is_str( asctime_r_buf1, asctime_r_ret1, " return
value same" );
+
+ date.tm_hour = 5;
+ asctime_r_ret2 = asctime64_r( &date, asctime_r_buf2 );
+ is_str( asctime_r_buf2, "Mon May 4 05:02:42
234567\n", "asctime64_r() again" );
+ is_str( asctime_r_ret1, "Mon May 4 03:02:42 234567\n", " return not
static" );
+
+ /* Upon successful completion, asctime() shall return a pointer to the
string.
+ If the function is unsuccessful, it shall return NULL. (ISO)
+ */
+ date.tm_wday = -1;
+ ok( asctime64(&date) == NULL, "asctime64() fail" );
+
+ /* Upon successful completion, asctime_r() shall return a pointer to a
character string
+ containing the date and time. This string is pointed to by the
argument buf. If the
+ function is unsuccessful, it shall return NULL. (POSIX)
+ */
+ ok( asctime64_r(&date, asctime_r_buf2) == NULL, "asctime64_r()
fail" );
+ is_str( asctime_r_buf2, "Mon May 4 05:02:42 234567\n", " buffer not
overwritten" );
+
+ /* No errors are defined. (ISO) */
+
+ return 0;
+}
Modified: trunk/t/tap.c
==============================================================================
--- trunk/t/tap.c (original)
+++ trunk/t/tap.c Wed Jan 7 11:05:07 2009
@@ -76,6 +76,24 @@
}
+int is_str(const char* have, const char* want, const char *message, ...) {
+ int test = strcmp(have, want) == 0;
+ va_list args;
+ va_start(args, message);
+
+ do_test( test, message, args );
+
+ if( !test ) {
+ diag("have: %s", have);
+ diag("want: %s", want);
+ }
+
+ va_end(args);
+
+ return test;
+}
+
+
int is_Int64(const Int64 have, const Int64 want, const char *name, ...) {
int test = (have == want);
@@ -131,6 +149,20 @@
pass *= is_int(have->tm_sec, want->tm_sec, " sec");
return pass;
+}
+
+
+struct TM make_tm( int sec, int min, int hour, int day, int mon, Year year
) {
+ struct TM date;
+
+ date.tm_year = year - 1900;
+ date.tm_mon = mon - 1;
+ date.tm_mday = day;
+ date.tm_hour = hour;
+ date.tm_min = min;
+ date.tm_sec = sec;
+
+ return date;
}
Modified: trunk/time64.c
==============================================================================
--- trunk/time64.c (original)
+++ trunk/time64.c Wed Jan 7 11:05:07 2009
@@ -51,7 +51,7 @@
/* Spec says except for stftime() and the _r() functions, these
all return static memory. Stabbings! */
static struct TM Static_Return_Date;
-/* static char Static_Return_String[1024]; */
+static char Static_Return_String[35];
static const int days_in_month[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
@@ -63,6 +63,15 @@
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335},
};
+static char wday_name[7][3] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
+
+static char mon_name[12][3] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
static const int length_of_year[2] = { 365, 366 };
/* Some numbers relating to the gregorian cycle */
@@ -699,11 +708,47 @@
}
+int valid_tm_wday( const struct TM* date ) {
+ if( 0 <= date->tm_wday && date->tm_wday <= 6 )
+ return 1;
+ else
+ return 0;
+}
+
+int valid_tm_mon( const struct TM* date ) {
+ if( 0 <= date->tm_mon && date->tm_mon <= 11 )
+ return 1;
+ else
+ return 0;
+}
+
+
+char *asctime64_r( const struct TM* date, char *result ) {
+ /* I figure everything else can be displayed, even hour 25, but if
+ these are out of range we walk off the name arrays */
+ if( !valid_tm_wday(date) || !valid_tm_mon(date) )
+ return NULL;
+
+ sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+ wday_name[date->tm_wday],
+ mon_name[date->tm_mon],
+ date->tm_mday, date->tm_hour,
+ date->tm_min, date->tm_sec,
+ 1900 + date->tm_year);
+
+ return result;
+}
+
+
+/* Non-thread safe versions of the above */
struct TM *localtime64(const Time64_T *time) {
return localtime64_r(time, &Static_Return_Date);
}
-
struct TM *gmtime64(const Time64_T *time) {
return gmtime64_r(time, &Static_Return_Date);
+}
+
+char *asctime64( const struct TM* date ) {
+ return asctime64_r( date, Static_Return_String );
}
Modified: trunk/time64.h
==============================================================================
--- trunk/time64.h (original)
+++ trunk/time64.h Wed Jan 7 11:05:07 2009
@@ -44,9 +44,11 @@
/* Declare public functions */
struct TM *gmtime64_r (const Time64_T *, struct TM *);
struct TM *localtime64_r (const Time64_T *, struct TM *);
-
struct TM *gmtime64 (const Time64_T *);
struct TM *localtime64 (const Time64_T *);
+
+char *asctime64 (const struct TM *);
+char *asctime64_r (const struct TM *, char *);
Time64_T timegm64 (const struct TM *);
Time64_T mktime64 (const struct TM *);