diff options
-rw-r--r-- | dump.c | 1 | ||||
-rw-r--r-- | embed.h | 1 | ||||
-rw-r--r-- | ext/Opcode/Opcode.pm | 2 | ||||
-rw-r--r-- | global.sym | 1 | ||||
-rw-r--r-- | globals.c | 4 | ||||
-rw-r--r-- | keywords.h | 193 | ||||
-rwxr-xr-x | keywords.pl | 1 | ||||
-rw-r--r-- | op.c | 10 | ||||
-rw-r--r-- | op.h | 9 | ||||
-rw-r--r-- | opcode.h | 639 | ||||
-rwxr-xr-x | opcode.pl | 1 | ||||
-rw-r--r-- | pod/perlfunc.pod | 4 | ||||
-rw-r--r-- | pp.c | 8 | ||||
-rw-r--r-- | pp_hot.c | 10 | ||||
-rw-r--r-- | pp_proto.h | 1 | ||||
-rw-r--r-- | proto.h | 2 | ||||
-rw-r--r-- | regcomp.c | 2 | ||||
-rw-r--r-- | regexp.h | 4 | ||||
-rw-r--r-- | sv.c | 31 | ||||
-rwxr-xr-x | t/op/pat.t | 27 | ||||
-rw-r--r-- | toke.c | 29 |
21 files changed, 528 insertions, 452 deletions
@@ -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; @@ -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 @@ -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 @@ -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++; @@ -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; @@ -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 */ @@ -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/ @@ -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; @@ -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) @@ -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)); @@ -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. */ @@ -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) @@ -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'; @@ -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; |