comparison src/regex.c @ 31172:0ee53ec2081a

(PUSH_FAILURE_COUNT): New macro. (POP_FAILURE_REG_OR_COUNT): Renamed from POP_FAILURE_REG. Handle popping of a register's or a counter's data. (POP_FAILURE_POINT): Use the new name. (re_match_2_internal): Push counter data on the stack for succeed_n, jump_n and set_number_at and remove misleading dead code in succeed_n.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Fri, 25 Aug 2000 14:35:12 +0000
parents db737e34fc36
children 9efb8adfefa4
comparison
equal deleted inserted replaced
31171:b43c3984c06c 31172:0ee53ec2081a
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 USA. */ 20 USA. */
21 21
22 /* TODO: 22 /* TODO:
23 - structure the opcode space into opcode+flag. 23 - structure the opcode space into opcode+flag.
24 - merge with glibc's regex.[ch] 24 - merge with glibc's regex.[ch].
25 - replace succeed_n + jump_n with a combined operation so that the counter
26 can simply be decremented when popping the failure_point without having
27 to stack up failure_count entries.
25 */ 28 */
26 29
27 /* AIX requires this to be the first thing in the file. */ 30 /* AIX requires this to be the first thing in the file. */
28 #if defined (_AIX) && !defined (REGEX_MALLOC) 31 #if defined (_AIX) && !defined (REGEX_MALLOC)
29 #pragma alloca 32 #pragma alloca
1414 PUSH_FAILURE_POINTER (regstart[num]); \ 1417 PUSH_FAILURE_POINTER (regstart[num]); \
1415 PUSH_FAILURE_POINTER (regend[num]); \ 1418 PUSH_FAILURE_POINTER (regend[num]); \
1416 PUSH_FAILURE_INT (num); \ 1419 PUSH_FAILURE_INT (num); \
1417 } while (0) 1420 } while (0)
1418 1421
1422 #define PUSH_FAILURE_COUNT(ptr) \
1423 do { \
1424 char *destination; \
1425 int c; \
1426 ENSURE_FAIL_STACK(3); \
1427 EXTRACT_NUMBER (c, ptr); \
1428 DEBUG_PRINT3 (" Push counter %p = %d\n", ptr, c); \
1429 PUSH_FAILURE_INT (c); \
1430 PUSH_FAILURE_POINTER (ptr); \
1431 PUSH_FAILURE_INT (-1); \
1432 } while (0)
1433
1419 /* Pop a saved register off the stack. */ 1434 /* Pop a saved register off the stack. */
1420 #define POP_FAILURE_REG() \ 1435 #define POP_FAILURE_REG_OR_COUNT() \
1421 do { \ 1436 do { \
1422 int reg = POP_FAILURE_INT (); \ 1437 int reg = POP_FAILURE_INT (); \
1423 regend[reg] = POP_FAILURE_POINTER (); \ 1438 if (reg == -1) \
1424 regstart[reg] = POP_FAILURE_POINTER (); \ 1439 { \
1425 DEBUG_PRINT4 (" Pop reg %d (spanning %p -> %p)\n", \ 1440 /* It's a counter. */ \
1426 reg, regstart[reg], regend[reg]); \ 1441 unsigned char *ptr = (unsigned char*) POP_FAILURE_POINTER (); \
1442 reg = POP_FAILURE_INT (); \
1443 STORE_NUMBER (ptr, reg); \
1444 DEBUG_PRINT3 (" Pop counter %p = %d\n", ptr, reg); \
1445 } \
1446 else \
1447 { \
1448 regend[reg] = POP_FAILURE_POINTER (); \
1449 regstart[reg] = POP_FAILURE_POINTER (); \
1450 DEBUG_PRINT4 (" Pop reg %d (spanning %p -> %p)\n", \
1451 reg, regstart[reg], regend[reg]); \
1452 } \
1427 } while (0) 1453 } while (0)
1428 1454
1429 /* Check that we are not stuck in an infinite loop. */ 1455 /* Check that we are not stuck in an infinite loop. */
1430 #define CHECK_INFINITE_LOOP(pat_cur, string_place) \ 1456 #define CHECK_INFINITE_LOOP(pat_cur, string_place) \
1431 do { \ 1457 do { \
1515 DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ 1541 DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
1516 DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ 1542 DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
1517 \ 1543 \
1518 /* Pop the saved registers. */ \ 1544 /* Pop the saved registers. */ \
1519 while (fail_stack.frame < fail_stack.avail) \ 1545 while (fail_stack.frame < fail_stack.avail) \
1520 POP_FAILURE_REG (); \ 1546 POP_FAILURE_REG_OR_COUNT (); \
1521 \ 1547 \
1522 pat = (unsigned char *) POP_FAILURE_POINTER (); \ 1548 pat = (unsigned char *) POP_FAILURE_POINTER (); \
1523 DEBUG_PRINT2 (" Popping pattern %p: ", pat); \ 1549 DEBUG_PRINT2 (" Popping pattern %p: ", pat); \
1524 DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ 1550 DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
1525 \ 1551 \
5215 After that, handle like `on_failure_jump'. */ 5241 After that, handle like `on_failure_jump'. */
5216 case succeed_n: 5242 case succeed_n:
5217 EXTRACT_NUMBER (mcnt, p + 2); 5243 EXTRACT_NUMBER (mcnt, p + 2);
5218 DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); 5244 DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
5219 5245
5220 assert (mcnt >= 0); 5246 /* Originally, mcnt is how many times we HAVE to succeed. */
5221 /* Originally, this is how many times we HAVE to succeed. */ 5247 if (mcnt != 0)
5222 if (mcnt > 0)
5223 { 5248 {
5224 mcnt--; 5249 mcnt--;
5225 p += 2; 5250 p += 2;
5226 STORE_NUMBER_AND_INCR (p, mcnt); 5251 PUSH_FAILURE_COUNT (p);
5227 DEBUG_PRINT3 (" Setting %p to %d.\n", p, mcnt); 5252 STORE_NUMBER_AND_INCR (p, mcnt);
5253 DEBUG_PRINT3 (" Setting %p to %d.\n", p, mcnt);
5228 } 5254 }
5229 else if (mcnt == 0) 5255 else
5230 { 5256 /* The two bytes encoding mcnt == 0 are two no_op opcodes. */
5231 DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", p+2); 5257 goto on_failure;
5232 p[2] = (unsigned char) no_op;
5233 p[3] = (unsigned char) no_op;
5234 goto on_failure;
5235 }
5236 break; 5258 break;
5237 5259
5238 case jump_n: 5260 case jump_n:
5239 EXTRACT_NUMBER (mcnt, p + 2); 5261 EXTRACT_NUMBER (mcnt, p + 2);
5240 DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); 5262 DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
5241 5263
5242 /* Originally, this is how many times we CAN jump. */ 5264 /* Originally, this is how many times we CAN jump. */
5243 if (mcnt) 5265 if (mcnt != 0)
5244 { 5266 {
5245 mcnt--; 5267 mcnt--;
5246 STORE_NUMBER (p + 2, mcnt); 5268 PUSH_FAILURE_COUNT (p + 2);
5247 goto unconditional_jump; 5269 STORE_NUMBER (p + 2, mcnt);
5270 goto unconditional_jump;
5248 } 5271 }
5249 /* If don't have to jump any more, skip over the rest of command. */ 5272 /* If don't have to jump any more, skip over the rest of command. */
5250 else 5273 else
5251 p += 4; 5274 p += 4;
5252 break; 5275 break;
5257 5280
5258 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5281 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5259 p1 = p + mcnt; 5282 p1 = p + mcnt;
5260 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5283 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5261 DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt); 5284 DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt);
5285 PUSH_FAILURE_COUNT (p1);
5262 STORE_NUMBER (p1, mcnt); 5286 STORE_NUMBER (p1, mcnt);
5263 break; 5287 break;
5264 } 5288 }
5265 5289
5266 case wordbound: 5290 case wordbound: