1 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
2 |
* |
3 |
* ***** BEGIN LICENSE BLOCK ***** |
4 |
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
5 |
* |
6 |
* The contents of this file are subject to the Mozilla Public License Version |
7 |
* 1.1 (the "License"); you may not use this file except in compliance with |
8 |
* the License. You may obtain a copy of the License at |
9 |
* http://www.mozilla.org/MPL/ |
10 |
* |
11 |
* Software distributed under the License is distributed on an "AS IS" basis, |
12 |
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
13 |
* for the specific language governing rights and limitations under the |
14 |
* License. |
15 |
* |
16 |
* The Original Code is Mozilla Communicator client code, released |
17 |
* March 31, 1998. |
18 |
* |
19 |
* The Initial Developer of the Original Code is |
20 |
* Netscape Communications Corporation. |
21 |
* Portions created by the Initial Developer are Copyright (C) 1998 |
22 |
* the Initial Developer. All Rights Reserved. |
23 |
* |
24 |
* Contributor(s): |
25 |
* |
26 |
* Alternatively, the contents of this file may be used under the terms of |
27 |
* either of the GNU General Public License Version 2 or later (the "GPL"), |
28 |
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
29 |
* in which case the provisions of the GPL or the LGPL are applicable instead |
30 |
* of those above. If you wish to allow use of your version of this file only |
31 |
* under the terms of either the GPL or the LGPL, and not to allow others to |
32 |
* use your version of this file under the terms of the MPL, indicate your |
33 |
* decision by deleting the provisions above and replace them with the notice |
34 |
* and other provisions required by the GPL or the LGPL. If you do not delete |
35 |
* the provisions above, a recipient may use your version of this file under |
36 |
* the terms of any one of the MPL, the GPL or the LGPL. |
37 |
* |
38 |
* ***** END LICENSE BLOCK ***** */ |
39 |
|
40 |
#ifndef jsregexp_h___ |
41 |
#define jsregexp_h___ |
42 |
/* |
43 |
* JS regular expression interface. |
44 |
*/ |
45 |
#include <stddef.h> |
46 |
#include "jspubtd.h" |
47 |
#include "jsstr.h" |
48 |
|
49 |
#ifdef JS_THREADSAFE |
50 |
#include "jsdhash.h" |
51 |
#endif |
52 |
|
53 |
JS_BEGIN_EXTERN_C |
54 |
|
55 |
struct JSRegExpStatics { |
56 |
JSString *input; /* input string to match (perl $_, GC root) */ |
57 |
JSBool multiline; /* whether input contains newlines (perl $*) */ |
58 |
uint16 parenCount; /* number of valid elements in parens[] */ |
59 |
uint16 moreLength; /* number of allocated elements in moreParens */ |
60 |
JSSubString parens[9]; /* last set of parens matched (perl $1, $2) */ |
61 |
JSSubString *moreParens; /* null or realloc'd vector for $10, etc. */ |
62 |
JSSubString lastMatch; /* last string matched (perl $&) */ |
63 |
JSSubString lastParen; /* last paren matched (perl $+) */ |
64 |
JSSubString leftContext; /* input to left of last match (perl $`) */ |
65 |
JSSubString rightContext; /* input to right of last match (perl $') */ |
66 |
}; |
67 |
|
68 |
/* |
69 |
* This struct holds a bitmap representation of a class from a regexp. |
70 |
* There's a list of these referenced by the classList field in the JSRegExp |
71 |
* struct below. The initial state has startIndex set to the offset in the |
72 |
* original regexp source of the beginning of the class contents. The first |
73 |
* use of the class converts the source representation into a bitmap. |
74 |
* |
75 |
*/ |
76 |
typedef struct RECharSet { |
77 |
JSPackedBool converted; |
78 |
JSPackedBool sense; |
79 |
uint16 length; |
80 |
union { |
81 |
uint8 *bits; |
82 |
struct { |
83 |
size_t startIndex; |
84 |
size_t length; |
85 |
} src; |
86 |
} u; |
87 |
} RECharSet; |
88 |
|
89 |
/* |
90 |
* This macro is safe because moreParens is guaranteed to be allocated and big |
91 |
* enough to hold parenCount, or else be null when parenCount is 0. |
92 |
*/ |
93 |
#define REGEXP_PAREN_SUBSTRING(res, num) \ |
94 |
(((jsuint)(num) < (jsuint)(res)->parenCount) \ |
95 |
? ((jsuint)(num) < 9) \ |
96 |
? &(res)->parens[num] \ |
97 |
: &(res)->moreParens[(num) - 9] \ |
98 |
: &js_EmptySubString) |
99 |
|
100 |
typedef struct RENode RENode; |
101 |
|
102 |
struct JSRegExp { |
103 |
jsrefcount nrefs; /* reference count */ |
104 |
uint16 flags; /* flags, see jsapi.h's JSREG_* defines */ |
105 |
size_t parenCount; /* number of parenthesized submatches */ |
106 |
size_t classCount; /* count [...] bitmaps */ |
107 |
RECharSet *classList; /* list of [...] bitmaps */ |
108 |
JSString *source; /* locked source string, sans // */ |
109 |
jsbytecode program[1]; /* regular expression bytecode */ |
110 |
}; |
111 |
|
112 |
extern JSRegExp * |
113 |
js_NewRegExp(JSContext *cx, JSTokenStream *ts, |
114 |
JSString *str, uintN flags, JSBool flat); |
115 |
|
116 |
extern JSRegExp * |
117 |
js_NewRegExpOpt(JSContext *cx, JSString *str, JSString *opt, JSBool flat); |
118 |
|
119 |
#define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs) |
120 |
#define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re) |
121 |
|
122 |
extern void |
123 |
js_DestroyRegExp(JSContext *cx, JSRegExp *re); |
124 |
|
125 |
/* |
126 |
* Execute re on input str at *indexp, returning null in *rval on mismatch. |
127 |
* On match, return true if test is true, otherwise return an array object. |
128 |
* Update *indexp and cx->regExpStatics always on match. |
129 |
*/ |
130 |
extern JSBool |
131 |
js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp, |
132 |
JSBool test, jsval *rval); |
133 |
|
134 |
/* |
135 |
* These two add and remove GC roots, respectively, so their calls must be |
136 |
* well-ordered. |
137 |
*/ |
138 |
extern JSBool |
139 |
js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res); |
140 |
|
141 |
extern void |
142 |
js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res); |
143 |
|
144 |
#define VALUE_IS_REGEXP(cx, v) \ |
145 |
(JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) && \ |
146 |
OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_RegExpClass) |
147 |
|
148 |
extern JSClass js_RegExpClass; |
149 |
|
150 |
enum regexp_tinyid { |
151 |
REGEXP_SOURCE = -1, |
152 |
REGEXP_GLOBAL = -2, |
153 |
REGEXP_IGNORE_CASE = -3, |
154 |
REGEXP_LAST_INDEX = -4, |
155 |
REGEXP_MULTILINE = -5, |
156 |
REGEXP_STICKY = -6 |
157 |
}; |
158 |
|
159 |
extern JSObject * |
160 |
js_InitRegExpClass(JSContext *cx, JSObject *obj); |
161 |
|
162 |
/* |
163 |
* Export js_regexp_toString to the decompiler. |
164 |
*/ |
165 |
extern JSBool |
166 |
js_regexp_toString(JSContext *cx, JSObject *obj, jsval *vp); |
167 |
|
168 |
/* |
169 |
* Create, serialize/deserialize, or clone a RegExp object. |
170 |
*/ |
171 |
extern JSObject * |
172 |
js_NewRegExpObject(JSContext *cx, JSTokenStream *ts, |
173 |
jschar *chars, size_t length, uintN flags); |
174 |
|
175 |
extern JSBool |
176 |
js_XDRRegExp(JSXDRState *xdr, JSObject **objp); |
177 |
|
178 |
extern JSObject * |
179 |
js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent); |
180 |
|
181 |
/* |
182 |
* Get and set the per-object (clone or clone-parent) lastIndex slot. |
183 |
*/ |
184 |
extern JSBool |
185 |
js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex); |
186 |
|
187 |
extern JSBool |
188 |
js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex); |
189 |
|
190 |
JS_END_EXTERN_C |
191 |
|
192 |
#endif /* jsregexp_h___ */ |