1 /*******************************************************************************
2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $(date) The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
20 *******************************************************************************/
22 // This software is now distributed according to
23 // the Lesser Gnu Public License. Please see
24 // http://www.gnu.org/copyleft/lesser.txt for
26 // -- Happy Computing!
28 package com.stevesoft.pat;
31 * This class is used internally to search ahead for some optimized Regex
32 * objects. It searches within a String for occrences of a given String -- like
33 * a more flexible version of String.indexOf.
35 * @see com.stevesoft.pat.Skip2
36 * @see com.stevesoft.pat.SkipBMH
40 static int mkmask(int c)
43 return ~(CaseMgr.toUpperCase(x) | CaseMgr.toLowerCase(x) | CaseMgr
56 * Examine a Regex to determine what String it will attempt to skip to when
57 * searching for patterns. Return -1 if we aren't doing this.
59 public static String string(Regex r)
61 return r.skipper == null ? null : r.skipper.src;
65 * Determine the offset of the String within the pattern that we are skipping
66 * to. Return -1 if we aren't doing this.
68 public static int offset(Regex r)
70 return r.skipper == null ? -1 : r.skipper.offset;
74 * Initialize, give it a String to search for, tell it whether or not to
75 * ignoreCase, and what the offset is of the String within the String to be
78 public Skip(String s, boolean ign, int o)
92 m1 = (s.length() == 1);
95 /** The same as find(s,0,s.length()) */
96 public final int find(StringLike s)
98 return find(s, 0, s.length());
101 static final int min(int a, int b)
103 return a < b ? a : b;
107 * Searches a given region of text beginning at position start and ending at
108 * position end for the skip object.
110 public int find(StringLike s, int start, int end)
117 int vend = min(s.length() - 1, end + offset);
120 for (int i = start; i <= vend; i++)
122 if (0 == (s.charAt(i) & mask))
124 // if(m1||s.regionMatches(ign,i,src,0,src.length()) )
125 if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))
134 for (int i = start; i <= vend; i++)
136 if (c == s.charAt(i))
138 // if(m1||s.regionMatches(ign,i,src,0,src.length()) )
139 if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))
149 static Skip findSkip(Regex r)
151 return findSkip(r.thePattern, r.ignoreCase, !r.dontMatchInQuotes);
154 // look for things that can be skipped
155 static Skip findSkip(Pattern p, boolean ignoreCase, boolean trnc)
157 StringBuffer sb = new StringBuffer();
160 int skipc = -1, skipoff = 0;
161 for (; p != null; p = p.next)
163 if (p instanceof oneChar)
165 skipc = ((oneChar) p).c;
168 if (p instanceof oneChar && p.next instanceof oneChar)
171 sb.append(((oneChar) p).c);
172 while (p.next instanceof oneChar)
174 sb.append(((oneChar) p.next).c);
177 String st = sb.toString();
181 sk = new SkipBMH(st, ignoreCase, offset);
185 sk = new Skip2(st, ignoreCase, offset);
187 if (trnc && st.length() > 2)
188 { // chop out a whole string...
189 psav.next = new Skipped(st.substring(1));
190 psav.next.next = p.next;
191 psav.next.parent = p.parent;
195 else if (p instanceof Or
196 && ((Or) p).v.size() == 1
197 && !((Or) p).leftForm().equals("(?!")
198 && null != (subsk = findSkip(
199 (Pattern) ((Or) p).v.elementAt(0), ignoreCase, trnc)))
201 subsk.offset += offset;
204 else if (p.minChars().equals(p.maxChars()))
206 offset += p.minChars().intValue();
210 return skipc < 0 ? null : new Skip("" + (char) skipc, ignoreCase,