mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			264 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			264 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* gnu/regexp/REMatch.java
 | |
|    Copyright (C) 1998-2001, 2004 Free Software Foundation, Inc.
 | |
| 
 | |
| This file is part of GNU Classpath.
 | |
| 
 | |
| GNU Classpath is free software; you can redistribute it and/or modify
 | |
| it under the terms of the GNU General Public License as published by
 | |
| the Free Software Foundation; either version 2, or (at your option)
 | |
| any later version.
 | |
| 
 | |
| GNU Classpath is distributed in the hope that it will be useful, but
 | |
| WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| General Public License for more details.
 | |
| 
 | |
| You should have received a copy of the GNU General Public License
 | |
| along with GNU Classpath; see the file COPYING.  If not, write to the
 | |
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 | |
| 02111-1307 USA.
 | |
| 
 | |
| Linking this library statically or dynamically with other modules is
 | |
| making a combined work based on this library.  Thus, the terms and
 | |
| conditions of the GNU General Public License cover the whole
 | |
| combination.
 | |
| 
 | |
| As a special exception, the copyright holders of this library give you
 | |
| permission to link this library with independent modules to produce an
 | |
| executable, regardless of the license terms of these independent
 | |
| modules, and to copy and distribute the resulting executable under
 | |
| terms of your choice, provided that you also meet, for each linked
 | |
| independent module, the terms and conditions of the license of that
 | |
| module.  An independent module is a module which is not derived from
 | |
| or based on this library.  If you modify this library, you may extend
 | |
| this exception to your version of the library, but you are not
 | |
| obligated to do so.  If you do not wish to do so, delete this
 | |
| exception statement from your version. */
 | |
| 
 | |
| 
 | |
| package gnu.regexp;
 | |
| import java.io.Serializable;
 | |
| 
 | |
| /**
 | |
|  * An instance of this class represents a match
 | |
|  * completed by a gnu.regexp matching function. It can be used
 | |
|  * to obtain relevant information about the location of a match
 | |
|  * or submatch.
 | |
|  *
 | |
|  * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
 | |
|  */
 | |
