KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > MakefileFormatter


1 /*
2  * MakefileFormatter.java
3  *
4  * Copyright (C) 2000-2002 Peter Graves
5  * $Id: MakefileFormatter.java,v 1.1.1.1 2002/09/24 16:07:55 piso Exp $
6  *
7  * This program 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 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import gnu.regexp.RE;
25 import gnu.regexp.REMatch;
26 import gnu.regexp.UncheckedRE;
27
28 public final class MakefileFormatter extends Formatter
29 {
30     private static final int MAKEFILE_FORMAT_TEXT = 0;
31     private static final int MAKEFILE_FORMAT_COMMENT = 1;
32     private static final int MAKEFILE_FORMAT_STRING = 2;
33     private static final int MAKEFILE_FORMAT_KEYWORD = 3;
34     private static final int MAKEFILE_FORMAT_TARGET = 4;
35
36     private static final int STATE_BACKQUOTE = STATE_LAST + 1;
37
38     private FastStringBuffer sb = new FastStringBuffer();
39     private int tokStart;
40
41     private static final RE targetRE = new UncheckedRE("^\\S+.*:");
42     private static final RE assignmentRE = new UncheckedRE("^\\S+\\s*:?=");
43     private static final RE conditionalRE =
44         new UncheckedRE("^(ifn?(eq|def)\\s)|^(else\\s*)|^(endif\\s*)");
45
46     public MakefileFormatter(Buffer buffer)
47     {
48         this.buffer = buffer;
49     }
50
51     private void endToken(int state)
52     {
53         if (sb.length() > 0) {
54             int format;
55             switch (state) {
56                 case STATE_QUOTE:
57                 case STATE_SINGLEQUOTE:
58                 case STATE_BACKQUOTE:
59                     format = MAKEFILE_FORMAT_STRING;
60                     break;
61                 case STATE_COMMENT:
62                     format = MAKEFILE_FORMAT_COMMENT;
63                     break;
64                 default:
65                     format = MAKEFILE_FORMAT_TEXT;
66                     break;
67             }
68             addSegment(sb.toString(), format);
69             tokStart += sb.length();
70             sb.setLength(0);
71         }
72     }
73
74     private void addToken(String JavaDoc s, int format)
75     {
76         int length = s.length();
77         if (length > 0) {
78             addSegment(s, format);
79             tokStart += length;
80         }
81     }
82
83     private void parseLine(String JavaDoc text, int state)
84     {
85         if (Editor.tabsAreVisible())
86             text = Utilities.makeTabsVisible(text, buffer.getTabWidth());
87         else
88             text = Utilities.detab(text, buffer.getTabWidth());
89         clearSegmentList();
90         int braceCount = 0;
91         sb.setLength(0);
92         int i = 0;
93         tokStart = 0;
94         if (text.trim().startsWith("#")) {
95             addToken(text, MAKEFILE_FORMAT_COMMENT);
96             return;
97         }
98         // Try some regexps at the beginning of the line.
99
REMatch match = conditionalRE.getMatch(text);
100         if (match != null) {
101             addToken(match.toString(), MAKEFILE_FORMAT_KEYWORD);
102             i += match.toString().length();
103         } else {
104             match = assignmentRE.getMatch(text);
105             if (match != null) {
106                 addToken(match.toString(), MAKEFILE_FORMAT_TEXT);
107                 i += match.toString().length();
108             } else {
109                 match = targetRE.getMatch(text);
110                 if (match != null) {
111                     addToken(match.toString(), MAKEFILE_FORMAT_TARGET);
112                     i += match.toString().length();
113                 }
114             }
115         }
116         final int limit = text.length();
117         // Skip whitespace at start of line.
118
while (i < limit) {
119             char c = text.charAt(i);
120             if (Character.isWhitespace(c)) {
121                 sb.append(c);
122                 ++i;
123             } else {
124                 endToken(state);
125                 break;
126             }
127         }
128         while (i < limit) {
129             char c = text.charAt(i);
130             if (state == STATE_QUOTE) {
131                 sb.append(c);
132                 if (c == '"') {
133                     endToken(state);
134                     state = STATE_NEUTRAL;
135                 } else if (c == '\\' && i < limit-1) {
136                     // Escape char.
137
sb.append(text.charAt(++i));
138                 }
139                 ++i;
140                 continue;
141             }
142             if (state == STATE_SINGLEQUOTE) {
143                 sb.append(c);
144                 if (c == '\'') {
145                     endToken(state);
146                     state = STATE_NEUTRAL;
147                 }
148                 ++i;
149                 continue;
150             }
151             if (state == STATE_BACKQUOTE) {
152                 sb.append(c);
153                 if (c == '`') {
154                     endToken(state);
155                     state = STATE_NEUTRAL;
156                 }
157                 ++i;
158                 continue;
159             }
160             // Reaching here, we're not in a quoted string.
161
if (c == '"') {
162                 endToken(state);
163                 sb.append(c);
164                 state = STATE_QUOTE;
165                 ++i;
166                 continue;
167             }
168             if (c == '\'') {
169                 endToken(state);
170                 sb.append(c);
171                 state = STATE_SINGLEQUOTE;
172                 ++i;
173                 continue;
174             }
175             if (c == '`') {
176                 endToken(state);
177                 sb.append(c);
178                 state = STATE_BACKQUOTE;
179                 ++i;
180                 continue;
181             }
182             if (c == '#') {
183                 endToken(state);
184                 state = STATE_COMMENT;
185                 sb.append(text.substring(i));
186                 endToken(state);
187                 return;
188             }
189             if (state == STATE_IDENTIFIER) {
190                 if (buffer.mode.isIdentifierPart(c))
191                     sb.append(c);
192                 else {
193                     endToken(state);
194                     sb.append(c);
195                     state = STATE_NEUTRAL;
196                 }
197                 ++i;
198                 continue;
199             }
200             if (state == STATE_NUMBER) {
201                 if (Character.isDigit(c))
202                     sb.append(c);
203                 else {
204                     endToken(state);
205                     sb.append(c);
206                     if (buffer.mode.isIdentifierStart(c))
207                         state = STATE_IDENTIFIER;
208                     else
209                         state = STATE_NEUTRAL;
210                 }
211                 ++i;
212                 continue;
213             }
214             if (state == STATE_NEUTRAL) {
215                 if (buffer.mode.isIdentifierStart(c)) {
216                     endToken(state);
217                     sb.append(c);
218                     state = STATE_IDENTIFIER;
219                 } else if (Character.isDigit(c)) {
220                     endToken(state);
221                     sb.append(c);
222                     state = STATE_NUMBER;
223                 } else // Still neutral...
224
sb.append(c);
225             }
226             ++i;
227         }
228         endToken(state);
229     }
230
231     public LineSegmentList formatLine(Line line)
232     {
233         if (line == null) {
234             clearSegmentList();
235             addSegment("", MAKEFILE_FORMAT_TEXT);
236             return segmentList;
237         }
238         parseLine(line.getText(), line.flags());
239         for (int i = 0; i < segmentList.size(); i++) {
240             LineSegment segment = segmentList.getSegment(i);
241             if (segment.getFormat() > 0)
242                 continue;
243             String JavaDoc token = segment.getText();
244             if (isKeyword(token))
245                 segment.setFormat(MAKEFILE_FORMAT_KEYWORD);
246             else
247                 segment.setFormat(MAKEFILE_FORMAT_TEXT);
248         }
249         return segmentList;
250     }
251
252     public FormatTable getFormatTable()
253     {
254         if (formatTable == null) {
255             formatTable = new FormatTable("MakefileMode");
256             formatTable.addEntryFromPrefs(MAKEFILE_FORMAT_TEXT, "text");
257             formatTable.addEntryFromPrefs(MAKEFILE_FORMAT_COMMENT, "comment");
258             formatTable.addEntryFromPrefs(MAKEFILE_FORMAT_STRING, "string");
259             formatTable.addEntryFromPrefs(MAKEFILE_FORMAT_KEYWORD, "keyword");
260             formatTable.addEntryFromPrefs(MAKEFILE_FORMAT_TARGET, "target");
261         }
262         return formatTable;
263     }
264 }
265
Popular Tags