summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dump.c1
-rw-r--r--embed.h1
-rw-r--r--ext/Opcode/Opcode.pm2
-rw-r--r--global.sym1
-rw-r--r--globals.c4
-rw-r--r--keywords.h193
-rwxr-xr-xkeywords.pl1
-rw-r--r--op.c10
-rw-r--r--op.h9
-rw-r--r--opcode.h639
-rwxr-xr-xopcode.pl1
-rw-r--r--pod/perlfunc.pod4
-rw-r--r--pp.c8
-rw-r--r--pp_hot.c10
-rw-r--r--pp_proto.h1
-rw-r--r--proto.h2
-rw-r--r--regcomp.c2
-rw-r--r--regexp.h4
-rw-r--r--sv.c31
-rwxr-xr-xt/op/pat.t27
-rw-r--r--toke.c29
21 files changed, 528 insertions, 452 deletions
diff --git a/dump.c b/dump.c
index c25bed934a..06273e51fe 100644
--- 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 6e8f5e9fb6..5bf672572f 100644
--- a/embed.h
+++ b/embed.h
@@ -689,6 +689,7 @@
#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
diff --git a/ext/Opcode/Opcode.pm b/ext/Opcode/Opcode.pm
index af1ab1db91..0ee6be6955 100644
--- a/ext/Opcode/Opcode.pm
+++ b/ext/Opcode/Opcode.pm
@@ -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
diff --git a/global.sym b/global.sym
index ff97e453e7..11f09f827e 100644
--- a/global.sym
+++ b/global.sym
@@ -756,6 +756,7 @@ pp_prtf
pp_push
pp_pushmark
pp_pushre
+pp_qr
pp_quotemeta
pp_rand
pp_range
diff --git a/globals.c b/globals.c
index ba4d872236..249e69b0b4 100644
--- 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,
diff --git a/keywords.h b/keywords.h
index 4b13795793..e818831148 100644
--- a/keywords.h
+++ b/keywords.h
@@ -151,99 +151,100 @@
#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
diff --git a/keywords.pl b/keywords.pl
index d1db4615ad..f907e3f115 100755
--- a/keywords.pl
+++ b/keywords.pl
@@ -177,6 +177,7 @@ prototype
push
q
qq
+qr
quotemeta
qw
qx
diff --git a/op.c b/op.c
index 58facaae07..ecefb838e0 100644
--- 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 9015028b6d..7a5d7a5992 100644
--- 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;
diff --git a/opcode.h b/opcode.h
index 04680c894f..a33e500900 100644
--- 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 */
diff --git a/opcode.pl b/opcode.pl
index 8544705b76..4ee7efe145 100755
--- 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
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index 3698c1f22d..7eaf69accb 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -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 64958c40c0..8625a3957e 100644
--- 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;
diff --git a/pp_hot.c b/pp_hot.c
index 42720a51cf..c721680e21 100644
--- 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;
diff --git a/pp_proto.h b/pp_proto.h
index fedb0dd850..ad82696849 100644
--- a/pp_proto.h
+++ b/pp_proto.h
@@ -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 ab57723c8a..9e99392bce 100644
--- 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));
diff --git a/regcomp.c b/regcomp.c
index 1d09aea409..ba67264432 100644
--- 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. */
diff --git a/regexp.h b/regexp.h
index a123efe02f..fbc92370b8 100644
--- 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 7390d9c3ed..41837fcfea 100644
--- 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;
}
diff --git a/t/op/pat.t b/t/op/pat.t
index 90623fbfca..46d2b91792 100755
--- a/t/op/pat.t
+++ b/t/op/pat.t
@@ -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 538625ed8a..db8775859a 100644
--- 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;