added patch, tweaked PERL_OBJECT things
Graham Barr [Sun, 12 Jul 1998 19:57:47 +0000 (14:57 -0500)]
Message-Id: <19980712195747.C493@pobox.com>
Subject: [ PATCH perl5.004_72] patch to add qr//

p4raw-id: //depot/perl@1461

21 files changed:
dump.c
embed.h
ext/Opcode/Opcode.pm
global.sym
globals.c
keywords.h
keywords.pl
op.c
op.h
opcode.h
opcode.pl
pod/perlfunc.pod
pp.c
pp_hot.c
pp_proto.h
proto.h
regcomp.c
regexp.h
sv.c
t/op/pat.t
toke.c

diff --git a/dump.c b/dump.c
index c25bed9..06273e5 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -300,6 +300,7 @@ dump_op(OP *o)
        break;
     case OP_PUSHRE:
     case OP_MATCH:
+    case OP_QR:
     case OP_SUBST:
        dump_pm(cPMOPo);
        break;
diff --git a/embed.h b/embed.h
index 6e8f5e9..5bf6725 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define pp_push                        Perl_pp_push
 #define pp_pushmark            Perl_pp_pushmark
 #define pp_pushre              Perl_pp_pushre
+#define pp_qr                  Perl_pp_qr
 #define pp_quotemeta           Perl_pp_quotemeta
 #define pp_rand                        Perl_pp_rand
 #define pp_range               Perl_pp_range
index af1ab1d..0ee6be6 100644 (file)
@@ -326,7 +326,7 @@ invert_opset function.
 
     ucfirst lcfirst uc lc quotemeta trans chop schop chomp schomp
 
-    match split
+    match split qr
 
     list lslice splice push pop shift unshift reverse
 
index ff97e45..11f09f8 100644 (file)
@@ -756,6 +756,7 @@ pp_prtf
 pp_push
 pp_pushmark
 pp_pushre
+pp_qr
 pp_quotemeta
 pp_rand
 pp_range
index ba4d872..249e69b 100644 (file)
--- a/globals.c
+++ b/globals.c
@@ -66,6 +66,8 @@
 #define pp_regcomp     CPerlObj::Perl_pp_regcomp
 #undef  pp_match       
 #define pp_match       CPerlObj::Perl_pp_match
+#undef  pp_qr
+#define pp_qr          CPerlObj::Perl_pp_qr
 #undef  pp_subst       
 #define pp_subst       CPerlObj::Perl_pp_subst
 #undef  pp_substcont   
@@ -730,6 +732,7 @@ OP * (CPERLscope(*check)[]) _((OP *op)) = {
        ck_fun,         /* regcreset */
        ck_null,        /* regcomp */
        ck_match,       /* match */
+       ck_match,       /* qr */
        ck_null,        /* subst */
        ck_null,        /* substcont */
        ck_null,        /* trans */
@@ -1080,6 +1083,7 @@ OP * (CPERLscope(*ppaddr)[])(ARGSproto) = {
        pp_regcreset,
        pp_regcomp,
        pp_match,
+       pp_qr,
        pp_subst,
        pp_substcont,
        pp_trans,
index 4b13795..e818831 100644 (file)
 #define KEY_push               150
 #define KEY_q                  151
 #define KEY_qq                 152
-#define KEY_quotemeta          153
-#define KEY_qw                 154
-#define KEY_qx                 155
-#define KEY_rand               156
-#define KEY_read               157
-#define KEY_readdir            158
-#define KEY_readline           159
-#define KEY_readlink           160
-#define KEY_readpipe           161
-#define KEY_recv               162
-#define KEY_redo               163
-#define KEY_ref                        164
-#define KEY_rename             165
-#define KEY_require            166
-#define KEY_reset              167
-#define KEY_return             168
-#define KEY_reverse            169
-#define KEY_rewinddir          170
-#define KEY_rindex             171
-#define KEY_rmdir              172
-#define KEY_s                  173
-#define KEY_scalar             174
-#define KEY_seek               175
-#define KEY_seekdir            176
-#define KEY_select             177
-#define KEY_semctl             178
-#define KEY_semget             179
-#define KEY_semop              180
-#define KEY_send               181
-#define KEY_setgrent           182
-#define KEY_sethostent         183
-#define KEY_setnetent          184
-#define KEY_setpgrp            185
-#define KEY_setpriority                186
-#define KEY_setprotoent                187
-#define KEY_setpwent           188
-#define KEY_setservent         189
-#define KEY_setsockopt         190
-#define KEY_shift              191
-#define KEY_shmctl             192
-#define KEY_shmget             193
-#define KEY_shmread            194
-#define KEY_shmwrite           195
-#define KEY_shutdown           196
-#define KEY_sin                        197
-#define KEY_sleep              198
-#define KEY_socket             199
-#define KEY_socketpair         200
-#define KEY_sort               201
-#define KEY_splice             202
-#define KEY_split              203
-#define KEY_sprintf            204
-#define KEY_sqrt               205
-#define KEY_srand              206
-#define KEY_stat               207
-#define KEY_study              208
-#define KEY_sub                        209
-#define KEY_substr             210
-#define KEY_symlink            211
-#define KEY_syscall            212
-#define KEY_sysopen            213
-#define KEY_sysread            214
-#define KEY_sysseek            215
-#define KEY_system             216
-#define KEY_syswrite           217
-#define KEY_tell               218
-#define KEY_telldir            219
-#define KEY_tie                        220
-#define KEY_tied               221
-#define KEY_time               222
-#define KEY_times              223
-#define KEY_tr                 224
-#define KEY_truncate           225
-#define KEY_uc                 226
-#define KEY_ucfirst            227
-#define KEY_umask              228
-#define KEY_undef              229
-#define KEY_unless             230
-#define KEY_unlink             231
-#define KEY_unpack             232
-#define KEY_unshift            233
-#define KEY_untie              234
-#define KEY_until              235
-#define KEY_use                        236
-#define KEY_utime              237
-#define KEY_values             238
-#define KEY_vec                        239
-#define KEY_wait               240
-#define KEY_waitpid            241
-#define KEY_wantarray          242
-#define KEY_warn               243
-#define KEY_while              244
-#define KEY_write              245
-#define KEY_x                  246
-#define KEY_xor                        247
-#define KEY_y                  248
+#define KEY_qr                 153
+#define KEY_quotemeta          154
+#define KEY_qw                 155
+#define KEY_qx                 156
+#define KEY_rand               157
+#define KEY_read               158
+#define KEY_readdir            159
+#define KEY_readline           160
+#define KEY_readlink           161
+#define KEY_readpipe           162
+#define KEY_recv               163
+#define KEY_redo               164
+#define KEY_ref                        165
+#define KEY_rename             166
+#define KEY_require            167
+#define KEY_reset              168
+#define KEY_return             169
+#define KEY_reverse            170
+#define KEY_rewinddir          171
+#define KEY_rindex             172
+#define KEY_rmdir              173
+#define KEY_s                  174
+#define KEY_scalar             175
+#define KEY_seek               176
+#define KEY_seekdir            177
+#define KEY_select             178
+#define KEY_semctl             179
+#define KEY_semget             180
+#define KEY_semop              181
+#define KEY_send               182
+#define KEY_setgrent           183
+#define KEY_sethostent         184
+#define KEY_setnetent          185
+#define KEY_setpgrp            186
+#define KEY_setpriority                187
+#define KEY_setprotoent                188
+#define KEY_setpwent           189
+#define KEY_setservent         190
+#define KEY_setsockopt         191
+#define KEY_shift              192
+#define KEY_shmctl             193
+#define KEY_shmget             194
+#define KEY_shmread            195
+#define KEY_shmwrite           196
+#define KEY_shutdown           197
+#define KEY_sin                        198
+#define KEY_sleep              199
+#define KEY_socket             200
+#define KEY_socketpair         201
+#define KEY_sort               202
+#define KEY_splice             203
+#define KEY_split              204
+#define KEY_sprintf            205
+#define KEY_sqrt               206
+#define KEY_srand              207
+#define KEY_stat               208
+#define KEY_study              209
+#define KEY_sub                        210
+#define KEY_substr             211
+#define KEY_symlink            212
+#define KEY_syscall            213
+#define KEY_sysopen            214
+#define KEY_sysread            215
+#define KEY_sysseek            216
+#define KEY_system             217
+#define KEY_syswrite           218
+#define KEY_tell               219
+#define KEY_telldir            220
+#define KEY_tie                        221
+#define KEY_tied               222
+#define KEY_time               223
+#define KEY_times              224
+#define KEY_tr                 225
+#define KEY_truncate           226
+#define KEY_uc                 227
+#define KEY_ucfirst            228
+#define KEY_umask              229
+#define KEY_undef              230
+#define KEY_unless             231
+#define KEY_unlink             232
+#define KEY_unpack             233
+#define KEY_unshift            234
+#define KEY_untie              235
+#define KEY_until              236
+#define KEY_use                        237
+#define KEY_utime              238
+#define KEY_values             239
+#define KEY_vec                        240
+#define KEY_wait               241
+#define KEY_waitpid            242
+#define KEY_wantarray          243
+#define KEY_warn               244
+#define KEY_while              245
+#define KEY_write              246
+#define KEY_x                  247
+#define KEY_xor                        248
+#define KEY_y                  249
index d1db461..f907e3f 100755 (executable)
@@ -177,6 +177,7 @@ prototype
 push
 q
 qq
+qr
 quotemeta
 qw
 qx
diff --git a/op.c b/op.c
index 58facaa..ecefb83 100644 (file)
--- a/op.c
+++ b/op.c
@@ -619,6 +619,7 @@ op_free(OP *o)
        /* FALL THROUGH */
     case OP_PUSHRE:
     case OP_MATCH:
+    case OP_QR:
        ReREFCNT_dec(cPMOPo->op_pmregexp);
        break;
     }
@@ -725,6 +726,7 @@ scalar(OP *o)
        }
        /* FALL THROUGH */
     case OP_MATCH:
