[Python-checkins] python/dist/src/Modules _sre.c,2.95,2.96

niemeyer@users.sourceforge.net niemeyer@users.sourceforge.net
Sun, 27 Apr 2003 07:42:58 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv15677/Modules

Modified Files:
	_sre.c 
Log Message:
- Included detailed documentation in _sre.c explaining how, when, and why
  to use LASTMARK_SAVE()/LASTMARK_RESTORE(), based on the discussion
  in patch #712900.

- Cleaned up LASTMARK_SAVE()/LASTMARK_RESTORE() usage, based on the
  established rules.

- Moved the upper part of the just commited patch (relative to bug #725106)
  to outside the for() loop of BRANCH OP. There's no need to mark_save()
  in every loop iteration.


Index: _sre.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v
retrieving revision 2.95
retrieving revision 2.96
diff -C2 -d -r2.95 -r2.96
*** _sre.c	27 Apr 2003 13:25:21 -0000	2.95
--- _sre.c	27 Apr 2003 14:42:54 -0000	2.96
***************
*** 689,693 ****
  #endif
  
! /* macros to preserve lastmark in case of backtracking */
  #define LASTMARK_SAVE()     \
      do { \
--- 689,720 ----
  #endif
  
! /* The macros below should be used to protect recursive SRE_MATCH()
!  * calls that *failed* and do *not* return immediately (IOW, those
!  * that will backtrack). Explaining:
!  *
!  * - Recursive SRE_MATCH() returned true: that's usually a success
!  *   (besides atypical cases like ASSERT_NOT), therefore there's no
!  *   reason to restore lastmark;
!  *
!  * - Recursive SRE_MATCH() returned false but the current SRE_MATCH()
!  *   is returning to the caller: If the current SRE_MATCH() is the
!  *   top function of the recursion, returning false will be a matching
!  *   failure, and it doesn't matter where lastmark is pointing to.
!  *   If it's *not* the top function, it will be a recursive SRE_MATCH()
!  *   failure by itself, and the calling SRE_MATCH() will have to deal
!  *   with the failure by the same rules explained here (it will restore
!  *   lastmark by itself if necessary);
!  *
!  * - Recursive SRE_MATCH() returned false, and will continue the
!  *   outside 'for' loop: must be protected when breaking, since the next
!  *   OP could potentially depend on lastmark;
!  *   
!  * - Recursive SRE_MATCH() returned false, and will be called again
!  *   inside a local for/while loop: must be protected between each
!  *   loop iteration, since the recursive SRE_MATCH() could do anything,
!  *   and could potentially depend on lastmark.
!  *
!  * For more information, check the discussion at SF patch #712900.
!  */
  #define LASTMARK_SAVE()     \
      do { \
***************
*** 943,946 ****
--- 970,978 ----
              TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
              LASTMARK_SAVE();
+             if (state->repeat) {
+                 i = mark_save(state, 0, lastmark, &mark_stack_base);
+                 if (i < 0)
+                     return i;
+             }
              for (; pattern[0]; pattern += pattern[0]) {
                  if (pattern[1] == SRE_OP_LITERAL &&
***************
*** 950,958 ****
                      (ptr >= end || !SRE_CHARSET(pattern + 3, (SRE_CODE) *ptr)))
                      continue;
-                 if (state->repeat) {
-                     i = mark_save(state, 0, lastmark, &mark_stack_base);
-                     if (i < 0)
-                         return i;
-                 }
                  state->ptr = ptr;
                  i = SRE_MATCH(state, pattern + 1, level + 1);
--- 982,985 ----
***************
*** 1093,1097 ****
                      if (c < 0)
                          return c;
-                     LASTMARK_RESTORE();
                      if (c == 0)
                          break;
--- 1120,1123 ----
***************
*** 1099,1102 ****
--- 1125,1129 ----
                      ptr++;
                      count++;
+                     LASTMARK_RESTORE();
                  }
              }
***************
*** 1141,1146 ****
              TRACE(("|%p|%p|MAX_UNTIL %d\n", pattern, ptr, count));
  
-             LASTMARK_SAVE();
- 
              if (count < rp->pattern[1]) {
                  /* not enough matches */
--- 1168,1171 ----
***************
*** 1152,1156 ****
                  rp->count = count - 1;
                  state->ptr = ptr;
-                 LASTMARK_RESTORE();
                  return 0;
              }
--- 1177,1180 ----
***************
*** 1160,1163 ****
--- 1184,1188 ----
                     match another item, do so */
                  rp->count = count;
+                 LASTMARK_SAVE();
                  i = mark_save(state, 0, lastmark, &mark_stack_base);
                  if (i < 0)
***************
*** 1168,1174 ****
                      return i;
                  i = mark_restore(state, 0, lastmark, &mark_stack_base);
-                 LASTMARK_RESTORE();
                  if (i < 0)
                      return i;
                  rp->count = count - 1;
                  state->ptr = ptr;
--- 1193,1199 ----
                      return i;
                  i = mark_restore(state, 0, lastmark, &mark_stack_base);
                  if (i < 0)
                      return i;
+                 LASTMARK_RESTORE();
                  rp->count = count - 1;
                  state->ptr = ptr;
***************
*** 1183,1187 ****
              state->repeat = rp;
              state->ptr = ptr;
-             LASTMARK_RESTORE();
              return 0;
  
--- 1208,1211 ----
***************
*** 1201,1206 ****
                     rp->pattern));
  
-             LASTMARK_SAVE();
- 
              if (count < rp->pattern[1]) {
                  /* not enough matches */
--- 1225,1228 ----
***************
*** 1212,1219 ****
                  rp->count = count-1;
                  state->ptr = ptr;
-                 LASTMARK_RESTORE();
                  return 0;
              }
  
              /* see if the tail matches */
              state->repeat = rp->prev;
--- 1234,1242 ----
                  rp->count = count-1;
                  state->ptr = ptr;
                  return 0;
              }
  
+             LASTMARK_SAVE();
+ 
              /* see if the tail matches */
              state->repeat = rp->prev;
***************
*** 1225,1232 ****
              state->repeat = rp;
  
-             LASTMARK_RESTORE();
              if (count >= rp->pattern[2] && rp->pattern[2] != 65535)
                  return 0;
  
              rp->count = count;
              /* RECURSIVE */
--- 1248,1256 ----
              state->repeat = rp;
  
              if (count >= rp->pattern[2] && rp->pattern[2] != 65535)
                  return 0;
  
+             LASTMARK_RESTORE();
+ 
              rp->count = count;
              /* RECURSIVE */
***************
*** 1236,1240 ****
              rp->count = count - 1;
              state->ptr = ptr;
!             LASTMARK_RESTORE();
              return 0;
  
--- 1260,1264 ----
              rp->count = count - 1;
              state->ptr = ptr;
! 
              return 0;