]> git.saurik.com Git - apple/javascriptcore.git/blob - kjs/regexp.cpp
JavaScriptCore-466.1.tar.gz
[apple/javascriptcore.git] / kjs / regexp.cpp
1 // -*- c-basic-offset: 2 -*-
2 /*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2001, 2004 Harri Porten (porten@kde.org)
5 * Copyright (c) 2007, Apple Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23 #include "config.h"
24 #include "regexp.h"
25
26 #include "lexer.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <wtf/Assertions.h>
31
32 namespace KJS {
33
34 RegExp::RegExp(const UString& pattern)
35 : m_pattern(pattern)
36 , m_flagBits(0)
37 , m_constructionError(0)
38 , m_numSubpatterns(0)
39 {
40 m_regExp = jsRegExpCompile(reinterpret_cast<const ::UChar*>(pattern.data()), pattern.size(),
41 JSRegExpDoNotIgnoreCase, JSRegExpSingleLine, &m_numSubpatterns, &m_constructionError);
42 }
43
44 RegExp::RegExp(const UString& pattern, const UString& flags)
45 : m_pattern(pattern)
46 , m_flags(flags)
47 , m_flagBits(0)
48 , m_constructionError(0)
49 , m_numSubpatterns(0)
50 {
51 // NOTE: The global flag is handled on a case-by-case basis by functions like
52 // String::match and RegExpImp::match.
53 if (flags.find('g') != -1)
54 m_flagBits |= Global;
55
56 // FIXME: Eliminate duplication by adding a way ask a JSRegExp what its flags are?
57 JSRegExpIgnoreCaseOption ignoreCaseOption = JSRegExpDoNotIgnoreCase;
58 if (flags.find('i') != -1) {
59 m_flagBits |= IgnoreCase;
60 ignoreCaseOption = JSRegExpIgnoreCase;
61 }
62
63 JSRegExpMultilineOption multilineOption = JSRegExpSingleLine;
64 if (flags.find('m') != -1) {
65 m_flagBits |= Multiline;
66 multilineOption = JSRegExpMultiline;
67 }
68
69 m_regExp = jsRegExpCompile(reinterpret_cast<const ::UChar*>(pattern.data()), pattern.size(),
70 ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
71 }
72
73 RegExp::~RegExp()
74 {
75 jsRegExpFree(m_regExp);
76 }
77
78 int RegExp::match(const UString& s, int i, OwnArrayPtr<int>* ovector)
79 {
80 if (i < 0)
81 i = 0;
82 if (ovector)
83 ovector->clear();
84
85 if (i > s.size() || s.isNull())
86 return -1;
87
88 if (!m_regExp)
89 return -1;
90
91 // Set up the offset vector for the result.
92 // First 2/3 used for result, the last third used by PCRE.
93 int* offsetVector;
94 int offsetVectorSize;
95 int fixedSizeOffsetVector[3];
96 if (!ovector) {
97 offsetVectorSize = 3;
98 offsetVector = fixedSizeOffsetVector;
99 } else {
100 offsetVectorSize = (m_numSubpatterns + 1) * 3;
101 offsetVector = new int [offsetVectorSize];
102 ovector->set(offsetVector);
103 }
104
105 int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const ::UChar*>(s.data()), s.size(), i, offsetVector, offsetVectorSize);
106
107 if (numMatches < 0) {
108 #ifndef NDEBUG
109 if (numMatches != JSRegExpErrorNoMatch)
110 fprintf(stderr, "jsRegExpExecute failed with result %d\n", numMatches);
111 #endif
112 if (ovector)
113 ovector->clear();
114 return -1;
115 }
116
117 return offsetVector[0];
118 }
119
120 } // namespace KJS