+    case OP_QR:
     case OP_SUBST:
     case OP_NULL:
     default:
@@ -983,6 +985,7 @@ list(OP *o)
        break;
     default:
     case OP_MATCH:
+    case OP_QR:
     case OP_SUBST:
     case OP_NULL:
        if (!(o->op_flags & OPf_KIDS))
@@ -1980,12 +1983,6 @@ newUNOP(I32 type, I32 flags, OP *first)
     unop->op_first = first;
     unop->op_flags = flags | OPf_KIDS;
     unop->op_private = 1 | (flags >> 8);
-#if 1
-    if(type == OP_STUDY && first->op_type == OP_MATCH) {
-       first->op_type = OP_PUSHRE;
-       first->op_ppaddr = ppaddr[OP_PUSHRE];
-    }
-#endif
     unop = (UNOP*) CHECKOP(type, unop);
     if (unop->op_next)
        return (OP*)unop;
@@ -5031,6 +5028,7 @@ peep(register OP *o)
            peep(cLOOP->op_lastop);
            break;
 
+       case OP_QR:
        case OP_MATCH:
        case OP_SUBST:
            o->op_seq = op_seqmax++;
diff --git a/op.h b/op.h
index 9015028..7a5d7a5 100644 (file)
--- a/op.h
+++ b/op.h
@@ -196,18 +196,21 @@ struct pmop {
 #define PMf_REVERSED   0x0004          /* Should be matched right->left */
 #define PMf_MAYBE_CONST        0x0008          /* replacement contains variables */
 #define PMf_SKIPWHITE  0x0010          /* skip leading whitespace for split */
-#define PMf_FOLD       0x0020          /* case insensitivity */
+#define PMf_WHITE      0x0020          /* pattern is \s+ */
 #define PMf_CONST      0x0040          /* subst replacement is constant */
 #define PMf_KEEP       0x0080          /* keep 1st runtime pattern forever */
 #define PMf_GLOBAL     0x0100          /* pattern had a g modifier */
 #define PMf_CONTINUE   0x0200          /* don't reset pos() if //g fails */
 #define PMf_EVAL       0x0400          /* evaluating replacement as expr */
-#define PMf_WHITE      0x0800          /* pattern is \s+ */
+#define PMf_LOCALE     0x0800          /* use locale for character types */
 #define PMf_MULTILINE  0x1000          /* assume multiple lines */
 #define PMf_SINGLELINE 0x2000          /* assume single line */
-#define PMf_LOCALE     0x4000          /* use locale for character types */
+#define PMf_FOLD       0x4000          /* case insensitivity */
 #define PMf_EXTENDED   0x8000          /* chuck embedded whitespace */
 
+/* mask of bits stored in regexp->reganch */
+#define PMf_COMPILETIME        (PMf_MULTILINE|PMf_SINGLELINE|PMf_LOCALE|PMf_FOLD|PMf_EXTENDED)
+
 struct svop {
     BASEOP
     SV *       op_sv;
index 04680c8..a33e500 100644 (file)
--- a/opcode.h
+++ b/opcode.h
@@ -36,325 +36,326 @@ typedef enum {
        OP_REGCRESET,   /* 29 */
        OP_REGCOMP,     /* 30 */
        OP_MATCH,       /* 31 */
-       OP_SUBST,       /* 32 */
-       OP_SUBSTCONT,   /* 33 */
-       OP_TRANS,       /* 34 */
-       OP_SASSIGN,     /* 35 */
-       OP_AASSIGN,     /* 36 */
-       OP_CHOP,        /* 37 */
-       OP_SCHOP,       /* 38 */
-       OP_CHOMP,       /* 39 */
-       OP_SCHOMP,      /* 40 */
-       OP_DEFINED,     /* 41 */
-       OP_UNDEF,       /* 42 */
-       OP_STUDY,       /* 43 */
-       OP_POS,         /* 44 */
-       OP_PREINC,      /* 45 */
-       OP_I_PREINC,    /* 46 */
-       OP_PREDEC,      /* 47 */
-       OP_I_PREDEC,    /* 48 */
-       OP_POSTINC,     /* 49 */
-       OP_I_POSTINC,   /* 50 */
-       OP_POSTDEC,     /* 51 */
-       OP_I_POSTDEC,   /* 52 */
-       OP_POW,         /* 53 */
-       OP_MULTIPLY,    /* 54 */
-       OP_I_MULTIPLY,  /* 55 */
-       OP_DIVIDE,      /* 56 */
-       OP_I_DIVIDE,    /* 57 */
-       OP_MODULO,      /* 58 */
-       OP_I_MODULO,    /* 59 */
-       OP_REPEAT,      /* 60 */
-       OP_ADD,         /* 61 */
-       OP_I_ADD,       /* 62 */
-       OP_SUBTRACT,    /* 63 */
-       OP_I_SUBTRACT,  /* 64 */
-       OP_CONCAT,      /* 65 */
-       OP_STRINGIFY,   /* 66 */
-       OP_LEFT_SHIFT,  /* 67 */
-       OP_RIGHT_SHIFT, /* 68 */
-       OP_LT,          /* 69 */
-       OP_I_LT,        /* 70 */
-       OP_GT,          /* 71 */
-       OP_I_GT,        /* 72 */
-       OP_LE,          /* 73 */
-       OP_I_LE,        /* 74 */
-       OP_GE,          /* 75 */
-       OP_I_GE,        /* 76 */
-       OP_EQ,          /* 77 */
-       OP_I_EQ,        /* 78 */
-       OP_NE,          /* 79 */
-       OP_I_NE,        /* 80 */
-       OP_NCMP,        /* 81 */
-       OP_I_NCMP,      /* 82 */
-       OP_SLT,         /* 83 */
-       OP_SGT,         /* 84 */
-       OP_SLE,         /* 85 */
-       OP_SGE,         /* 86 */
-       OP_SEQ,         /* 87 */
-       OP_SNE,         /* 88 */
-       OP_SCMP,        /* 89 */
-       OP_BIT_AND,     /* 90 */
-       OP_BIT_XOR,     /* 91 */
-       OP_BIT_OR,      /* 92 */
-       OP_NEGATE,      /* 93 */
-       OP_I_NEGATE,    /* 94 */
-       OP_NOT,         /* 95 */
-       OP_COMPLEMENT,  /* 96 */
-       OP_ATAN2,       /* 97 */
-       OP_SIN,         /* 98 */
-       OP_COS,         /* 99 */
-       OP_RAND,        /* 100 */
-       OP_SRAND,       /* 101 */
-       OP_EXP,         /* 102 */
-       OP_LOG,         /* 103 */
-       OP_SQRT,        /* 104 */
-       OP_INT,         /* 105 */
-       OP_HEX,         /* 106 */
-       OP_OCT,         /* 107 */
-       OP_ABS,         /* 108 */
-       OP_LENGTH,      /* 109 */
-       OP_SUBSTR,      /* 110 */
-       OP_VEC,         /* 111 */
-       OP_INDEX,       /* 112 */
-       OP_RINDEX,      /* 113 */
-       OP_SPRINTF,     /* 114 */
-       OP_FORMLINE,    /* 115 */
-       OP_ORD,         /* 116 */
-       OP_CHR,         /* 117 */
-       OP_CRYPT,       /* 118 */
-       OP_UCFIRST,     /* 119 */
-       OP_LCFIRST,     /* 120 */
-       OP_UC,          /* 121 */
-       OP_LC,          /* 122 */
-       OP_QUOTEMETA,   /* 123 */
-       OP_RV2AV,       /* 124 */
-       OP_AELEMFAST,   /* 125 */
-       OP_AELEM,       /* 126 */
-       OP_ASLICE,      /* 127 */
-       OP_EACH,        /* 128 */
-       OP_VALUES,      /* 129 */
-       OP_KEYS,        /* 130 */
-       OP_DELETE,      /* 131 */
-       OP_EXISTS,      /* 132 */
-       OP_RV2HV,       /* 133 */
-       OP_HELEM,       /* 134 */
-       OP_HSLICE,      /* 135 */
-       OP_UNPACK,      /* 136 */
-       OP_PACK,        /* 137 */
-       OP_SPLIT,       /* 138 */
-       OP_JOIN,        /* 139 */
-       OP_LIST,        /* 140 */
-       OP_LSLICE,      /* 141 */
-       OP_ANONLIST,    /* 142 */
-       OP_ANONHASH,    /* 143 */
-       OP_SPLICE,      /* 144 */
-       OP_PUSH,        /* 145 */
-       OP_POP,         /* 146 */
-       OP_SHIFT,       /* 147 */
-       OP_UNSHIFT,     /* 148 */
-       OP_SORT,        /* 149 */
-       OP_REVERSE,     /* 150 */
-       OP_GREPSTART,   /* 151 */
-       OP_GREPWHILE,   /* 152 */
-       OP_MAPSTART,    /* 153 */
-       OP_MAPWHILE,    /* 154 */
-       OP_RANGE,       /* 155 */
-       OP_FLIP,        /* 156 */
-       OP_FLOP,        /* 157 */
-       OP_AND,         /* 158 */
-       OP_OR,          /* 159 */
-       OP_XOR,         /* 160 */
-       OP_COND_EXPR,   /* 161 */
-       OP_ANDASSIGN,   /* 162 */
-       OP_ORASSIGN,    /* 163 */
-       OP_METHOD,      /* 164 */
-       OP_ENTERSUB,    /* 165 */
-       OP_LEAVESUB,    /* 166 */
-       OP_CALLER,      /* 167 */
-       OP_WARN,        /* 168 */
-       OP_DIE,         /* 169 */
-       OP_RESET,       /* 170 */
-       OP_LINESEQ,     /* 171 */
-       OP_NEXTSTATE,   /* 172 */
-       OP_DBSTATE,     /* 173 */
-       OP_UNSTACK,     /* 174 */
-       OP_ENTER,       /* 175 */
-       OP_LEAVE,       /* 176 */
-       OP_SCOPE,       /* 177 */
-       OP_ENTERITER,   /* 178 */
-       OP_ITER,        /* 179 */
-       OP_ENTERLOOP,   /* 180 */
-       OP_LEAVELOOP,   /* 181 */
-       OP_RETURN,      /* 182 */
-       OP_LAST,        /* 183 */
-       OP_NEXT,        /* 184 */
-       OP_REDO,        /* 185 */
-       OP_DUMP,        /* 186 */
-       OP_GOTO,        /* 187 */
-       OP_EXIT,        /* 188 */
-       OP_OPEN,        /* 189 */
-       OP_CLOSE,       /* 190 */
-       OP_PIPE_OP,     /* 191 */
-       OP_FILENO,      /* 192 */
-       OP_UMASK,       /* 193 */
-       OP_BINMODE,     /* 194 */
-       OP_TIE,         /* 195 */
-       OP_UNTIE,       /* 196 */
-       OP_TIED,        /* 197 */
-       OP_DBMOPEN,     /* 198 */
-       OP_DBMCLOSE,    /* 199 */
-       OP_SSELECT,     /* 200 */
-       OP_SELECT,      /* 201 */
-       OP_GETC,        /* 202 */
-       OP_READ,        /* 203 */
-       OP_ENTERWRITE,  /* 204 */
-       OP_LEAVEWRITE,  /* 205 */
-       OP_PRTF,        /* 206 */
-       OP_PRINT,       /* 207 */
-       OP_SYSOPEN,     /* 208 */
-       OP_SYSSEEK,     /* 209 */
-       OP_SYSREAD,     /* 210 */
-       OP_SYSWRITE,    /* 211 */
-       OP_SEND,        /* 212 */
-       OP_RECV,        /* 213 */
-       OP_EOF,         /* 214 */
-       OP_TELL,        /* 215 */
-       OP_SEEK,        /* 216 */
-       OP_TRUNCATE,    /* 217 */
-       OP_FCNTL,       /* 218 */
-       OP_IOCTL,       /* 219 */
-       OP_FLOCK,       /* 220 */
-       OP_SOCKET,      /* 221 */
-       OP_SOCKPAIR,    /* 222 */
-       OP_BIND,        /* 223 */
-       OP_CONNECT,     /* 224 */
-       OP_LISTEN,      /* 225 */
-       OP_ACCEPT,      /* 226 */
-       OP_SHUTDOWN,    /* 227 */
-       OP_GSOCKOPT,    /* 228 */
-       OP_SSOCKOPT,    /* 229 */
-       OP_GETSOCKNAME, /* 230 */
-       OP_GETPEERNAME, /* 231 */
-       OP_LSTAT,       /* 232 */
-       OP_STAT,        /* 233 */
-       OP_FTRREAD,     /* 234 */
-       OP_FTRWRITE,    /* 235 */
-       OP_FTREXEC,     /* 236 */
-       OP_FTEREAD,     /* 237 */
-       OP_FTEWRITE,    /* 238 */
-       OP_FTEEXEC,     /* 239 */
-       OP_FTIS,        /* 240 */
-       OP_FTEOWNED,    /* 241 */
-       OP_FTROWNED,    /* 242 */
-       OP_FTZERO,      /* 243 */
-       OP_FTSIZE,      /* 244 */
-       OP_FTMTIME,     /* 245 */
-       OP_FTATIME,     /* 246 */
-       OP_FTCTIME,     /* 247 */
-       OP_FTSOCK,      /* 248 */
-       OP_FTCHR,       /* 249 */
-       OP_FTBLK,       /* 250 */
-       OP_FTFILE,      /* 251 */
-       OP_FTDIR,       /* 252 */
-       OP_FTPIPE,      /* 253 */
-       OP_FTLINK,      /* 254 */
-       OP_FTSUID,      /* 255 */
-       OP_FTSGID,      /* 256 */
-       OP_FTSVTX,      /* 257 */
-       OP_FTTTY,       /* 258 */
-       OP_FTTEXT,      /* 259 */
-       OP_FTBINARY,    /* 260 */
-       OP_CHDIR,       /* 261 */
-       OP_CHOWN,       /* 262 */
-       OP_CHROOT,      /* 263 */
-       OP_UNLINK,      /* 264 */
-       OP_CHMOD,       /* 265 */
-       OP_UTIME,       /* 266 */
-       OP_RENAME,      /* 267 */
-       OP_LINK,        /* 268 */
-       OP_SYMLINK,     /* 269 */
-       OP_READLINK,    /* 270 */
-       OP_MKDIR,       /* 271 */
-       OP_RMDIR,       /* 272 */
-       OP_OPEN_DIR,    /* 273 */
-       OP_READDIR,     /* 274 */
-       OP_TELLDIR,     /* 275 */
-       OP_SEEKDIR,     /* 276 */
-       OP_REWINDDIR,   /* 277 */
-       OP_CLOSEDIR,    /* 278 */
-       OP_FORK,        /* 279 */
-       OP_WAIT,        /* 280 */
-       OP_WAITPID,     /* 281 */
-       OP_SYSTEM,      /* 282 */
-       OP_EXEC,        /* 283 */
-       OP_KILL,        /* 284 */
-       OP_GETPPID,     /* 285 */
-       OP_GETPGRP,     /* 286 */
-       OP_SETPGRP,     /* 287 */
-       OP_GETPRIORITY, /* 288 */
-       OP_SETPRIORITY, /* 289 */
-       OP_TIME,        /* 290 */
-       OP_TMS,         /* 291 */
-       OP_LOCALTIME,   /* 292 */
-       OP_GMTIME,      /* 293 */
-       OP_ALARM,       /* 294 */
-       OP_SLEEP,       /* 295 */
-       OP_SHMGET,      /* 296 */
-       OP_SHMCTL,      /* 297 */
-       OP_SHMREAD,     /* 298 */
-       OP_SHMWRITE,    /* 299 */
-       OP_MSGGET,      /* 300 */
-       OP_MSGCTL,      /* 301 */
-       OP_MSGSND,      /* 302 */
-       OP_MSGRCV,      /* 303 */
-       OP_SEMGET,      /* 304 */
-       OP_SEMCTL,      /* 305 */
-       OP_SEMOP,       /* 306 */
-       OP_REQUIRE,     /* 307 */
-       OP_DOFILE,      /* 308 */
-       OP_ENTEREVAL,   /* 309 */
-       OP_LEAVEEVAL,   /* 310 */
-       OP_ENTERTRY,    /* 311 */
-       OP_LEAVETRY,    /* 312 */
-       OP_GHBYNAME,    /* 313 */
-       OP_GHBYADDR,    /* 314 */
-       OP_GHOSTENT,    /* 315 */
-       OP_GNBYNAME,    /* 316 */
-       OP_GNBYADDR,    /* 317 */
-       OP_GNETENT,     /* 318 */
-       OP_GPBYNAME,    /* 319 */
-       OP_GPBYNUMBER,  /* 320 */
-       OP_GPROTOENT,   /* 321 */
-       OP_GSBYNAME,    /* 322 */
-       OP_GSBYPORT,    /* 323 */
-       OP_GSERVENT,    /* 324 */
-       OP_SHOSTENT,    /* 325 */
-       OP_SNETENT,     /* 326 */
-       OP_SPROTOENT,   /* 327 */
-       OP_SSERVENT,    /* 328 */
-       OP_EHOSTENT,    /* 329 */
-       OP_ENETENT,     /* 330 */
-       OP_EPROTOENT,   /* 331 */
-       OP_ESERVENT,    /* 332 */
-       OP_GPWNAM,      /* 333 */
-       OP_GPWUID,      /* 334 */
-       OP_GPWENT,      /* 335 */
-       OP_SPWENT,      /* 336 */
-       OP_EPWENT,      /* 337 */
-       OP_GGRNAM,      /* 338 */
-       OP_GGRGID,      /* 339 */
-       OP_GGRENT,      /* 340 */
-       OP_SGRENT,      /* 341 */
-       OP_EGRENT,      /* 342 */
-       OP_GETLOGIN,    /* 343 */
-       OP_SYSCALL,     /* 344 */
-       OP_LOCK,        /* 345 */
-       OP_THREADSV,    /* 346 */
+       OP_QR,          /* 32 */
+       OP_SUBST,       /* 33 */
+       OP_SUBSTCONT,   /* 34 */
+       OP_TRANS,       /* 35 */
+       OP_SASSIGN,     /* 36 */
+       OP_AASSIGN,     /* 37 */
+       OP_CHOP,        /* 38 */
+       OP_SCHOP,       /* 39 */
+       OP_CHOMP,       /* 40 */
+       OP_SCHOMP,      /* 41 */
+       OP_DEFINED,     /* 42 */
+       OP_UNDEF,       /* 43 */
+       OP_STUDY,       /* 44 */
+       OP_POS,         /* 45 */
+       OP_PREINC,      /* 46 */
+       OP_I_PREINC,    /* 47 */
+       OP_PREDEC,      /* 48 */
+       OP_I_PREDEC,    /* 49 */
+       OP_POSTINC,     /* 50 */
+       OP_I_POSTINC,   /* 51 */
+       OP_POSTDEC,     /* 52 */
+       OP_I_POSTDEC,   /* 53 */
+       OP_POW,         /* 54 */
+       OP_MULTIPLY,    /* 55 */
+       OP_I_MULTIPLY,  /* 56 */
+       OP_DIVIDE,      /* 57 */
+       OP_I_DIVIDE,    /* 58 */
+       OP_MODULO,      /* 59 */
+       OP_I_MODULO,    /* 60 */
+       OP_REPEAT,      /* 61 */
+       OP_ADD,         /* 62 */
+       OP_I_ADD,       /* 63 */
+       OP_SUBTRACT,    /* 64 */
+       OP_I_SUBTRACT,  /* 65 */
+       OP_CONCAT,      /* 66 */
+       OP_STRINGIFY,   /* 67 */
+       OP_LEFT_SHIFT,  /* 68 */
+       OP_RIGHT_SHIFT, /* 69 */
+       OP_LT,          /* 70 */
+       OP_I_LT,        /* 71 */
+       OP_GT,          /* 72 */
+       OP_I_GT,        /* 73 */
+       OP_LE,          /* 74 */
+       OP_I_LE,        /* 75 */
+       OP_GE,          /* 76 */
+       OP_I_GE,        /* 77 */
+       OP_EQ,          /* 78 */
+       OP_I_EQ,        /* 79 */
+       OP_NE,          /* 80 */
+       OP_I_NE,        /* 81 */
+       OP_NCMP,        /* 82 */
+       OP_I_NCMP,      /* 83 */
+       OP_SLT,         /* 84 */
+       OP_SGT,         /* 85 */
+       OP_SLE,         /* 86 */
+       OP_SGE,         /* 87 */
+       OP_SEQ,         /* 88 */
+       OP_SNE,         /* 89 */
+       OP_SCMP,        /* 90 */
+       OP_BIT_AND,     /* 91 */
+       OP_BIT_XOR,     /* 92 */
+       OP_BIT_OR,      /* 93 */
+       OP_NEGATE,      /* 94 */
+       OP_I_NEGATE,    /* 95 */
+       OP_NOT,         /* 96 */
+       OP_COMPLEMENT,  /* 97 */
+       OP_ATAN2,       /* 98 */
+       OP_SIN,         /* 99 */
+       OP_COS,         /* 100 */
+       OP_RAND,        /* 101 */
+       OP_SRAND,       /* 102 */
+       OP_EXP,         /* 103 */
+       OP_LOG,         /* 104 */
+       OP_SQRT,        /* 105 */
+       OP_INT,         /* 106 */
+       OP_HEX,         /* 107 */
+       OP_OCT,         /* 108 */
+       OP_ABS,         /* 109 */
+       OP_LENGTH,      /* 110 */
+       OP_SUBSTR,      /* 111 */
+       OP_VEC,         /* 112 */
+       OP_INDEX,       /* 113 */
+       OP_RINDEX,      /* 114 */
+       OP_SPRINTF,     /* 115 */
+       OP_FORMLINE,    /* 116 */
+       OP_ORD,         /* 117 */
+       OP_CHR,         /* 118 */
+       OP_CRYPT,       /* 119 */
+       OP_UCFIRST,     /* 120 */
+       OP_LCFIRST,     /* 121 */
+       OP_UC,          /* 122 */
+       OP_LC,          /* 123 */
+       OP_QUOTEMETA,   /* 124 */
+       OP_RV2AV,       /* 125 */
+       OP_AELEMFAST,   /* 126 */
+       OP_AELEM,       /* 127 */
+       OP_ASLICE,      /* 128 */
+       OP_EACH,        /* 129 */
+       OP_VALUES,      /* 130 */
+       OP_KEYS,        /* 131 */
+       OP_DELETE,      /* 132 */
+       OP_EXISTS,      /* 133 */
+       OP_RV2HV,       /* 134 */
+       OP_HELEM,       /* 135 */
+       OP_HSLICE,      /* 136 */
+       OP_UNPACK,      /* 137 */
+       OP_PACK,        /* 138 */
+       OP_SPLIT,       /* 139 */
+       OP_JOIN,        /* 140 */
+       OP_LIST,        /* 141 */
+       OP_LSLICE,      /* 142 */
+       OP_ANONLIST,    /* 143 */
+       OP_ANONHASH,    /* 144 */
+       OP_SPLICE,      /* 145 */
+       OP_PUSH,        /* 146 */
+       OP_POP,         /* 147 */
+       OP_SHIFT,       /* 148 */
+       OP_UNSHIFT,     /* 149 */
+       OP_SORT,        /* 150 */
+       OP_REVERSE,     /* 151 */
+       OP_GREPSTART,   /* 152 */
+       OP_GREPWHILE,   /* 153 */
+       OP_MAPSTART,    /* 154 */
+       OP_MAPWHILE,    /* 155 */
+       OP_RANGE,       /* 156 */
+       OP_FLIP,        /* 157 */
+       OP_FLOP,        /* 158 */
+       OP_AND,         /* 159 */
+       OP_OR,          /* 160 */
+       OP_XOR,         /* 161 */
+       OP_COND_EXPR,   /* 162 */
+       OP_ANDASSIGN,   /* 163 */
+       OP_ORASSIGN,    /* 164 */
+       OP_METHOD,      /* 165 */
+       OP_ENTERSUB,    /* 166 */
+       OP_LEAVESUB,    /* 167 */
+       OP_CALLER,      /* 168 */
+       OP_WARN,        /* 169 */
+       OP_DIE,         /* 170 */
+       OP_RESET,       /* 171 */
+       OP_LINESEQ,     /* 172 */
+       OP_NEXTSTATE,   /* 173 */
+       OP_DBSTATE,     /* 174 */
+       OP_UNSTACK,     /* 175 */
+       OP_ENTER,       /* 176 */
+       OP_LEAVE,       /* 177 */
+       OP_SCOPE,       /* 178 */
+       OP_ENTERITER,   /* 179 */
+       OP_ITER,        /* 180 */
+       OP_ENTERLOOP,   /* 181 */
+       OP_LEAVELOOP,   /* 182 */
+       OP_RETURN,      /* 183 */
+       OP_LAST,        /* 184 */
+       OP_NEXT,        /* 185 */
+       OP_REDO,        /* 186 */
+       OP_DUMP,        /* 187 */
+       OP_GOTO,        /* 188 */
+       OP_EXIT,        /* 189 */
+       OP_OPEN,        /* 190 */
+       OP_CLOSE,       /* 191 */
+       OP_PIPE_OP,     /* 192 */
+       OP_FILENO,      /* 193 */
+       OP_UMASK,       /* 194 */
+       OP_BINMODE,     /* 195 */
+       OP_TIE,         /* 196 */
+       OP_UNTIE,       /* 197 */
+       OP_TIED,        /* 198 */
+       OP_DBMOPEN,     /* 199 */
+       OP_DBMCLOSE,    /* 200 */
+       OP_SSELECT,     /* 201 */
+       OP_SELECT,      /* 202 */
+       OP_GETC,        /* 203 */
+       OP_READ,        /* 204 */
+       OP_ENTERWRITE,  /* 205 */
+       OP_LEAVEWRITE,  /* 206 */
+       OP_PRTF,        /* 207 */
+       OP_PRINT,       /* 208 */
+       OP_SYSOPEN,     /* 209 */
+       OP_SYSSEEK,     /* 210 */
+       OP_SYSREAD,     /* 211 */
+       OP_SYSWRITE,    /* 212 */
+       OP_SEND,        /* 213 */
+       OP_RECV,        /* 214 */
+       OP_EOF,         /* 215 */
+       OP_TELL,        /* 216 */
+       OP_SEEK,        /* 217 */
+       OP_TRUNCATE,    /* 218 */
+       OP_FCNTL,       /* 219 */
+       OP_IOCTL,       /* 220 */
+       OP_FLOCK,       /* 221 */
+       OP_SOCKET,      /* 222 */
+       OP_SOCKPAIR,    /* 223 */
+       OP_BIND,        /* 224 */
+       OP_CONNECT,     /* 225 */
+       OP_LISTEN,      /* 226 */
+       OP_ACCEPT,      /* 227 */
+       OP_SHUTDOWN,    /* 228 */
+       OP_GSOCKOPT,    /* 229 */
+       OP_SSOCKOPT,    /* 230 */
+       OP_GETSOCKNAME, /* 231 */
+       OP_GETPEERNAME, /* 232 */
+       OP_LSTAT,       /* 233 */
+       OP_STAT,        /* 234 */
+       OP_FTRREAD,     /* 235 */
+       OP_FTRWRITE,    /* 236 */
+       OP_FTREXEC,     /* 237 */
+       OP_FTEREAD,     /* 238 */
+       OP_FTEWRITE,    /* 239 */
+       OP_FTEEXEC,     /* 240 */
+       OP_FTIS,        /* 241 */
+       OP_FTEOWNED,    /* 242 */
+       OP_FTROWNED,    /* 243 */
+       OP_FTZERO,      /* 244 */
+       OP_FTSIZE,      /* 245 */
+       OP_FTMTIME,     /* 246 */
+       OP_FTATIME,     /* 247 */
+       OP_FTCTIME,     /* 248 */
+       OP_FTSOCK,      /* 249 */
+       OP_FTCHR,       /* 250 */
+       OP_FTBLK,       /* 251 */
+       OP_FTFILE,      /* 252 */
+       OP_FTDIR,       /* 253 */
+       OP_FTPIPE,      /* 254 */
+       OP_FTLINK,      /* 255 */
+       OP_FTSUID,      /* 256 */
+       OP_FTSGID,      /* 257 */
+       OP_FTSVTX,      /* 258 */
+       OP_FTTTY,       /* 259 */
+       OP_FTTEXT,      /* 260 */
+       OP_FTBINARY,    /* 261 */
+       OP_CHDIR,       /* 262 */
+       OP_CHOWN,       /* 263 */
+       OP_CHROOT,      /* 264 */
+       OP_UNLINK,      /* 265 */
+       OP_CHMOD,       /* 266 */
+       OP_UTIME,       /* 267 */
+       OP_RENAME,      /* 268 */
+       OP_LINK,        /* 269 */
+       OP_SYMLINK,     /* 270 */
+       OP_READLINK,    /* 271 */
+       OP_MKDIR,       /* 272 */
+       OP_RMDIR,       /* 273 */
+       OP_OPEN_DIR,    /* 274 */
+       OP_READDIR,     /* 275 */
+       OP_TELLDIR,     /* 276 */
+       OP_SEEKDIR,     /* 277 */
+       OP_REWINDDIR,   /* 278 */
+       OP_CLOSEDIR,    /* 279 */
+       OP_FORK,        /* 280 */
+       OP_WAIT,        /* 281 */
+       OP_WAITPID,     /* 282 */
+       OP_SYSTEM,      /* 283 */
+       OP_EXEC,        /* 284 */
+       OP_KILL,        /* 285 */
+       OP_GETPPID,     /* 286 */
+       OP_GETPGRP,     /* 287 */
+       OP_SETPGRP,     /* 288 */
+       OP_GETPRIORITY, /* 289 */
+       OP_SETPRIORITY, /* 290 */
+       OP_TIME,        /* 291 */
+       OP_TMS,         /* 292 */
+       OP_LOCALTIME,   /* 293 */
+       OP_GMTIME,      /* 294 */
+       OP_ALARM,       /* 295 */
+       OP_SLEEP,       /* 296 */
+       OP_SHMGET,      /* 297 */
+       OP_SHMCTL,      /* 298 */
+       OP_SHMREAD,     /* 299 */
+       OP_SHMWRITE,    /* 300 */
+       OP_MSGGET,      /* 301 */
+       OP_MSGCTL,      /* 302 */
+       OP_MSGSND,      /* 303 */
+       OP_MSGRCV,      /* 304 */
+       OP_SEMGET,      /* 305 */
+       OP_SEMCTL,      /* 306 */
+       OP_SEMOP,       /* 307 */
+       OP_REQUIRE,     /* 308 */
+       OP_DOFILE,      /* 309 */
+       OP_ENTEREVAL,   /* 310 */
+       OP_LEAVEEVAL,   /* 311 */
+       OP_ENTERTRY,    /* 312 */
+       OP_LEAVETRY,    /* 313 */
+       OP_GHBYNAME,    /* 314 */
+       OP_GHBYADDR,    /* 315 */
+       OP_GHOSTENT,    /* 316 */
+       OP_GNBYNAME,    /* 317 */
+       OP_GNBYADDR,    /* 318 */
+       OP_GNETENT,     /* 319 */
+       OP_GPBYNAME,    /* 320 */
+       OP_GPBYNUMBER,  /* 321 */
+       OP_GPROTOENT,   /* 322 */
+       OP_GSBYNAME,    /* 323 */
+       OP_GSBYPORT,    /* 324 */
+       OP_GSERVENT,    /* 325 */
+       OP_SHOSTENT,    /* 326 */
+       OP_SNETENT,     /* 327 */
+       OP_SPROTOENT,   /* 328 */
+       OP_SSERVENT,    /* 329 */
+       OP_EHOSTENT,    /* 330 */
+       OP_ENETENT,     /* 331 */
+       OP_EPROTOENT,   /* 332 */
+       OP_ESERVENT,    /* 333 */
+       OP_GPWNAM,      /* 334 */
+       OP_GPWUID,      /* 335 */
+       OP_GPWENT,      /* 336 */
+       OP_SPWENT,      /* 337 */
+       OP_EPWENT,      /* 338 */
+       OP_GGRNAM,      /* 339 */
+       OP_GGRGID,      /* 340 */
+       OP_GGRENT,      /* 341 */
+       OP_SGRENT,      /* 342 */
+       OP_EGRENT,      /* 343 */
+       OP_GETLOGIN,    /* 344 */
+       OP_SYSCALL,     /* 345 */
+       OP_LOCK,        /* 346 */
+       OP_THREADSV,    /* 347 */
        OP_max          
 } opcode;
 
-#define MAXO 347
+#define MAXO 348
 
 #ifndef DOINIT
 EXT char *op_name[];
@@ -392,6 +393,7 @@ EXT char *op_name[] = {
        "regcreset",
        "regcomp",
        "match",
+       "qr",
        "subst",
        "substcont",
        "trans",
@@ -746,6 +748,7 @@ EXT char *op_desc[] = {
        "regexp reset interpolation flag",
        "regexp compilation",
        "pattern match",
+       "pattern quote",
        "substitution",
        "substitution cont",
        "character translation",
@@ -1132,6 +1135,7 @@ OP *      pp_regcmaybe    _((ARGSproto));
 OP *   pp_regcreset    _((ARGSproto));
 OP *   pp_regcomp      _((ARGSproto));
 OP *   pp_match        _((ARGSproto));
+OP *   pp_qr           _((ARGSproto));
 OP *   pp_subst        _((ARGSproto));
 OP *   pp_substcont    _((ARGSproto));
 OP *   pp_trans        _((ARGSproto));
@@ -1488,6 +1492,7 @@ EXT OP * (CPERLscope(*ppaddr)[])(ARGSproto) = {
        pp_regcreset,
        pp_regcomp,
        pp_match,
+       pp_qr,
        pp_subst,
        pp_substcont,
        pp_trans,
@@ -1844,6 +1849,7 @@ EXT OP * (CPERLscope(*check)[]) _((OP *op)) = {
        ck_fun,         /* regcreset */
        ck_null,        /* regcomp */
        ck_match,       /* match */
+       ck_match,       /* qr */
        ck_null,        /* subst */
        ck_null,        /* substcont */
        ck_null,        /* trans */
@@ -2199,6 +2205,7 @@ EXT U32 opargs[] = {
        0x00001104,     /* regcreset */
        0x00001304,     /* regcomp */
        0x00000640,     /* match */
+       0x00000004,     /* qr */
        0x00001654,     /* subst */
        0x00000354,     /* substcont */
        0x00001914,     /* trans */
index 8544705..4ee7efe 100755 (executable)
--- a/opcode.pl
+++ b/opcode.pl
@@ -277,6 +277,7 @@ regcmaybe   regexp comp once        ck_fun          s1      S
 regcreset      regexp reset interpolation flag ck_fun          s1      S
 regcomp                regexp compilation      ck_null         s|      S
 match          pattern match           ck_match        d/
+qr             pattern quote           ck_match        s0
 subst          substitution            ck_null         dis/    S
 substcont      substitution cont       ck_null         dis|    
 trans          character translation   ck_null         is"     S
index 3698c1f..7eaf69a 100644 (file)
@@ -95,7 +95,7 @@ C<rindex>, C<sprintf>, C<substr>, C<tr///>, C<uc>, C<ucfirst>, C<y>///
 
 =item Regular expressions and pattern matching
 
-C<m>//, C<pos>, C<quotemeta>, C<s>///, C<split>, C<study>
+C<m>//, C<pos>, C<quotemeta>, C<s>///, C<split>, C<study>, C<qr//>
 
 =item Numeric functions
 
@@ -2618,6 +2618,8 @@ but is more efficient.  Returns the new number of elements in the array.
 
 =item qq/STRING/
 
+=item qr/STRING/
+
 =item qx/STRING/
 
 =item qw/STRING/
diff --git a/pp.c b/pp.c
index 64958c4..8625a39 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -601,14 +601,6 @@ PP(pp_study)
     register I32 *snext;
     STRLEN len;
 
-    if(unop->op_first && unop->op_first->op_type == OP_PUSHRE) {
-       PMOP *pm = (PMOP *)unop->op_first;
-       SV *rv = sv_newmortal();
-       sv = newSVrv(rv, "Regexp");
-       sv_magic(sv,(SV*)ReREFCNT_inc(pm->op_pmregexp),'r',0,0);
-       RETURNX(PUSHs(rv));
-    }
-
     if (sv == lastscream) {
        if (SvSCREAM(sv))
            RETPUSHYES;
index 42720a5..c721680 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -780,6 +780,16 @@ PP(pp_aassign)
     RETURN;
 }
 
+PP(pp_qr)
+{
+    djSP;
+    register PMOP *pm = cPMOP;
+    SV *rv = sv_newmortal();
+    SV *sv = newSVrv(rv, "Regexp");
+    sv_magic(sv,(SV*)ReREFCNT_inc(pm->op_pmregexp),'r',0,0);
+    RETURNX(PUSHs(rv));
+}
+
 PP(pp_match)
 {
     djSP; dTARG;
index fedb0dd..ad82696 100644 (file)
@@ -30,6 +30,7 @@ PPDEF(pp_regcmaybe)
 PPDEF(pp_regcreset)
 PPDEF(pp_regcomp)
 PPDEF(pp_match)
+PPDEF(pp_qr)
 PPDEF(pp_subst)
 PPDEF(pp_substcont)
 PPDEF(pp_trans)
diff --git a/proto.h b/proto.h
index ab57723..9e99392 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -726,7 +726,7 @@ char *scan_formline _((char *s));
 char *scan_heredoc _((char *s));
 char *scan_ident _((char *s, char *send, char *dest, STRLEN destlen, I32 ck_uni));
 char *scan_inputsymbol _((char *start));
-char *scan_pat _((char *start));
+char *scan_pat _((char *start, I32 type));
 char *scan_str _((char *start));
 char *scan_subst _((char *start));
 char *scan_trans _((char *start));
index 1d09aea..ba67264 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -799,8 +799,8 @@ pregcomp(char *exp, char *xend, PMOP *pm)
        return(NULL);
 
     /* Dig out information for optimizations. */
+    r->reganch = pm->op_pmflags & PMf_COMPILETIME;
     pm->op_pmflags = regflags;
-    r->reganch = 0;
     r->regstclass = NULL;
     r->naughty = regnaughty >= 10;     /* Probably an expensive pattern. */
     scan = r->program + 1;             /* First BRANCH. */
index a123efe..fbc9237 100644 (file)
--- a/regexp.h
+++ b/regexp.h
@@ -86,8 +86,8 @@ typedef struct regexp {
 #define ROPT_CHECK_ALL         0x80
 #define ROPT_LOOKBEHIND_SEEN   0x100
 #define ROPT_EVAL_SEEN         0x200
-
-#define ROPT_TAINTED_SEEN      0x8000
+#define ROPT_TAINTED_SEEN      0x400
+/* 0xf800 of reganch is used by PMf_COMPILETIME */
 
 #define RX_MATCH_TAINTED(prog) ((prog)->reganch & ROPT_TAINTED_SEEN)
 #define RX_MATCH_TAINTED_on(prog) ((prog)->reganch |= ROPT_TAINTED_SEEN)
diff --git a/sv.c b/sv.c
index 7390d9c..41837fc 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1710,10 +1710,33 @@ sv_2pv(register SV *sv, STRLEN *lp)
                        regexp *re = (regexp *)mg->mg_obj;
 
                        if (!mg->mg_ptr) {
-                           mg->mg_len = re->prelen + 4;
-                           New(616, mg->mg_ptr, mg->mg_len + 1, char);
-                           Copy("(?:", mg->mg_ptr, 3, char);
-                           Copy(re->precomp, mg->mg_ptr+3, re->prelen, char);
+                           char *fptr = "msix";
+                           char reflags[6];
+                           char ch;
+                           int left = 0;
+                           int right = 4;
+                           U16 reganch = (re->reganch & PMf_COMPILETIME) >> 12;
+
+                           while(ch = *fptr++) {
+                               if(reganch & 1) {
+                                   reflags[left++] = ch;
+                               }
+                               else {
+                                   reflags[right--] = ch;
+                               }
+                               reganch >>= 1;
+                           }
+                           if(left != 4) {
+                               reflags[left] = '-';
+                               left = 5;
+                           }
+
+                           mg->mg_len = re->prelen + 4 + left;
+                           New(616, mg->mg_ptr, mg->mg_len + 1 + left, char);
+                           Copy("(?", mg->mg_ptr, 2, char);
+                           Copy(reflags, mg->mg_ptr+2, left, char);
+                           Copy(":", mg->mg_ptr+left+2, 1, char);
+                           Copy(re->precomp, mg->mg_ptr+3+left, re->prelen, char);
                            mg->mg_ptr[mg->mg_len - 1] = ')';
                            mg->mg_ptr[mg->mg_len] = 0;
                        }
index 90623fb..46d2b91 100755 (executable)
@@ -6,7 +6,7 @@
 
 # $RCSfile: pat.t,v $$Revision: 4.1 $$Date: 92/08/07 18:28:12 $
 
-print "1..130\n";
+print "1..135\n";
 
 BEGIN {
     chdir 't' if -d 't';
@@ -450,8 +450,27 @@ print "not " unless $^R eq '79' and $x eq '12';
 print "ok $test\n";
 $test++;
 
-# This should be changed to qr/\b\v$/ ASAP
-print "not " unless study(/\b\v$/) eq '(?:\bv$)';
+print "not " unless qr/\b\v$/i eq '(?i-xsm:\bv$)';
+print "ok $test\n";
+$test++;
+
+print "not " unless qr/\b\v$/s eq '(?s-xim:\bv$)';
+print "ok $test\n";
+$test++;
+
+print "not " unless qr/\b\v$/m eq '(?m-xis:\bv$)';
+print "ok $test\n";
+$test++;
+
+print "not " unless qr/\b\v$/x eq '(?x-ism:\bv$)';
+print "ok $test\n";
+$test++;
+
+print "not " unless qr/\b\v$/xism eq '(?msix:\bv$)';
+print "ok $test\n";
+$test++;
+
+print "not " unless qr/\b\v$/ eq '(?-xism:\bv$)';
 print "ok $test\n";
 $test++;
 
@@ -487,7 +506,7 @@ print "not " unless $1 and /$1/;
 print "ok $test\n";
 $test++;
 
-$a=study/(?{++$b})/; 
+$a=qr/(?{++$b})/; 
 $b = 7;
 /$a$a/; 
 print "not " unless $b eq '9'; 
diff --git a/toke.c b/toke.c
index 538625e..db87758 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -28,7 +28,7 @@ static char *scan_heredoc _((char *s));
 static char *scan_ident _((char *s, char *send, char *dest, STRLEN destlen,
                           I32 ck_uni));
 static char *scan_inputsymbol _((char *start));
-static char *scan_pat _((char *start));
+static char *scan_pat _((char *start, I32 type));
 static char *scan_str _((char *start));
 static char *scan_subst _((char *start));
 static char *scan_trans _((char *start));
@@ -710,7 +710,7 @@ sublex_push(void)
     curcop->cop_line = multi_start;
 
     lex_inwhat = sublex_info.sub_inwhat;
-    if (lex_inwhat == OP_MATCH || lex_inwhat == OP_SUBST)
+    if (lex_inwhat == OP_MATCH || lex_inwhat == OP_QR || lex_inwhat == OP_SUBST)
        lex_inpat = sublex_info.sub_op;
     else
        lex_inpat = Nullop;
@@ -2651,7 +2651,7 @@ yylex(void)
                && (*last_uni != 's' || s - last_uni < 5 
                    || memNE(last_uni, "study", 5) || isALNUM(last_uni[5])))
                check_uni();
-           s = scan_pat(s);
+           s = scan_pat(s,OP_MATCH);
            TERM(sublex_start());
        }
        tmp = *s++;
@@ -2792,7 +2792,7 @@ yylex(void)
        tmp = (len == 1 && strchr("msyq", tokenbuf[0]) ||
               len == 2 && ((tokenbuf[0] == 't' && tokenbuf[1] == 'r') ||
                            (tokenbuf[0] == 'q' &&
-                            strchr("qwx", tokenbuf[1]))));
+                            strchr("qwxr", tokenbuf[1]))));
 
        /* x::* is just a word, unless x is "CORE" */
        if (!tmp && *s == ':' && s[1] == ':' && strNE(tokenbuf, "CORE"))
@@ -3500,7 +3500,7 @@ yylex(void)
            UNI(OP_LSTAT);
 
        case KEY_m:
-           s = scan_pat(s);
+           s = scan_pat(s,OP_MATCH);
            TERM(sublex_start());
 
        case KEY_map:
@@ -3661,6 +3661,10 @@ yylex(void)
                SvIVX(lex_stuff) = 0;   /* qq'$foo' should intepolate */
            TERM(sublex_start());
 
+       case KEY_qr:
+           s = scan_pat(s,OP_QR);
+           TERM(sublex_start());
+
        case KEY_qx:
            s = scan_str(s);
            if (!s)
@@ -4458,6 +4462,7 @@ keyword(register char *d, I32 len)
     case 'q':
        if (len <= 2) {
            if (strEQ(d,"q"))                   return KEY_q;
+           if (strEQ(d,"qr"))                  return KEY_qr;
            if (strEQ(d,"qq"))                  return KEY_qq;
            if (strEQ(d,"qw"))                  return KEY_qw;
            if (strEQ(d,"qx"))                  return KEY_qx;
@@ -4967,7 +4972,7 @@ void pmflag(U16 *pmfl, int ch)
 }
 
 STATIC char *
-scan_pat(char *start)
+scan_pat(char *start, I32 type)
 {
     PMOP *pm;
     char *s;
@@ -4980,11 +4985,17 @@ scan_pat(char *start)
        croak("Search pattern not terminated");
     }
 
-    pm = (PMOP*)newPMOP(OP_MATCH, 0);
+    pm = (PMOP*)newPMOP(type, 0);
     if (multi_open == '?')
        pm->op_pmflags |= PMf_ONCE;
-    while (*s && strchr("iogcmsx", *s))
-       pmflag(&pm->op_pmflags,*s++);
+    if(type == OP_QR) {
+       while (*s && strchr("iomsx", *s))
+           pmflag(&pm->op_pmflags,*s++);
+    }
+    else {
+       while (*s && strchr("iogcmsx", *s))
+           pmflag(&pm->op_pmflags,*s++);
+    }
     pm->op_pmpermflags = pm->op_pmflags;
 
     lex_op = (OP*)pm;