| public final class REMatch implements Serializable, Cloneable {
 | |
|     private String matchedText;
 | |
| 
 | |
|     // These variables are package scope for fast access within the engine
 | |
|     int eflags; // execution flags this match was made using
 | |
| 
 | |
|     // Offset in source text where match was tried.  This is zero-based;
 | |
|     // the actual position in the source text is given by (offset + anchor).
 | |
|     int offset;
 | |
| 
 | |
|     // Anchor position refers to the index into the source input
 | |
|     // at which the matching operation began.
 | |
|     // This is also useful for the ANCHORINDEX option.
 | |
|     int anchor;
 | |
| 
 | |
|     // Package scope; used by RE.
 | |
|     int index; // used while matching to mark current match position in input
 | |
|     int[] start; // start positions (relative to offset) for each (sub)exp.
 | |
|     int[] end;   // end positions for the same
 | |
|     REMatch next; // other possibility (to avoid having to use arrays)
 | |
| 
 | |
|     public Object clone() {
 | |
| 	try {
 | |
| 	    REMatch copy = (REMatch) super.clone();
 | |
| 	    copy.next = null;
 | |
| 
 | |
| 	    copy.start = (int[]) start.clone();
 | |
| 	    copy.end = (int[]) end.clone();
 | |
| 
 | |
| 	    return copy;
 | |
| 	} catch (CloneNotSupportedException e) {
 | |
| 	    throw new Error(); // doesn't happen
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     void assignFrom(REMatch other) {
 | |
| 	start = other.start;
 | |
| 	end = other.end;
 | |
| 	index = other.index;
 | |
| 	// need to deep clone?
 | |
| 	next = other.next;
 | |
|     }
 | |
| 
 | |
|     REMatch(int subs, int anchor, int eflags) {
 | |
| 	start = new int[subs+1];
 | |
| 	end = new int[subs+1];
 | |
| 	this.anchor = anchor;
 | |
| 	this.eflags = eflags;
 | |
| 	clear(anchor);
 | |
|     }
 | |
| 
 | |
|     void finish(CharIndexed text) {
 | |
| 	start[0] = 0;
 | |
| 	StringBuffer sb = new StringBuffer();
 | |
| 	int i;
 | |
| 	for (i = 0; i < end[0]; i++)
 | |
| 	    sb.append(text.charAt(i));
 | |
| 	matchedText = sb.toString();
 | |
| 	for (i = 0; i < start.length; i++) {
 | |
| 	    // If any subexpressions didn't terminate, they don't count
 | |
| 	    // TODO check if this code ever gets hit
 | |
| 	    if ((start[i] == -1) ^ (end[i] == -1)) {
 | |
| 		start[i] = -1;
 | |
| 		end[i] = -1;
 | |
| 	    }
 | |
| 	}
 | |
| 	next = null; // cut off alternates
 | |
|     }
 | |
|     
 | |
|     /** Clears the current match and moves the offset to the new index. */
 | |
|     void clear(int index) {
 | |
| 	offset = index;
 | |
| 	this.index = 0;
 | |
| 	for (int i = 0; i < start.length; i++) {
 | |
| 	    start[i] = end[i] = -1;
 | |
| 	}
 | |
| 	next = null; // cut off alternates
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Returns the string matching the pattern.  This makes it convenient
 | |
|      * to write code like the following:
 | |
|      * <P>
 | |
|      * <code> 
 | |
|      * REMatch myMatch = myExpression.getMatch(myString);<br>
 | |
|      * if (myMatch != null) System.out.println("Regexp found: "+myMatch);
 | |
|      * </code>
 | |
|      */
 | |
|     public String toString() {
 | |
| 	return matchedText;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Returns the index within the input text where the match in its entirety
 | |
|      * began.
 | |
|      */
 | |
|     public int getStartIndex() {
 | |
| 	return offset + start[0];
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Returns the index within the input string where the match in
 | |
|      * its entirety ends.  The return value is the next position after
 | |
|      * the end of the string; therefore, a match created by the
 | |
|      * following call:
 | |
|      *
 | |
|      * <P>
 | |
|      * <code>REMatch myMatch = myExpression.getMatch(myString);</code>
 | |
|      * <P>
 | |
|      * can be viewed (given that myMatch is not null) by creating
 | |
|      * <P>
 | |
|      * <code>String theMatch = myString.substring(myMatch.getStartIndex(),
 | |
|      * myMatch.getEndIndex());</code>
 | |
|      * <P>
 | |
|      * But you can save yourself that work, since the <code>toString()</code>
 | |
|      * method (above) does exactly that for you.  
 | |
|      */
 | |
|     public int getEndIndex() {
 | |
| 	return offset + end[0];
 | |
|     }
 | |
|   
 | |
|     /**
 | |
|      * Returns the string matching the given subexpression.  The subexpressions
 | |
|      * are indexed starting with one, not zero.  That is, the subexpression
 | |
|      * identified by the first set of parentheses in a regular expression
 | |
|      * could be retrieved from an REMatch by calling match.toString(1).
 | |
|      *
 | |
|      * @param sub Index of the subexpression.
 | |
|      */
 | |
|     public String toString(int sub) {
 | |
| 	if ((sub >= start.length) || (start[sub] == -1)) return "";
 | |
| 	return (matchedText.substring(start[sub],end[sub]));
 | |
|     }
 | |
|     
 | |
|     /** 
 | |
|      * Returns the index within the input string used to generate this match
 | |
|      * where subexpression number <i>sub</i> begins, or <code>-1</code> if
 | |
|      * the subexpression does not exist.  The initial position is zero.
 | |
|      *
 | |
|      * @param sub Subexpression index
 | |
|      * @deprecated Use getStartIndex(int) instead.
 | |
|      */
 | |
|     public int getSubStartIndex(int sub) {
 | |
| 	if (sub >= start.length) return -1;
 | |
| 	int x = start[sub];
 | |
| 	return (x == -1) ? x : offset + x;
 | |
|     }
 | |
|     
 | |
|     /** 
 | |
|      * Returns the index within the input string used to generate this match
 | |
|      * where subexpression number <i>sub</i> begins, or <code>-1</code> if
 | |
|      * the subexpression does not exist.  The initial position is zero.
 | |
|      *
 | |
|      * @param sub Subexpression index
 | |
|      * @since gnu.regexp 1.1.0
 | |
|      */
 | |
|     public int getStartIndex(int sub) {
 | |
| 	if (sub >= start.length) return -1;
 | |
| 	int x = start[sub];
 | |
| 	return (x == -1) ? x : offset + x;
 | |
|     }
 | |
|   
 | |
|     /** 
 | |
|      * Returns the index within the input string used to generate this match
 | |
|      * where subexpression number <i>sub</i> ends, or <code>-1</code> if
 | |
|      * the subexpression does not exist.  The initial position is zero.
 | |
|      *
 | |
|      * @param sub Subexpression index
 | |
|      * @deprecated Use getEndIndex(int) instead
 | |
|      */
 | |
|     public int getSubEndIndex(int sub) {
 | |
| 	if (sub >= start.length) return -1;
 | |
| 	int x = end[sub];
 | |
| 	return (x == -1) ? x : offset + x;
 | |
|     }
 | |
|     
 | |
|     /** 
 | |
|      * Returns the index within the input string used to generate this match
 | |
|      * where subexpression number <i>sub</i> ends, or <code>-1</code> if
 | |
|      * the subexpression does not exist.  The initial position is zero.
 | |
|      *
 | |
|      * @param sub Subexpression index
 | |
|      */
 | |
|     public int getEndIndex(int sub) {
 | |
| 	if (sub >= start.length) return -1;
 | |
| 	int x = end[sub];
 | |
| 	return (x == -1) ? x : offset + x;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Substitute the results of this match to create a new string.
 | |
|      * This is patterned after PERL, so the tokens to watch out for are
 | |
|      * <code>$0</code> through <code>$9</code>.  <code>$0</code> matches
 | |
|      * the full substring matched; <code>$<i>n</i></code> matches
 | |
|      * subexpression number <i>n</i>.
 | |
|      *
 | |
|      * @param input A string consisting of literals and <code>$<i>n</i></code> tokens.
 | |
|      */
 | |
|     public String substituteInto(String input) {
 | |
| 	// a la Perl, $0 is whole thing, $1 - $9 are subexpressions
 | |
| 	StringBuffer output = new StringBuffer();
 | |
| 	int pos;
 | |
| 	for (pos = 0; pos < input.length()-1; pos++) {
 | |
| 	    if ((input.charAt(pos) == '$') && (Character.isDigit(input.charAt(pos+1)))) {
 | |
| 		int val = Character.digit(input.charAt(++pos),10);
 | |
| 		if (val < start.length) {
 | |
| 		    output.append(toString(val));
 | |
| 		} 
 | |
| 	    } else output.append(input.charAt(pos));
 | |
| 	}
 | |
| 	if (pos < input.length()) output.append(input.charAt(pos));
 | |
| 	return output.toString();
 | |
|     }
 | |
| }
 |