001: /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
002: *
003: * ***** BEGIN LICENSE BLOCK *****
004: * Version: MPL 1.1/GPL 2.0
005: *
006: * The contents of this file are subject to the Mozilla Public License Version
007: * 1.1 (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: * http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the
014: * License.
015: *
016: * The Original Code is Rhino code, released
017: * May 6, 1998.
018: *
019: * The Initial Developer of the Original Code is
020: * Netscape Communications Corporation.
021: * Portions created by the Initial Developer are Copyright (C) 1997-1999
022: * the Initial Developer. All Rights Reserved.
023: *
024: * Contributor(s):
025: * Norris Boyd
026: * Igor Bukanov
027: * Brendan Eich
028: *
029: * Alternatively, the contents of this file may be used under the terms of
030: * the GNU General Public License Version 2 or later (the "GPL"), in which
031: * case the provisions of the GPL are applicable instead of those above. If
032: * you wish to allow use of your version of this file only under the terms of
033: * the GPL and not to allow others to use your version of this file under the
034: * MPL, indicate your decision by deleting the provisions above and replacing
035: * them with the notice and other provisions required by the GPL. If you do
036: * not delete the provisions above, a recipient may use your version of this
037: * file under either the MPL or the GPL.
038: *
039: * ***** END LICENSE BLOCK ***** */
040:
041: package org.mozilla.javascript.regexp;
042:
043: import org.mozilla.javascript.*;
044:
045: /**
046: * This class implements the RegExp constructor native object.
047: *
048: * Revision History:
049: * Implementation in C by Brendan Eich
050: * Initial port to Java by Norris Boyd from jsregexp.c version 1.36
051: * Merged up to version 1.38, which included Unicode support.
052: * Merged bug fixes in version 1.39.
053: * Merged JSFUN13_BRANCH changes up to 1.32.2.11
054: *
055: * @author Brendan Eich
056: * @author Norris Boyd
057: */
058: class NativeRegExpCtor extends BaseFunction {
059: static final long serialVersionUID = -5733330028285400526L;
060:
061: NativeRegExpCtor() {
062: }
063:
064: public String getFunctionName() {
065: return "RegExp";
066: }
067:
068: public Object call(Context cx, Scriptable scope,
069: Scriptable this Obj, Object[] args) {
070: if (args.length > 0 && args[0] instanceof NativeRegExp
071: && (args.length == 1 || args[1] == Undefined.instance)) {
072: return args[0];
073: }
074: return construct(cx, scope, args);
075: }
076:
077: public Scriptable construct(Context cx, Scriptable scope,
078: Object[] args) {
079: NativeRegExp re = new NativeRegExp();
080: re.compile(cx, scope, args);
081: ScriptRuntime.setObjectProtoAndParent(re, scope);
082: return re;
083: }
084:
085: private static RegExpImpl getImpl() {
086: Context cx = Context.getCurrentContext();
087: return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);
088: }
089:
090: // #string_id_map#
091:
092: private static final int Id_multiline = 1, Id_STAR = 2, // #string=$*#
093:
094: Id_input = 3, Id_UNDERSCORE = 4, // #string=$_#
095:
096: Id_lastMatch = 5, Id_AMPERSAND = 6, // #string=$&#
097:
098: Id_lastParen = 7, Id_PLUS = 8, // #string=$+#
099:
100: Id_leftContext = 9, Id_BACK_QUOTE = 10, // #string=$`#
101:
102: Id_rightContext = 11, Id_QUOTE = 12, // #string=$'#
103:
104: DOLLAR_ID_BASE = 12;
105:
106: private static final int Id_DOLLAR_1 = DOLLAR_ID_BASE + 1, // #string=$1#
107: Id_DOLLAR_2 = DOLLAR_ID_BASE + 2, // #string=$2#
108: Id_DOLLAR_3 = DOLLAR_ID_BASE + 3, // #string=$3#
109: Id_DOLLAR_4 = DOLLAR_ID_BASE + 4, // #string=$4#
110: Id_DOLLAR_5 = DOLLAR_ID_BASE + 5, // #string=$5#
111: Id_DOLLAR_6 = DOLLAR_ID_BASE + 6, // #string=$6#
112: Id_DOLLAR_7 = DOLLAR_ID_BASE + 7, // #string=$7#
113: Id_DOLLAR_8 = DOLLAR_ID_BASE + 8, // #string=$8#
114: Id_DOLLAR_9 = DOLLAR_ID_BASE + 9, // #string=$9#
115:
116: MAX_INSTANCE_ID = DOLLAR_ID_BASE + 9;
117:
118: protected int getMaxInstanceId() {
119: return super .getMaxInstanceId() + MAX_INSTANCE_ID;
120: }
121:
122: protected int findInstanceIdInfo(String s) {
123: int id;
124: // #generated# Last update: 2001-05-24 16:09:31 GMT+02:00
125: L0: {
126: id = 0;
127: String X = null;
128: int c;
129: L: switch (s.length()) {
130: case 2:
131: switch (s.charAt(1)) {
132: case '&':
133: if (s.charAt(0) == '$') {
134: id = Id_AMPERSAND;
135: break L0;
136: }
137: break L;
138: case '\'':
139: if (s.charAt(0) == '$') {
140: id = Id_QUOTE;
141: break L0;
142: }
143: break L;
144: case '*':
145: if (s.charAt(0) == '$') {
146: id = Id_STAR;
147: break L0;
148: }
149: break L;
150: case '+':
151: if (s.charAt(0) == '$') {
152: id = Id_PLUS;
153: break L0;
154: }
155: break L;
156: case '1':
157: if (s.charAt(0) == '$') {
158: id = Id_DOLLAR_1;
159: break L0;
160: }
161: break L;
162: case '2':
163: if (s.charAt(0) == '$') {
164: id = Id_DOLLAR_2;
165: break L0;
166: }
167: break L;
168: case '3':
169: if (s.charAt(0) == '$') {
170: id = Id_DOLLAR_3;
171: break L0;
172: }
173: break L;
174: case '4':
175: if (s.charAt(0) == '$') {
176: id = Id_DOLLAR_4;
177: break L0;
178: }
179: break L;
180: case '5':
181: if (s.charAt(0) == '$') {
182: id = Id_DOLLAR_5;
183: break L0;
184: }
185: break L;
186: case '6':
187: if (s.charAt(0) == '$') {
188: id = Id_DOLLAR_6;
189: break L0;
190: }
191: break L;
192: case '7':
193: if (s.charAt(0) == '$') {
194: id = Id_DOLLAR_7;
195: break L0;
196: }
197: break L;
198: case '8':
199: if (s.charAt(0) == '$') {
200: id = Id_DOLLAR_8;
201: break L0;
202: }
203: break L;
204: case '9':
205: if (s.charAt(0) == '$') {
206: id = Id_DOLLAR_9;
207: break L0;
208: }
209: break L;
210: case '_':
211: if (s.charAt(0) == '$') {
212: id = Id_UNDERSCORE;
213: break L0;
214: }
215: break L;
216: case '`':
217: if (s.charAt(0) == '$') {
218: id = Id_BACK_QUOTE;
219: break L0;
220: }
221: break L;
222: }
223: break L;
224: case 5:
225: X = "input";
226: id = Id_input;
227: break L;
228: case 9:
229: c = s.charAt(4);
230: if (c == 'M') {
231: X = "lastMatch";
232: id = Id_lastMatch;
233: } else if (c == 'P') {
234: X = "lastParen";
235: id = Id_lastParen;
236: } else if (c == 'i') {
237: X = "multiline";
238: id = Id_multiline;
239: }
240: break L;
241: case 11:
242: X = "leftContext";
243: id = Id_leftContext;
244: break L;
245: case 12:
246: X = "rightContext";
247: id = Id_rightContext;
248: break L;
249: }
250: if (X != null && X != s && !X.equals(s))
251: id = 0;
252: }
253: // #/generated#
254:
255: if (id == 0)
256: return super .findInstanceIdInfo(s);
257:
258: int attr;
259: switch (id) {
260: case Id_multiline:
261: case Id_STAR:
262: case Id_input:
263: case Id_UNDERSCORE:
264: attr = PERMANENT;
265: break;
266: default:
267: attr = PERMANENT | READONLY;
268: break;
269: }
270:
271: return instanceIdInfo(attr, super .getMaxInstanceId() + id);
272: }
273:
274: // #/string_id_map#
275:
276: protected String getInstanceIdName(int id) {
277: int shifted = id - super .getMaxInstanceId();
278: if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
279: switch (shifted) {
280: case Id_multiline:
281: return "multiline";
282: case Id_STAR:
283: return "$*";
284:
285: case Id_input:
286: return "input";
287: case Id_UNDERSCORE:
288: return "$_";
289:
290: case Id_lastMatch:
291: return "lastMatch";
292: case Id_AMPERSAND:
293: return "$&";
294:
295: case Id_lastParen:
296: return "lastParen";
297: case Id_PLUS:
298: return "$+";
299:
300: case Id_leftContext:
301: return "leftContext";
302: case Id_BACK_QUOTE:
303: return "$`";
304:
305: case Id_rightContext:
306: return "rightContext";
307: case Id_QUOTE:
308: return "$'";
309: }
310: // Must be one of $1..$9, convert to 0..8
311: int substring_number = shifted - DOLLAR_ID_BASE - 1;
312: char[] buf = { '$', (char) ('1' + substring_number) };
313: return new String(buf);
314: }
315: return super .getInstanceIdName(id);
316: }
317:
318: protected Object getInstanceIdValue(int id) {
319: int shifted = id - super .getMaxInstanceId();
320: if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
321: RegExpImpl impl = getImpl();
322: Object stringResult;
323: switch (shifted) {
324: case Id_multiline:
325: case Id_STAR:
326: return ScriptRuntime.wrapBoolean(impl.multiline);
327:
328: case Id_input:
329: case Id_UNDERSCORE:
330: stringResult = impl.input;
331: break;
332:
333: case Id_lastMatch:
334: case Id_AMPERSAND:
335: stringResult = impl.lastMatch;
336: break;
337:
338: case Id_lastParen:
339: case Id_PLUS:
340: stringResult = impl.lastParen;
341: break;
342:
343: case Id_leftContext:
344: case Id_BACK_QUOTE:
345: stringResult = impl.leftContext;
346: break;
347:
348: case Id_rightContext:
349: case Id_QUOTE:
350: stringResult = impl.rightContext;
351: break;
352:
353: default: {
354: // Must be one of $1..$9, convert to 0..8
355: int substring_number = shifted - DOLLAR_ID_BASE - 1;
356: stringResult = impl.getParenSubString(substring_number);
357: break;
358: }
359: }
360: return (stringResult == null) ? "" : stringResult
361: .toString();
362: }
363: return super .getInstanceIdValue(id);
364: }
365:
366: protected void setInstanceIdValue(int id, Object value) {
367: int shifted = id - super.getMaxInstanceId();
368: switch (shifted) {
369: case Id_multiline:
370: case Id_STAR:
371: getImpl().multiline = ScriptRuntime.toBoolean(value);
372: return;
373:
374: case Id_input:
375: case Id_UNDERSCORE:
376: getImpl().input = ScriptRuntime.toString(value);
377: return;
378: }
379: super.setInstanceIdValue(id, value);
380: }
381:
382: }
|