@@ -1,5 +1,23 @@
Revision history for Time-Piece
+1.27 2014-01-03
+ - portability fixes for XS changes in 1.25_01
+
+1.26 2013-12-29
+ - no changes since previous (trial) release
+
+1.25_01 2013-12-16
+ - fix compiling for WinCE, execution is untested
+ - add a .gitignore (from Win32::API)
+ - fix a compiler warning about unused var, and add inlining
+ - add PERL_NO_GET_CONTEXT to XS to bring the binary into 21st century
+ - refactor XS code to remove large sections of duplicate machine code
+ - fix _crt_localtime to return year only once, previously
+ _crt_localtime returned year (item #6) twice in the list
+
+1.24 2013-12-03
+ - add repository metadata (thanks, David Steinbrunner)
+
1.23 2013-09-06
- add a LICENSE file (thanks, John Peacock!)
- make sure Time::Seconds loads Exporter, which it relies on (thanks,
@@ -4,7 +4,7 @@
"Matt Sergeant"
],
"dynamic_config" : 1,
- "generated_by" : "ExtUtils::MakeMaker version 6.72, CPAN::Meta::Converter version 2.132140",
+ "generated_by" : "ExtUtils::MakeMaker version 6.84, CPAN::Meta::Converter version 2.133380",
"license" : [
"perl_5"
],
@@ -37,5 +37,10 @@
}
},
"release_status" : "stable",
- "version" : "1.23"
+ "resources" : {
+ "repository" : {
+ "url" : "https://github.com/rjbs/Time-Piece"
+ }
+ },
+ "version" : "1.27"
}
@@ -7,7 +7,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: 0
dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.72, CPAN::Meta::Converter version 2.132140'
+generated_by: 'ExtUtils::MakeMaker version 6.84, CPAN::Meta::Converter version 2.133380'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -19,4 +19,6 @@ no_index:
- inc
requires:
Exporter: 5.57
-version: 1.23
+resources:
+ repository: https://github.com/rjbs/Time-Piece
+version: 1.27
@@ -10,4 +10,9 @@ WriteMakefile(
'INSTALLDIRS' => ( ($] >= 5.009005 and $] < 5.011) ? 'perl' : 'site'),
'PREREQ_PM' => { Exporter => '5.57' },
(eval { ExtUtils::MakeMaker->VERSION(6.21) } ? (LICENSE => 'perl') : ()),
+ 'META_MERGE' => {
+ 'resources' => {
+ 'repository' => 'https://github.com/rjbs/Time-Piece',
+ },
+ },
);
@@ -19,7 +19,7 @@ our %EXPORT_TAGS = (
':override' => 'internal',
);
-our $VERSION = '1.23';
+our $VERSION = '1.27';
bootstrap Time::Piece $VERSION;
@@ -1,6 +1,7 @@
#ifdef __cplusplus
extern "C" {
#endif
+#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
@@ -133,6 +134,10 @@ my_init_tm(struct tm *ptm) /* see mktime, strftime and asctime */
#undef getenv
#undef putenv
+# ifdef UNDER_CE
+# define getenv xcegetenv
+# define putenv xceputenv
+# endif
#undef malloc
#undef free
@@ -944,14 +949,63 @@ label:
return (char *)buf;
}
+/* Saves alot of machine code.
+ Takes a (auto) SP, which may or may not have been PUSHed before, puts
+ tm struct members on Perl stack, then returns new, advanced, SP to caller.
+ Assign the return of push_common_tm to your SP, so you can continue to PUSH
+ or do a PUTBACK and return eventually.
+ !!!! push_common_tm does not touch PL_stack_sp !!!!
+ !!!! do not use PUTBACK then SPAGAIN semantics around push_common_tm !!!!
+ !!!! You must mortalize whatever push_common_tm put on stack yourself to
+ avoid leaking !!!!
+*/
+SV **
+push_common_tm(pTHX_ SV ** SP, struct tm *mytm)
+{
+ PUSHs(newSViv(mytm->tm_sec));
+ PUSHs(newSViv(mytm->tm_min));
+ PUSHs(newSViv(mytm->tm_hour));
+ PUSHs(newSViv(mytm->tm_mday));
+ PUSHs(newSViv(mytm->tm_mon));
+ PUSHs(newSViv(mytm->tm_year));
+ PUSHs(newSViv(mytm->tm_wday));
+ PUSHs(newSViv(mytm->tm_yday));
+ return SP;
+}
-char *
-our_strptime(pTHX_ const char *buf, const char *fmt, struct tm *tm)
+/* specialized common end of 2 XSUBs
+ SV ** SP -- pass your (auto) SP, which has not been PUSHed before, but was
+ reset to 0 (PPCODE only or SP -= items or XSprePUSH)
+ tm *mytm -- a tm *, will be proprocessed with my_mini_mktime
+ return -- none, after calling return_11part_tm, you must call "return;"
+ no exceptions
+*/
+void
+return_11part_tm(pTHX_ SV ** SP, struct tm *mytm)
{
- char *ret;
- int got_GMT = 0;
+ my_mini_mktime(mytm);
+
+ /* warn("tm: %d-%d-%d %d:%d:%d\n", mytm.tm_year, mytm.tm_mon, mytm.tm_mday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec); */
- return _strptime(aTHX_ buf, fmt, tm, &got_GMT);
+ EXTEND(SP, 11);
+ SP = push_common_tm(aTHX_ SP, mytm);
+ /* isdst */
+ PUSHs(newSViv(0));
+ /* epoch */
+ PUSHs(newSViv(0));
+ /* islocal */
+ PUSHs(newSViv(0));
+ PUTBACK;
+ {
+ SV ** endsp = SP; /* the SV * under SP needs to be mortaled */
+ SP -= (11 - 1); /* subtract 0 based count of SVs to mortal */
+/* mortal target of SP, then increment before function call
+ so SP is already calculated before next comparison to not stall CPU */
+ do {
+ sv_2mortal(*SP++);
+ } while(SP <= endsp);
+ }
+ return;
}
MODULE = Time::Piece PACKAGE = Time::Piece
@@ -1037,8 +1091,9 @@ _strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1
void
_tzset()
PPCODE:
+ PUTBACK; /* makes rest of this function tailcall friendly */
my_tzset(aTHX);
-
+ return; /* skip XSUBPP's PUTBACK */
void
_strptime ( string, format )
@@ -1048,36 +1103,22 @@ _strptime ( string, format )
struct tm mytm;
time_t t;
char * remainder;
+ int got_GMT;
PPCODE:
t = 0;
mytm = *gmtime(&t);
- remainder = (char *)our_strptime(aTHX_ string, format, &mytm);
+ got_GMT = 0;
+
+ remainder = (char *)_strptime(aTHX_ string, format, &mytm, &got_GMT);
if (remainder == NULL) {
croak("Error parsing time");
}
if (*remainder != '\0') {
warn("garbage at end of string in strptime: %s", remainder);
}
-
- my_mini_mktime(&mytm);
- /* warn("tm: %d-%d-%d %d:%d:%d\n", mytm.tm_year, mytm.tm_mon, mytm.tm_mday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec); */
-
- EXTEND(SP, 11);
- PUSHs(sv_2mortal(newSViv(mytm.tm_sec)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_min)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_hour)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_mday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_mon)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_year)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_wday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_yday)));
- /* isdst */
- PUSHs(sv_2mortal(newSViv(0)));
- /* epoch */
- PUSHs(sv_2mortal(newSViv(0)));
- /* islocal */
- PUSHs(sv_2mortal(newSViv(0)));
+ return_11part_tm(aTHX_ SP, &mytm);
+ return;
void
_mini_mktime(int sec, int min, int hour, int mday, int mon, int year)
@@ -1094,61 +1135,32 @@ _mini_mktime(int sec, int min, int hour, int mday, int mon, int year)
mytm.tm_mday = mday;
mytm.tm_mon = mon;
mytm.tm_year = year;
-
- my_mini_mktime(&mytm);
- EXTEND(SP, 11);
- PUSHs(sv_2mortal(newSViv(mytm.tm_sec)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_min)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_hour)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_mday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_mon)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_year)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_wday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_yday)));
- /* isdst */
- PUSHs(sv_2mortal(newSViv(0)));
- /* epoch */
- PUSHs(sv_2mortal(newSViv(0)));
- /* islocal */
- PUSHs(sv_2mortal(newSViv(0)));
+ return_11part_tm(aTHX_ SP, &mytm);
+ return;
void
_crt_localtime(time_t sec)
+ ALIAS:
+ _crt_gmtime = 1
PREINIT:
struct tm mytm;
PPCODE:
- mytm = *localtime(&sec);
+ if(ix) mytm = *gmtime(&sec);
+ else mytm = *localtime(&sec);
/* Need to get: $s,$n,$h,$d,$m,$y */
EXTEND(SP, 9);
- PUSHs(sv_2mortal(newSViv(mytm.tm_sec)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_min)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_hour)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_mday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_mon)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_year)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_year)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_wday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_yday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_isdst)));
-
-void
-_crt_gmtime(time_t sec)
- PREINIT:
- struct tm mytm;
- PPCODE:
- mytm = *gmtime(&sec);
- /* Need to get: $s,$n,$h,$d,$m,$y */
-
- EXTEND(SP, 9);
- PUSHs(sv_2mortal(newSViv(mytm.tm_sec)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_min)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_hour)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_mday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_mon)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_year)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_wday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_yday)));
- PUSHs(sv_2mortal(newSViv(mytm.tm_isdst)));
-
+ SP = push_common_tm(aTHX_ SP, &mytm);
+ PUSHs(newSViv(mytm.tm_isdst));
+ PUTBACK;
+ {
+ SV ** endsp = SP; /* the SV * under SP needs to be mortaled */
+ SP -= (9 - 1); /* subtract 0 based count of SVs to mortal */
+/* mortal target of SP, then increment before function call
+ so SP is already calculated before next comparison to not stall CPU */
+ do {
+ sv_2mortal(*SP++);
+ } while(SP <= endsp);
+ }
+ return;
@@ -2,7 +2,7 @@ package Time::Seconds;
use strict;
use vars qw/@EXPORT @EXPORT_OK/;
-our $VERSION = '1.23';
+our $VERSION = '1.27';
use Exporter 5.57 'import';