Mercurial > emacs
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: |