diff 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
line wrap: on
line diff
--- a/src/regex.c	Fri Aug 25 13:21:46 2000 +0000
+++ b/src/regex.c	Fri Aug 25 14:35:12 2000 +0000
@@ -21,7 +21,10 @@
 
 /* TODO:
    - structure the opcode space into opcode+flag.
-   - merge with glibc's regex.[ch]
+   - merge with glibc's regex.[ch].
+   - replace succeed_n + jump_n with a combined operation so that the counter
+     can simply be decremented when popping the failure_point without having
+     to stack up failure_count entries.
  */
 
 /* AIX requires this to be the first thing in the file. */
@@ -1416,14 +1419,37 @@
   PUSH_FAILURE_INT (num);						\
 } while (0)
 
+#define PUSH_FAILURE_COUNT(ptr)						\
+do {									\
+  char *destination;							\
+  int c;								\
+  ENSURE_FAIL_STACK(3);							\
+  EXTRACT_NUMBER (c, ptr);						\
+  DEBUG_PRINT3 ("    Push counter %p = %d\n", ptr, c);			\
+  PUSH_FAILURE_INT (c);							\
+  PUSH_FAILURE_POINTER (ptr);						\
+  PUSH_FAILURE_INT (-1);						\
+} while (0)
+
 /* Pop a saved register off the stack.  */
-#define POP_FAILURE_REG()						\
+#define POP_FAILURE_REG_OR_COUNT()					\
 do {									\
   int reg = POP_FAILURE_INT ();						\
-  regend[reg] = POP_FAILURE_POINTER ();					\
-  regstart[reg] = POP_FAILURE_POINTER ();				\
-  DEBUG_PRINT4 ("     Pop reg %d (spanning %p -> %p)\n",		\
-		reg, regstart[reg], regend[reg]);			\
+  if (reg == -1)							\
+    {									\
+      /* It's a counter.  */						\
+      unsigned char *ptr = (unsigned char*) POP_FAILURE_POINTER ();	\
+      reg = POP_FAILURE_INT ();						\
+      STORE_NUMBER (ptr, reg);						\
+      DEBUG_PRINT3 ("     Pop counter %p = %d\n", ptr, reg);		\
+    }									\
+  else									\
+    {									\
+      regend[reg] = POP_FAILURE_POINTER ();				\
+      regstart[reg] = POP_FAILURE_POINTER ();				\
+      DEBUG_PRINT4 ("     Pop reg %d (spanning %p -> %p)\n",		\
+		    reg, regstart[reg], regend[reg]);			\
+    }									\
 } while (0)
 
 /* Check that we are not stuck in an infinite loop.  */
@@ -1517,7 +1543,7 @@
 									\
   /* Pop the saved registers.  */					\
   while (fail_stack.frame < fail_stack.avail)				\
-    POP_FAILURE_REG ();							\
+    POP_FAILURE_REG_OR_COUNT ();					\
 									\
   pat = (unsigned char *) POP_FAILURE_POINTER ();			\
   DEBUG_PRINT2 ("  Popping pattern %p: ", pat);				\
@@ -5217,22 +5243,18 @@
 	  EXTRACT_NUMBER (mcnt, p + 2);
 	  DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
 
-	  assert (mcnt >= 0);
-	  /* Originally, this is how many times we HAVE to succeed.  */
-	  if (mcnt > 0)
+	  /* Originally, mcnt is how many times we HAVE to succeed.  */
+	  if (mcnt != 0)
 	    {
-	       mcnt--;
-	       p += 2;
-	       STORE_NUMBER_AND_INCR (p, mcnt);
-	       DEBUG_PRINT3 ("	Setting %p to %d.\n", p, mcnt);
+	      mcnt--;
+	      p += 2;
+	      PUSH_FAILURE_COUNT (p);
+	      STORE_NUMBER_AND_INCR (p, mcnt);
+	      DEBUG_PRINT3 ("	Setting %p to %d.\n", p, mcnt);
 	    }
-	  else if (mcnt == 0)
-	    {
-	      DEBUG_PRINT2 ("  Setting two bytes from %p to no_op.\n", p+2);
-	      p[2] = (unsigned char) no_op;
-	      p[3] = (unsigned char) no_op;
-	      goto on_failure;
-	    }
+	  else
+	    /* The two bytes encoding mcnt == 0 are two no_op opcodes.  */
+	    goto on_failure;
 	  break;
 
 	case jump_n:
@@ -5240,11 +5262,12 @@
 	  DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
 
 	  /* Originally, this is how many times we CAN jump.  */
-	  if (mcnt)
+	  if (mcnt != 0)
 	    {
-	       mcnt--;
-	       STORE_NUMBER (p + 2, mcnt);
-	       goto unconditional_jump;
+	      mcnt--;
+	      PUSH_FAILURE_COUNT (p + 2);
+	      STORE_NUMBER (p + 2, mcnt);
+	      goto unconditional_jump;
 	    }
 	  /* If don't have to jump any more, skip over the rest of command.  */
 	  else
@@ -5259,6 +5282,7 @@
 	    p1 = p + mcnt;
 	    EXTRACT_NUMBER_AND_INCR (mcnt, p);
 	    DEBUG_PRINT3 ("  Setting %p to %d.\n", p1, mcnt);
+	    PUSH_FAILURE_COUNT (p1);
 	    STORE_NUMBER (p1, mcnt);
 	    break;
 	  }