1 /*
2 * Fsgrep is a simple Java application which allows a user to
3 * search all files in a directory structure for lines matching
4 * a given pattern. Its functionality is a combination of the
5 * Unix 'find' and 'grep' utilities.
6 * Visit [http://fsgrep.sourceforge.net/] for more information.
7 *
8 * Copyright (C) 2003-2006 Murali Krishnan [murali_ca_us@users.sourceforge.net]
9 *
10 * Fsgrep is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public
12 * License as published by the Free Software Foundation.
13 *
14 * Fsgrep is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Fsgrep (see the file named LICENSE.txt); if not, write
21 * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22 * Boston, MA 02111-1307 USA
23 */
24
25 package mk.fsgrep.match;
26
27 import java.util.regex.*;
28
29 /***
30 *
31 *
32 * @author Murali Krishnan
33 *
34 */
35 public abstract class CodeSearch extends TextSearch {
36
37 //------------------------------------------------------------
38 //- Class Variables
39
40
41
42 //------------------------------------------------------------
43 //- Class Functions
44
45
46
47 //------------------------------------------------------------
48 //- Instance Variables
49
50 private boolean _inBlockComment = false;
51
52
53
54 //------------------------------------------------------------
55 //- Constructors
56
57
58 //------------------------------------------------------------
59 //- Accessors
60
61 public boolean isInBlockComment() {return _inBlockComment;}
62
63
64
65 //------------------------------------------------------------
66 //- Settors
67
68 public void setInBlockComment(boolean val) {_inBlockComment=val;}
69
70
71
72 //------------------------------------------------------------
73 //- Private/Protected Utility Functions
74
75
76 // This does not handle single-line blocks within multi-line blocks.
77 // But that is a fool's game.
78 // Note: this could be optimized. We are doing several pattern matches
79 // to determine if there is a comment or comment fragment on the current
80 // line. Instead, we could do a single check to determine whether there
81 // is a potential comment on the line, and then do all the remaining
82 // checks if there is. This should save MANY match checks.
83 protected boolean matchesNonComment(String origLine) {
84 String processed = origLine;
85 boolean startBlockAfterThisLine = false;
86 // System.out.println("orig[" + processed + "]");
87
88 // (0) First check if there could be a comment on this line. If not,
89 // then bypass the multiple matches done for comments.
90 boolean couldHaveComment = (rePrincipleCommentPattern() == null) ||
91 rePrincipleCommentPattern().matcher(processed).find();
92 if (couldHaveComment) {
93 // (1) Strip line comments.
94 if (reLineComment() != null) {
95 processed = reLineComment().matcher(processed).replaceAll("");
96 }
97 // System.out.println("step1[" + processed + "]");
98
99 // (2) Strip end of block comments.
100 if (isInBlockComment()) {
101 if (reBlockCommentEnd().matcher(processed).find()) {
102 setInBlockComment(false);
103 }
104 processed = reBlockCommentEnd().matcher(processed).replaceAll("");
105 }
106 // System.out.println("step2[" + processed + "]");
107
108 // (3) Strip all single-line block comments.
109 if (reBlockCommentOneLine() != null) {
110 processed = reBlockCommentOneLine().matcher(processed).replaceAll("");
111 }
112 // System.out.println("step3[" + processed + "]");
113
114 // (4) Strip start of block comments.
115 if (reBlockCommentStart() != null) {
116 startBlockAfterThisLine = reBlockCommentStart().matcher(processed).find();
117 processed = reBlockCommentStart().matcher(processed).replaceAll("");
118 }
119 // System.out.println("step4[" + processed + "]");
120 // System.out.println("in block: " + isInBlockComment());
121 }
122
123 boolean result = !isInBlockComment() && getRE().matcher(processed).find();
124 // System.out.println("match[" + processed + "]: " + result);
125
126 if (startBlockAfterThisLine) {
127 setInBlockComment(true);
128 }
129
130 return result;
131 }
132
133
134 protected void process(int linenum, String line) {
135 if (matchesNonComment(line)) {
136 handleMatch(linenum, line);
137 }
138
139 if (!isInBlockComment()) {
140 incrementLinesSearched();
141 }
142 }
143
144
145
146 //------------------------------------------------------------
147 //- Public Interface Functions
148
149
150
151 //------------------------------------------------------------
152 //- Class Interface Functions
153
154 protected Pattern rePrincipleCommentPattern() {return null;}
155 protected Pattern reLineComment() {return null;}
156 protected Pattern reBlockCommentStart() {return null;}
157 protected Pattern reBlockCommentEnd() {return null;}
158 protected Pattern reBlockCommentOneLine() {return null;}
159
160
161
162 //------------------------------------------------------------
163 //- Inner Classes
164
165
166
167 //------------------------------------------------------------
168 //- Main
169
170
171
172 }