1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
---|
2 | * JFlex 1.4.3 *
|
---|
3 | * Copyright (C) 1998-2009 Gerwin Klein <[email protected]> *
|
---|
4 | * All rights reserved. *
|
---|
5 | * *
|
---|
6 | * This program is free software; you can redistribute it and/or modify *
|
---|
7 | * it under the terms of the GNU General Public License. See the file *
|
---|
8 | * COPYRIGHT for more information. *
|
---|
9 | * *
|
---|
10 | * This program is distributed in the hope that it will be useful, *
|
---|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
---|
13 | * GNU General Public License for more details. *
|
---|
14 | * *
|
---|
15 | * You should have received a copy of the GNU General Public License along *
|
---|
16 | * with this program; if not, write to the Free Software Foundation, Inc., *
|
---|
17 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
|
---|
18 | * *
|
---|
19 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
---|
20 | package JFlex;
|
---|
21 |
|
---|
22 | import java.io.*;
|
---|
23 | import java.net.URL;
|
---|
24 | import java.util.Vector;
|
---|
25 |
|
---|
26 |
|
---|
27 | /**
|
---|
28 | * This class stores the skeleton of generated scanners.
|
---|
29 | *
|
---|
30 | * The skeleton consists of several parts that can be emitted to
|
---|
31 | * a file. Usually there is a portion of generated code
|
---|
32 | * (produced in class Emitter) between every two parts of skeleton code.
|
---|
33 | *
|
---|
34 | * There is a static part (the skeleton code) and state based iterator
|
---|
35 | * part to this class. The iterator part is used to emit consecutive skeleton
|
---|
36 | * sections to some <code>PrintWriter</code>.
|
---|
37 | *
|
---|
38 | * @see JFlex.Emitter
|
---|
39 | *
|
---|
40 | * @author Gerwin Klein
|
---|
41 | * @version JFlex 1.4.3, $Revision: 433 $, $Date: 2009-01-31 19:52:34 +1100 (Sat, 31 Jan 2009) $
|
---|
42 | */
|
---|
43 | public class Skeleton {
|
---|
44 |
|
---|
45 | /** location of default skeleton */
|
---|
46 | static final private String DEFAULT_LOC = "JFlex/skeleton.default"; //$NON-NLS-1$
|
---|
47 |
|
---|
48 | /** expected number of sections in the skeleton file */
|
---|
49 | static final private int size = 21;
|
---|
50 |
|
---|
51 | /** platform specific newline */
|
---|
52 | static final private String NL = System.getProperty("line.separator"); //$NON-NLS-1$
|
---|
53 |
|
---|
54 | /** The skeleton */
|
---|
55 | public static String line[];
|
---|
56 |
|
---|
57 | /** initialization */
|
---|
58 | static { readDefault(); }
|
---|
59 |
|
---|
60 | // the state based, iterator part of Skeleton:
|
---|
61 |
|
---|
62 | /**
|
---|
63 | * The current part of the skeleton (an index of nextStop[])
|
---|
64 | */
|
---|
65 | private int pos;
|
---|
66 |
|
---|
67 | /**
|
---|
68 | * The writer to write the skeleton-parts to
|
---|
69 | */
|
---|
70 | private PrintWriter out;
|
---|
71 |
|
---|
72 |
|
---|
73 | /**
|
---|
74 | * Creates a new skeleton (iterator) instance.
|
---|
75 | *
|
---|
76 | * @param out the writer to write the skeleton-parts to
|
---|
77 | */
|
---|
78 | public Skeleton(PrintWriter out) {
|
---|
79 | this.out = out;
|
---|
80 | }
|
---|
81 |
|
---|
82 |
|
---|
83 | /**
|
---|
84 | * Emits the next part of the skeleton
|
---|
85 | */
|
---|
86 | public void emitNext() {
|
---|
87 | out.print( line[pos++] );
|
---|
88 | }
|
---|
89 |
|
---|
90 |
|
---|
91 | /**
|
---|
92 | * Make the skeleton private.
|
---|
93 | *
|
---|
94 | * Replaces all occurences of " public " in the skeleton with " private ".
|
---|
95 | */
|
---|
96 | public static void makePrivate() {
|
---|
97 | for (int i=0; i < line.length; i++) {
|
---|
98 | line[i] = replace(" public ", " private ", line[i]); //$NON-NLS-1$ //$NON-NLS-2$
|
---|
99 | }
|
---|
100 | }
|
---|
101 |
|
---|
102 |
|
---|
103 | /**
|
---|
104 | * Reads an external skeleton file for later use with this class.
|
---|
105 | *
|
---|
106 | * @param skeletonFile the file to read (must be != null and readable)
|
---|
107 | */
|
---|
108 | public static void readSkelFile(File skeletonFile) {
|
---|
109 | if (skeletonFile == null)
|
---|
110 | throw new IllegalArgumentException("Skeleton file must not be null"); //$NON-NLS-1$
|
---|
111 |
|
---|
112 | if (!skeletonFile.isFile() || !skeletonFile.canRead()) {
|
---|
113 | Out.error(ErrorMessages.CANNOT_READ_SKEL, skeletonFile.toString());
|
---|
114 | throw new GeneratorException();
|
---|
115 | }
|
---|
116 |
|
---|
117 | Out.println(ErrorMessages.READING_SKEL, skeletonFile.toString());
|
---|
118 |
|
---|
119 | try {
|
---|
120 | BufferedReader reader = new BufferedReader(new FileReader(skeletonFile));
|
---|
121 | readSkel(reader);
|
---|
122 | }
|
---|
123 | catch (IOException e) {
|
---|
124 | Out.error(ErrorMessages.SKEL_IO_ERROR);
|
---|
125 | throw new GeneratorException();
|
---|
126 | }
|
---|
127 | }
|
---|
128 |
|
---|
129 |
|
---|
130 | /**
|
---|
131 | * Reads an external skeleton file from a BufferedReader.
|
---|
132 | *
|
---|
133 | * @param reader the reader to read from (must be != null)
|
---|
134 | * @throws IOException if an IO error occurs
|
---|
135 | * @throws GeneratorException if the number of skeleton sections does not match
|
---|
136 | */
|
---|
137 | public static void readSkel(BufferedReader reader) throws IOException {
|
---|
138 | Vector lines = new Vector();
|
---|
139 | StringBuffer section = new StringBuffer();
|
---|
140 |
|
---|
141 | String ln;
|
---|
142 | while ((ln = reader.readLine()) != null) {
|
---|
143 | if (ln.startsWith("---")) { //$NON-NLS-1$
|
---|
144 | lines.addElement(section.toString());
|
---|
145 | section.setLength(0);
|
---|
146 | } else {
|
---|
147 | section.append(ln);
|
---|
148 | section.append(NL);
|
---|
149 | }
|
---|
150 | }
|
---|
151 |
|
---|
152 | if (section.length() > 0)
|
---|
153 | lines.addElement(section.toString());
|
---|
154 |
|
---|
155 | if (lines.size() != size) {
|
---|
156 | Out.error(ErrorMessages.WRONG_SKELETON);
|
---|
157 | throw new GeneratorException();
|
---|
158 | }
|
---|
159 |
|
---|
160 | line = new String[size];
|
---|
161 | for (int i = 0; i < size; i++)
|
---|
162 | line[i] = (String) lines.elementAt(i);
|
---|
163 | }
|
---|
164 |
|
---|
165 | /**
|
---|
166 | * Replaces a with b in c.
|
---|
167 | *
|
---|
168 | * @param a the String to be replaced
|
---|
169 | * @param b the replacement
|
---|
170 | * @param c the String in which to replace a by b
|
---|
171 | * @return a String object with a replaced by b in c
|
---|
172 | */
|
---|
173 | public static String replace(String a, String b, String c) {
|
---|
174 | StringBuffer result = new StringBuffer(c.length());
|
---|
175 | int i = 0;
|
---|
176 | int j = c.indexOf(a);
|
---|
177 |
|
---|
178 | while (j >= i) {
|
---|
179 | result.append(c.substring(i,j));
|
---|
180 | result.append(b);
|
---|
181 | i = j+a.length();
|
---|
182 | j = c.indexOf(a,i);
|
---|
183 | }
|
---|
184 |
|
---|
185 | result.append(c.substring(i,c.length()));
|
---|
186 |
|
---|
187 | return result.toString();
|
---|
188 | }
|
---|
189 |
|
---|
190 |
|
---|
191 | /**
|
---|
192 | * (Re)load the default skeleton. Looks in the current system class path.
|
---|
193 | */
|
---|
194 | public static void readDefault() {
|
---|
195 | ClassLoader l = Skeleton.class.getClassLoader();
|
---|
196 | URL url;
|
---|
197 |
|
---|
198 | /* Try to load from same class loader as this class.
|
---|
199 | * Should work, but does not on OS/2 JDK 1.1.8 (see bug 1065521).
|
---|
200 | * Use system class loader in this case.
|
---|
201 | */
|
---|
202 | if (l != null) {
|
---|
203 | url = l.getResource(DEFAULT_LOC);
|
---|
204 | }
|
---|
205 | else {
|
---|
206 | url = ClassLoader.getSystemResource(DEFAULT_LOC);
|
---|
207 | }
|
---|
208 |
|
---|
209 | if (url == null) {
|
---|
210 | Out.error(ErrorMessages.SKEL_IO_ERROR_DEFAULT);
|
---|
211 | throw new GeneratorException();
|
---|
212 | }
|
---|
213 |
|
---|
214 | try {
|
---|
215 | InputStreamReader reader = new InputStreamReader(url.openStream());
|
---|
216 | readSkel(new BufferedReader(reader));
|
---|
217 | } catch (IOException e) {
|
---|
218 | Out.error(ErrorMessages.SKEL_IO_ERROR_DEFAULT);
|
---|
219 | throw new GeneratorException();
|
---|
220 | }
|
---|
221 | }
|
---|
222 | }
|
---|