Finish the rest of the -X ops.
Ben Morrow [Sun, 18 Jan 2009 08:56:11 +0000 (08:56 +0000)]
pp.h
pp_sys.c

diff --git a/pp.h b/pp.h
index 5c25b55..a0714e9 100644 (file)
--- a/pp.h
+++ b/pp.h
@@ -471,19 +471,20 @@ Does not use C<TARG>.  See also C<XPUSHu>, C<mPUSHu> and C<PUSHu>.
 #define tryAMAGICunDEREF_var(meth_enum) \
        tryAMAGICunW_var(meth_enum,setAGAIN,0,(void)0)
 
-#define tryAMAGICftest(chr)                        \
-    STMT_START {                                   \
-       if (SvAMAGIC(TOPs)) {                       \
-           SV * const tmpsv = amagic_call(TOPs,    \
-               newSVpvn_flags(&chr, 1, SVs_TEMP),  \
-               ftest_amg, 0);                      \
-                                                   \
-           if (tmpsv) {                            \
-               SPAGAIN;                            \
-               SETs(tmpsv);                        \
-               RETURN;                             \
-           }                                       \
-       }                                           \
+#define tryAMAGICftest(chr)                            \
+    STMT_START {                                       \
+       if (SvAMAGIC(TOPs)) {                           \
+           const char tmpchr = (chr);                  \
+           SV * const tmpsv = amagic_call(TOPs,        \
+               newSVpvn_flags(&tmpchr, 1, SVs_TEMP),   \
+               ftest_amg, 0);                          \
+                                                       \
+           if (tmpsv) {                                \
+               SPAGAIN;                                \
+               SETs(tmpsv);                            \
+               RETURN;                                 \
+           }                                           \
+       }                                               \
     } STMT_END
 
 
index 1945b13..374e5c1 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -2983,7 +2983,7 @@ PP(pp_ftrread)
     int stat_mode = S_IRUSR;
 
     bool effective = FALSE;
-    char opchar;
+    char opchar = '?';
     dSP;
 
     STACKED_FTEST_CHECK;
@@ -3090,8 +3090,19 @@ PP(pp_ftis)
     dVAR;
     I32 result;
     const int op_type = PL_op->op_type;
+    char opchar = '?';
     dSP;
     STACKED_FTEST_CHECK;
+
+    switch (op_type) {
+    case OP_FTIS:      opchar = 'e'; break;
+    case OP_FTSIZE:    opchar = 's'; break;
+    case OP_FTMTIME:   opchar = 'M'; break;
+    case OP_FTCTIME:   opchar = 'C'; break;
+    case OP_FTATIME:   opchar = 'A'; break;
+    }
+    tryAMAGICftest(opchar);
+
     result = my_stat();
     SPAGAIN;
     if (result < 0)
@@ -3128,10 +3139,12 @@ PP(pp_ftrowned)
 {
     dVAR;
     I32 result;
+    char opchar = '?';
     dSP;
 
     /* I believe that all these three are likely to be defined on most every
        system these days.  */
+    if (!SvAMAGIC(TOPs)) {
 #ifndef S_ISUID
     if(PL_op->op_type == OP_FTSUID)
        RETPUSHNO;
@@ -3144,8 +3157,26 @@ PP(pp_ftrowned)
     if(PL_op->op_type == OP_FTSVTX)
        RETPUSHNO;
 #endif
+    }
 
     STACKED_FTEST_CHECK;
+
+    switch (PL_op->op_type) {
+    case OP_FTROWNED:  opchar = 'O'; break;
+    case OP_FTEOWNED:  opchar = 'o'; break;
+    case OP_FTZERO:    opchar = 'z'; break;
+    case OP_FTSOCK:    opchar = 'S'; break;
+    case OP_FTCHR:     opchar = 'c'; break;
+    case OP_FTBLK:     opchar = 'b'; break;
+    case OP_FTFILE:    opchar = 'f'; break;
+    case OP_FTDIR:     opchar = 'd'; break;
+    case OP_FTPIPE:    opchar = 'p'; break;
+    case OP_FTSUID:    opchar = 'u'; break;
+    case OP_FTSGID:    opchar = 'g'; break;
+    case OP_FTSVTX:    opchar = 'k'; break;
+    }
+    tryAMAGICftest(opchar);
+
     result = my_stat();
     SPAGAIN;
     if (result < 0)
@@ -3212,8 +3243,11 @@ PP(pp_ftrowned)
 PP(pp_ftlink)
 {
     dVAR;
-    I32 result = my_lstat();
+    I32 result;
     dSP;
+
+    tryAMAGICftest('l');
+    result = my_lstat();
     if (result < 0)
        RETPUSHUNDEF;
     if (S_ISLNK(PL_statcache.st_mode))
@@ -3231,6 +3265,8 @@ PP(pp_fttty)
 
     STACKED_FTEST_CHECK;
 
+    tryAMAGICftest('t');
+
     if (PL_op->op_flags & OPf_REF)
        gv = cGVOP_gv;
     else if (isGV(TOPs))
@@ -3280,6 +3316,8 @@ PP(pp_fttext)
 
     STACKED_FTEST_CHECK;
 
+    tryAMAGICftest(PL_op->op_type == OP_FTTEXT ? 'T' : 'B');
+
     if (PL_op->op_flags & OPf_REF)
        gv = cGVOP_gv;
     else if (isGV(TOPs))