2007-11-24 Eric Seidel <eric@webkit.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2007 11:13:33 +0000 (11:13 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2007 11:13:33 +0000 (11:13 +0000)
        Reviewed by Sam.

        give PCRE_STARTLINE a better name and rename match_data to MatchData

        * pcre/pcre_compile.cpp:
        (compile_branch):
        (canApplyFirstCharOptimization):
        (find_firstassertedchar):
        (printCompiledRegExp):
        (jsRegExpCompile):
        * pcre/pcre_exec.cpp:
        (pchars):
        (jsRegExpExecute):
        * pcre/pcre_internal.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28148 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/pcre/pcre_compile.cpp
JavaScriptCore/pcre/pcre_exec.cpp
JavaScriptCore/pcre/pcre_internal.h

index cdd7fd550da6bae0708a938cbe7aabceb86c8b95..ed8e00c91d3d661800add85c70808f788f37eb60 100644 (file)
@@ -1,3 +1,20 @@
+2007-11-24  Eric Seidel  <eric@webkit.org>
+
+        Reviewed by Sam.
+
+        give PCRE_STARTLINE a better name and rename match_data to MatchData
+
+        * pcre/pcre_compile.cpp:
+        (compile_branch):
+        (canApplyFirstCharOptimization):
+        (find_firstassertedchar):
+        (printCompiledRegExp):
+        (jsRegExpCompile):
+        * pcre/pcre_exec.cpp:
+        (pchars):
+        (jsRegExpExecute):
+        * pcre/pcre_internal.h:
+
 2007-11-24  Eric Seidel  <eric@webkit.org>
 
         Reviewed by Sam.
index 2835ec781c01292d851a58b11318cf838e563bba..94b815fe4936e7b67c8c21a8cfa51162f4dc4a06 100644 (file)
@@ -900,11 +900,11 @@ compile_branch(int options, int* brackets, uschar** codeptr,
     int zerofirstbyte = REQ_UNSET;
     
     /* The variable req_caseopt contains either the REQ_CASELESS value or zero,
-     according to the current setting of the caseless flag. REQ_CASELESS is a bit
+     according to the current setting of the ignores-case flag. REQ_CASELESS is a bit
      value > 255. It is added into the firstbyte or reqbyte variables to record the
      case status of the value. This is used only for ASCII characters. */
     
-    int req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
+    int req_caseopt = (options & PCRE_CASELESS) ? REQ_CASELESS : 0;
     
     /* Switch on next character until the end of the branch */
     
@@ -1953,7 +1953,7 @@ compile_branch(int options, int* brackets, uschar** codeptr,
                     mclength = 1;
                     mcbuffer[0] = c;
                     
-                    if (options & PCRE_CASELESS && (c | 0x20) >= 'a' && (c | 0x20) <= 'z') {
+                    if ((options & PCRE_CASELESS) && (c | 0x20) >= 'a' && (c | 0x20) <= 'z') {
                         *code++ = OP_ASCII_LETTER_NC;
                         *code++ = c | 0x20;
                     } else {
@@ -2255,52 +2255,45 @@ Arguments:
 Returns:         true or false
 */
 
-static bool
-is_startline(const uschar *code, unsigned int bracket_map,
-  unsigned int backref_map)
+static bool canApplyFirstCharOptimization(const uschar* code, unsigned int bracket_map, unsigned int backref_map)
 {
-do {
-   const uschar *scode = first_significant_code(code + 1+LINK_SIZE, false);
-   int op = *scode;
-
-   /* Capturing brackets */
-
-   if (op > OP_BRA)
-     {
-     int new_map;
-     op -= OP_BRA;
-     if (op > EXTRACT_BASIC_MAX) op = GET2(scode, 2+LINK_SIZE);
-     new_map = bracket_map | ((op < 32)? (1 << op) : 1);
-     if (!is_startline(scode, new_map, backref_map)) return false;
-     }
-
-   /* Other brackets */
-
-   else if (op == OP_BRA || op == OP_ASSERT || op == OP_ONCE)
-     { if (!is_startline(scode, bracket_map, backref_map)) return false; }
-
-   /* .* means "start at start or after \n" if it isn't in brackets that
-   may be referenced. */
-
-   else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR)
-     {
-     if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return false;
-     }
-
-   /* Check for explicit circumflex */
-
-   else if (op != OP_CIRC) return false;
-
-   /* Move on to the next alternative */
-
-   code += GET(code, 1);
-   }
-while (*code == OP_ALT);  /* Loop for each alternative */
-return true;
+    do {
+        const uschar* scode = first_significant_code(code + 1 + LINK_SIZE, false);
+        int op = *scode;
+        
+        /* Capturing brackets */
+        if (op > OP_BRA) {
+            op -= OP_BRA;
+            if (op > EXTRACT_BASIC_MAX)
+                op = GET2(scode, 2+LINK_SIZE);
+            int new_map = bracket_map | ((op < 32)? (1 << op) : 1);
+            if (!canApplyFirstCharOptimization(scode, new_map, backref_map))
+                return false;
+        }
+        
+        /* Other brackets */
+        else if (op == OP_BRA || op == OP_ASSERT || op == OP_ONCE) {
+            if (!canApplyFirstCharOptimization(scode, bracket_map, backref_map))
+                return false;
+        
+        /* .* means "start at start or after \n" if it isn't in brackets that
+         may be referenced. */
+        
+        } else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR) {
+            if (scode[1] != OP_ANY || (bracket_map & backref_map))
+                return false;
+        } else if (op != OP_CIRC) /* Check for explicit circumflex */
+            return false;
+        
+        /* Move on to the next alternative */
+        
+        code += GET(code, 1);
+    }
+    while (*code == OP_ALT);  /* Loop for each alternative */
+    return true;
 }
 
 
-
 /*************************************************
 *       Check for asserted fixed first char      *
 *************************************************/
@@ -2332,40 +2325,40 @@ static int find_firstassertedchar(const uschar* code, int options, bool inassert
             op = OP_BRA;
         
         switch(op) {
-            default:
+        default:
+            return -1;
+            
+        case OP_BRA:
+        case OP_ASSERT:
+        case OP_ONCE: {
+            int d;
+            if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0)
                 return -1;
-                
-            case OP_BRA:
-            case OP_ASSERT:
-            case OP_ONCE: {
-                int d;
-                if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0)
-                    return -1;
-                if (c < 0)
-                    c = d;
-                else if (c != d)
-                    return -1;
-                break;
+            if (c < 0)
+                c = d;
+            else if (c != d)
+                return -1;
+            break;
+        }
+        case OP_EXACT:       /* Fall through */
+            scode += 2;
+            
+        case OP_CHAR:
+        case OP_CHARNC:
+        case OP_ASCII_CHAR:
+        case OP_ASCII_LETTER_NC:
+        case OP_PLUS:
+        case OP_MINPLUS:
+            if (!inassert)
+                return -1;
+            if (c < 0) {
+                c = scode[1];
+                if (options & PCRE_CASELESS)
+                    c |= REQ_CASELESS;
             }
-            case OP_EXACT:       /* Fall through */
-                scode += 2;
-                
-            case OP_CHAR:
-            case OP_CHARNC:
-            case OP_ASCII_CHAR:
-            case OP_ASCII_LETTER_NC:
-            case OP_PLUS:
-            case OP_MINPLUS:
-                if (!inassert)
-                    return -1;
-                if (c < 0) {
-                    c = scode[1];
-                    if (options & PCRE_CASELESS)
-                        c |= REQ_CASELESS;
-                }
-                else if (c != scode[1])
-                    return -1;
-                break;
+            else if (c != scode[1])
+                return -1;
+            break;
         }
         
         code += GET(code, 1);
@@ -2883,13 +2876,13 @@ static void printCompiledRegExp(JSRegExp* re, int length)
     if (re->options) {
         printf("%s%s%s\n",
                ((re->options & PCRE_ANCHORED) != 0)? "anchored " : "",
-               ((re->options & PCRE_CASELESS) != 0)? "caseless " : "",
+               ((re->options & PCRE_CASELESS) != 0)? "ignores case " : "",
                ((re->options & PCRE_MULTILINE) != 0)? "multiline " : "");
     }
     
     if (re->options & PCRE_FIRSTSET) {
         char ch = re->first_byte & 255;
-        const char* caseless = ((re->first_byte & REQ_CASELESS) == 0) ? "" : " (caseless)";
+        const char* caseless = (re->first_byte & REQ_CASELESS) ? " (ignores case)" : "";
         if (isASCIIAlphanumeric(ch))
             printf("First char = %c%s\n", ch, caseless);
         else
@@ -3029,7 +3022,7 @@ JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength,
      
      Otherwise, if we know what the first character has to be, save it, because that
      speeds up unanchored matches no end. If not, see if we can set the
-     PCRE_STARTLINE flag. This is helpful for multiline matches when all branches
+     OptionUseMultiLineFirstCharOptimization flag. This is helpful for multiline matches when all branches
      start with ^. and also when all branches start with .* for non-DOTALL matches.
      */
     
@@ -3047,8 +3040,8 @@ JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength,
                 re->options |= PCRE_FIRSTSET;
             }
         }
-        else if (is_startline(codestart, 0, compile_block.backref_map))
-            re->options |= PCRE_STARTLINE;
+        else if (canApplyFirstCharOptimization(codestart, 0, compile_block.backref_map))
+            re->options |= OptionUseMultiLineFirstCharOptimization;
     }
     
     /* For an anchored pattern, we use the "required byte" only if it follows a
index c66261bf4580bed6c44dfbcb58dd6601e07ee441..bf217d280d7dd5f193cfe4939865f8b326333288 100644 (file)
@@ -117,13 +117,13 @@ struct MatchFrame {
 /* Structure for passing "static" information around between the functions
 doing traditional NFA matching, so that they are thread-safe. */
 
-typedef struct match_data {
+struct MatchData {
   unsigned long int match_call_count;      /* As it says */
-  int   *offset_vector;         /* Offset vector */
+  int*   offset_vector;         /* Offset vector */
   int    offset_end;            /* One past the end */
   int    offset_max;            /* The maximum usable for return data */
-  const uschar *lcc;            /* Points to lower casing table */
-  const uschar *ctypes;         /* Points to table of type maps */
+  const uscharlcc;            /* Points to lower casing table */
+  const uscharctypes;         /* Points to table of type maps */
   bool   offset_overflow;       /* Set if too many extractions */
   UChar*  start_subject;         /* Start of the subject string */
   UChar*  end_subject;           /* End of the subject string */
@@ -131,7 +131,7 @@ typedef struct match_data {
   int    end_offset_top;        /* Highwater mark at end of match */
   bool   multiline;
   bool   caseless;
-} match_data;
+};
 
 #define match_isgroup      true    /* Set if start of bracketed group */
 
@@ -165,15 +165,19 @@ Arguments:
 Returns:     nothing
 */
 
-static void
-pchars(const UChar* p, int length, bool is_subject, match_data *md)
+static void pchars(const UChar* p, int length, bool is_subject, MatchData *md)
 {
-int c;
-if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
-while (length-- > 0)
-  if (isprint(c = *(p++))) printf("%c", c);
-  else if (c < 256) printf("\\x%02x", c);
-  else printf("\\x{%x}", c);
+    if (is_subject && length > md->end_subject - p)
+        length = md->end_subject - p;
+    while (length-- > 0) {
+        int c;
+        if (isprint(c = *(p++)))
+            printf("%c", c);
+        else if (c < 256)
+            printf("\\x%02x", c);
+        else
+            printf("\\x{%x}", c);
+    }
 }
 #endif
 
@@ -196,7 +200,7 @@ Returns:      true if matched
 */
 
 static bool
-match_ref(int offset, UChar* eptr, int length, match_data *md)
+match_ref(int offset, UChar* eptr, int length, MatchData *md)
 {
 UChar* p = md->start_subject + md->offset_vector[offset];
 
@@ -403,7 +407,7 @@ static inline void getUTF8CharAndIncrementLength(int& c, const uschar* eptr, int
     }
 }
 
-static int match(UChar* eptr, const uschar* ecode, int offset_top, match_data* md)
+static int match(UChar* eptr, const uschar* ecode, int offset_top, MatchData* md)
 {
     int is_match = false;
     int i;
@@ -2067,7 +2071,7 @@ int jsRegExpExecute(const JSRegExp* re,
     ASSERT(offsetcount >= 0);
     ASSERT(offsets || offsetcount == 0);
     
-    match_data match_block;
+    MatchData match_block;
     match_block.start_subject = (UChar*)subject;
     match_block.end_subject = match_block.start_subject + length;
     UChar* end_subject = match_block.end_subject;
@@ -2075,8 +2079,8 @@ int jsRegExpExecute(const JSRegExp* re,
     match_block.lcc = _pcre_default_tables + lcc_offset;
     match_block.ctypes = _pcre_default_tables + ctypes_offset;
     
-    match_block.multiline = (re->options & PCRE_MULTILINE) != 0;
-    match_block.caseless = (re->options & PCRE_CASELESS) != 0;
+    match_block.multiline = (re->options & PCRE_MULTILINE);
+    match_block.caseless = (re->options & PCRE_CASELESS);
     
     /* If the expression has got more back references than the offsets supplied can
      hold, we get a temporary chunk of working store to use during the matching.
@@ -2149,7 +2153,7 @@ int jsRegExpExecute(const JSRegExp* re,
     
     UChar* start_match = (UChar*)subject + start_offset;
     UChar* req_byte_ptr = start_match - 1;
-    bool startline = re->options & PCRE_STARTLINE;
+    bool useMultiLineFirstCharOptimization = re->options & OptionUseMultiLineFirstCharOptimization;
     
     do {
         UChar* save_end_subject = end_subject;
@@ -2188,8 +2192,7 @@ int jsRegExpExecute(const JSRegExp* re,
         }
         
         /* Or to just after \n for a multiline match if possible */
-        
-        else if (startline) {
+        else if (useMultiLineFirstCharOptimization) {
             if (start_match > match_block.start_subject + start_offset) {
                 while (start_match < end_subject && !isNewline(start_match[-1]))
                     start_match++;
index 49a84440f18b941ca3c418d99e0d218e32610103..38bec88f38bad222e1de72dc574ba9f1a5954c2a 100644 (file)
@@ -292,10 +292,11 @@ static inline void getChar(int& c, const UChar* eptr)
 
 #define BACKCHAR(eptr) while(isTrailingSurrogate(*eptr)) eptr--;
 
+// FIXME: These are really more of a "regexp state" than "regexp options"
 enum PCREOptions {
     PCRE_FIRSTSET = 0x40000000,  /* first_byte is set */
     PCRE_REQCHSET = 0x20000000,  /* req_byte is set */
-    PCRE_STARTLINE = 0x10000000,  /* start after \n for multiline */
+    OptionUseMultiLineFirstCharOptimization = 0x10000000,  /* start after \n for multiline */
     PCRE_ANCHORED = 0x02000000,  /* can't use partial with this regex */
     PCRE_CASELESS = 0x00000001,
     PCRE_MULTILINE = 0x00000002