ef5f3f0a169f3fd2fc825bd0a8aa7091861b3340
[jalviewjs.git] / unused / com / stevesoft / pat / Skip.java
1 //\r
2 // This software is now distributed according to\r
3 // the Lesser Gnu Public License.  Please see\r
4 // http://www.gnu.org/copyleft/lesser.txt for\r
5 // the details.\r
6 //    -- Happy Computing!\r
7 //\r
8 package com.stevesoft.pat;\r
9 \r
10 /**\r
11  * This class is used internally to search ahead for some optimized Regex\r
12  * objects. It searches within a String for occrences of a given String -- like\r
13  * a more flexible version of String.indexOf.\r
14  * \r
15  * @see com.stevesoft.pat.Skip2\r
16  * @see com.stevesoft.pat.SkipBMH\r
17  */\r
18 public class Skip\r
19 {\r
20   static int mkmask(int c)\r
21   {\r
22     char x = (char) c;\r
23     return ~(CaseMgr.toUpperCase(x) | CaseMgr.toLowerCase(x) | CaseMgr\r
24             .toTitleCase(x));\r
25   }\r
26 \r
27   String src;\r
28 \r
29   int c, mask;\r
30 \r
31   int offset;\r
32 \r
33   boolean ign, m1;\r
34 \r
35   /**\r
36    * Examine a Regex to determine what String it will attempt to skip to when\r
37    * searching for patterns. Return -1 if we aren't doing this.\r
38    */\r
39   public static String string(Regex r)\r
40   {\r
41     return r.skipper == null ? null : r.skipper.src;\r
42   }\r
43 \r
44   /**\r
45    * Determine the offset of the String within the pattern that we are skipping\r
46    * to. Return -1 if we aren't doing this.\r
47    */\r
48   public static int offset(Regex r)\r
49   {\r
50     return r.skipper == null ? -1 : r.skipper.offset;\r
51   }\r
52 \r
53   /**\r
54    * Initialize, give it a String to search for, tell it whether or not to\r
55    * ignoreCase, and what the offset is of the String within the String to be\r
56    * searched.\r
57    */\r
58   public Skip(String s, boolean ign, int o)\r
59   {\r
60     src = s;\r
61     c = s.charAt(0);\r
62     if (ign)\r
63     {\r
64       mask = mkmask(c);\r
65     }\r
66     else\r
67     {\r
68       mask = 0;\r
69     }\r
70     offset = o;\r
71     this.ign = ign;\r
72     m1 = (s.length() == 1);\r
73   }\r
74 \r
75   /** The same as find(s,0,s.length()) */\r
76   public final int find(StringLike s)\r
77   {\r
78     return find(s, 0, s.length());\r
79   }\r
80 \r
81   static final int min(int a, int b)\r
82   {\r
83     return a < b ? a : b;\r
84   }\r
85 \r
86   /**\r
87    * Searches a given region of text beginning at position start and ending at\r
88    * position end for the skip object.\r
89    */\r
90   public int find(StringLike s, int start, int end)\r
91   {\r
92     if (start > end)\r
93     {\r
94       return -1;\r
95     }\r
96     start += offset;\r
97     int vend = min(s.length() - 1, end + offset);\r
98     if (mask != c)\r
99     {\r
100       for (int i = start; i <= vend; i++)\r
101       {\r
102         if (0 == (s.charAt(i) & mask))\r
103         {\r
104           // if(m1||s.regionMatches(ign,i,src,0,src.length()) )\r
105           if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))\r
106           {\r
107             return i - offset;\r
108           }\r
109         }\r
110       }\r
111     }\r
112     else\r
113     {\r
114       for (int i = start; i <= vend; i++)\r
115       {\r
116         if (c == s.charAt(i))\r
117         {\r
118           // if(m1||s.regionMatches(ign,i,src,0,src.length()) )\r
119           if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))\r
120           {\r
121             return i - offset;\r
122           }\r
123         }\r
124       }\r
125     }\r
126     return -1;\r
127   }\r
128 \r
129   static Skip findSkip(Regex r)\r
130   {\r
131     return findSkip(r.thePattern, r.ignoreCase, !r.dontMatchInQuotes);\r
132   }\r
133 \r
134   // look for things that can be skipped\r
135   static Skip findSkip(Pattern p, boolean ignoreCase, boolean trnc)\r
136   {\r
137     javajs.util.SB sb = new javajs.util.SB();\r
138     Skip subsk = null;\r
139     int offset = 0;\r
140     int skipc = -1, skipoff = 0;\r
141     for (; p != null; p = p.next)\r
142     {\r
143       if (p instanceof oneChar)\r
144       {\r
145         skipc = ((oneChar) p).c;\r
146         skipoff = offset;\r
147       }\r
148       if (p instanceof oneChar && p.next instanceof oneChar)\r
149       {\r
150         Pattern psav = p;\r
151         sb.appendC(((oneChar) p).c);\r
152         while (p.next instanceof oneChar)\r
153         {\r
154           sb.appendC(((oneChar) p.next).c);\r
155           p = p.next;\r
156         }\r
157         String st = sb.toString();\r
158         Skip sk = null;\r
159         if (st.length() > 2)\r
160         {\r
161           sk = new SkipBMH(st, ignoreCase, offset);\r
162         }\r
163         else\r
164         {\r
165           sk = new Skip2(st, ignoreCase, offset);\r
166         }\r
167         if (trnc && st.length() > 2)\r
168         { // chop out a whole string...\r
169           psav.next = new Skipped(st.substring(1));\r
170           psav.next.next = p.next;\r
171           psav.next.parent = p.parent;\r
172         }\r
173         return sk;\r
174       }\r
175       else if (p instanceof Or\r
176               && ((Or) p).v.size() == 1\r
177               && !((Or) p).leftForm().equals("(?!")\r
178               && null != (subsk = findSkip((Pattern) ((Or) p).v\r
179                       .elementAt(0), ignoreCase, trnc)))\r
180       {\r
181         subsk.offset += offset;\r
182         return subsk;\r
183       }\r
184       else if (p.minChars().equals(p.maxChars()))\r
185       {\r
186         offset += p.minChars().intValue();\r
187       }\r
188       else\r
189       {\r
190         return skipc < 0 ? null : new Skip("" + (char) skipc, ignoreCase,\r
191                 skipoff);\r
192       }\r
193     }\r
194     return null;\r
195   }\r
196 }\r