This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge the implementations of POSIX::{asctime,mktime} using ALIAS.
authorNicholas Clark <nick@ccl4.org>
Fri, 9 Sep 2011 21:55:25 +0000 (23:55 +0200)
committerNicholas Clark <nick@ccl4.org>
Tue, 13 Sep 2011 09:28:09 +0000 (11:28 +0200)
This shares identical code marshaling 6 to 9 input arguments into a
struct tm. However, as the return types differ we have to explicitly code
pushing the return value onto perl's stack.

ext/POSIX/POSIX.xs

index 7284299..175b242 100644 (file)
@@ -1742,7 +1742,7 @@ tcflow(fd, action)
     OUTPUT:
        RETVAL
 
-char *
+void
 asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
        int             sec
        int             min
@@ -1753,8 +1753,11 @@ asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
        int             wday
        int             yday
        int             isdst
-    CODE:
+    ALIAS:
+       mktime = 1
+    PPCODE:
        {
+           dXSTARG;
            struct tm mytm;
            init_tm(&mytm);     /* XXX workaround - see init_tm() above */
            mytm.tm_sec = sec;
@@ -1766,10 +1769,20 @@ asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
            mytm.tm_wday = wday;
            mytm.tm_yday = yday;
            mytm.tm_isdst = isdst;
-           RETVAL = asctime(&mytm);
+           if (ix) {
+               const long result = mktime(&mytm);
+               if (result == -1)
+                   SvOK_off(TARG);
+               else if (result == 0)
+                   sv_setpvn(TARG, "0 but true", 10);
+               else
+                   sv_setiv(TARG, (IV)result);
+           } else {
+               sv_setpv(TARG, asctime(&mytm));
+           }
+           ST(0) = TARG;
+           XSRETURN(1);
        }
-    OUTPUT:
-       RETVAL
 
 long
 clock()
@@ -1796,35 +1809,6 @@ difftime(time1, time2)
        Time_t          time1
        Time_t          time2
 
-SysRetLong
-mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = -1)
-       int             sec
-       int             min
-       int             hour
-       int             mday
-       int             mon
-       int             year
-       int             wday
-       int             yday
-       int             isdst
-    CODE:
-       {
-           struct tm mytm;
-           init_tm(&mytm);     /* XXX workaround - see init_tm() above */
-           mytm.tm_sec = sec;
-           mytm.tm_min = min;
-           mytm.tm_hour = hour;
-           mytm.tm_mday = mday;
-           mytm.tm_mon = mon;
-           mytm.tm_year = year;
-           mytm.tm_wday = wday;
-           mytm.tm_yday = yday;
-           mytm.tm_isdst = isdst;
-           RETVAL = (SysRetLong) mktime(&mytm);
-       }
-    OUTPUT:
-       RETVAL
-
 #XXX: if $xsubpp::WantOptimize is always the default
 #     sv_setpv(TARG, ...) could be used rather than
 #     ST(0) = sv_2mortal(newSVpv(...))