1 package net.sourceforge.phpeclipse.actions;
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.text.MessageFormat;
6 import java.util.Hashtable;
8 //import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
9 import net.sourceforge.phpdt.internal.ui.util.StringUtil;
10 import net.sourceforge.phpdt.ui.PreferenceConstants;
11 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
12 import net.sourceforge.phpeclipse.views.PHPConsole;
14 import org.eclipse.core.resources.IFile;
15 import org.eclipse.core.resources.IMarker;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.jface.dialogs.MessageDialog;
18 import org.eclipse.jface.preference.IPreferenceStore;
19 import org.eclipse.ui.texteditor.MarkerUtilities;
22 * Calls the external parser and generates problem markers if necessary
24 public class ExternalPHPParser {
25 private final static String PROBLEM_ID = "net.sourceforge.phpeclipse.problem";
26 // strings for external parser call
27 private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
28 private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
29 public static final int ERROR = 2;
30 public static final int WARNING = 1;
31 public static final int INFO = 0;
32 public static final int TASK = 3;
33 // TODO design error? Analyze why fileToParse must be static ???
34 final protected IFile fFileToParse;
36 public ExternalPHPParser(IFile file) {
40 * Call the php parse command ( php -l -f <filename> ) and create
41 * markers according to the external parser output.
44 * the file that will be parsed
46 public void phpExternalParse() {
47 //IFile file = (IFile) resource;
48 // final IPath path = file.getFullPath();
49 final IPreferenceStore store = PHPeclipsePlugin.getDefault()
50 .getPreferenceStore();
51 final String filename = fFileToParse.getLocation().toString();
53 final String[] arguments = {filename};
54 final MessageFormat form = new MessageFormat(store
55 .getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
56 final String command = form.format(arguments);
58 final String parserResult = getParserOutput(command,
62 // parse the buffer to find the errors and warnings
63 createMarkers(parserResult, fFileToParse);
64 } catch (CoreException e) {
69 * Create markers according to the external parser output.
72 * the external parser output
74 * the file that was parsed.
76 protected void createMarkers(final String output, final IFile file)
77 throws CoreException {
79 file.deleteMarkers(PROBLEM_ID, false, 0);
84 while ((brIndx = output.indexOf("<br />", indx)) != -1) {
85 // newer php error output (tested with 4.2.3)
86 scanLine(output, file, indx, brIndx);
91 while ((brIndx = output.indexOf("<br>", indx)) != -1) {
92 // older php error output (tested with 4.2.3)
93 scanLine(output, file, indx, brIndx);
99 private void scanLine(final String output, final IFile file,
100 final int indx, final int brIndx) throws CoreException {
102 // String outLineNumberString; never used
103 final StringBuffer lineNumberBuffer = new StringBuffer(10);
105 current = output.substring(indx, brIndx);
107 if (current.indexOf(PARSE_WARNING_STRING) != -1
108 || current.indexOf(PARSE_ERROR_STRING) != -1) {
109 final int onLine = current.indexOf("on line <b>");
111 lineNumberBuffer.delete(0, lineNumberBuffer.length());
112 for (int i = onLine; i < current.length(); i++) {
113 ch = current.charAt(i);
114 if ('0' <= ch && '9' >= ch) {
115 lineNumberBuffer.append(ch);
119 final int lineNumber = Integer.parseInt(lineNumberBuffer
122 final Hashtable attributes = new Hashtable();
124 current = StringUtil.replaceAll(current, "\n", "");
125 current = StringUtil.replaceAll(current, "<b>", "");
126 current = StringUtil.replaceAll(current, "</b>", "");
127 MarkerUtilities.setMessage(attributes, current);
129 if (current.indexOf(PARSE_ERROR_STRING) != -1)
130 attributes.put(IMarker.SEVERITY, new Integer(
131 IMarker.SEVERITY_ERROR));
132 else if (current.indexOf(PARSE_WARNING_STRING) != -1)
133 attributes.put(IMarker.SEVERITY, new Integer(
134 IMarker.SEVERITY_WARNING));
136 attributes.put(IMarker.SEVERITY, new Integer(
137 IMarker.SEVERITY_INFO));
138 MarkerUtilities.setLineNumber(attributes, lineNumber);
139 MarkerUtilities.createMarker(file, attributes, PROBLEM_ID);
145 * This will set a marker.
148 * the file that generated the marker
152 * the starting character
156 * the error level ({@link ExternalPHPParser#ERROR},
157 * {@link ExternalPHPParser#INFO},
158 * {@link ExternalPHPParser#WARNING}),
159 * {@link ExternalPHPParser#TASK})
160 * @throws CoreException
161 * an exception throwed by the MarkerUtilities
163 private void setMarker(final IFile file, final String message,
164 final int charStart, final int charEnd, final int errorLevel)
165 throws CoreException {
167 final Hashtable attributes = new Hashtable();
168 MarkerUtilities.setMessage(attributes, message);
169 switch (errorLevel) {
171 attributes.put(IMarker.SEVERITY, new Integer(
172 IMarker.SEVERITY_ERROR));
175 attributes.put(IMarker.SEVERITY, new Integer(
176 IMarker.SEVERITY_WARNING));
179 attributes.put(IMarker.SEVERITY, new Integer(
180 IMarker.SEVERITY_INFO));
183 attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
186 MarkerUtilities.setCharStart(attributes, charStart);
187 MarkerUtilities.setCharEnd(attributes, charEnd);
188 MarkerUtilities.createMarker(file, attributes, PROBLEM_ID);
193 * This will set a marker.
196 * the file that generated the marker
202 * the error level ({@link ExternalPHPParser#ERROR},
203 * {@link ExternalPHPParser#INFO},
204 * {@link ExternalPHPParser#WARNING})
205 * @throws CoreException
206 * an exception throwed by the MarkerUtilities
208 private void setMarker(final IFile file, final String message,
209 final int line, final int errorLevel, final String location)
210 throws CoreException {
212 String markerKind = PROBLEM_ID;
213 final Hashtable attributes = new Hashtable();
214 MarkerUtilities.setMessage(attributes, message);
215 switch (errorLevel) {
217 attributes.put(IMarker.SEVERITY, new Integer(
218 IMarker.SEVERITY_ERROR));
221 attributes.put(IMarker.SEVERITY, new Integer(
222 IMarker.SEVERITY_WARNING));
225 attributes.put(IMarker.SEVERITY, new Integer(
226 IMarker.SEVERITY_INFO));
229 attributes.put(IMarker.SEVERITY, new Integer(
230 IMarker.SEVERITY_INFO));
231 markerKind = IMarker.TASK;
234 attributes.put(IMarker.LOCATION, location);
235 MarkerUtilities.setLineNumber(attributes, line);
236 MarkerUtilities.createMarker(file, attributes, markerKind);
241 * This will set a marker.
246 * the starting character
250 * the error level ({@link ExternalPHPParser#ERROR},
251 * {@link ExternalPHPParser#INFO},
252 * {@link ExternalPHPParser#WARNING})
253 * @throws CoreException
254 * an exception throwed by the MarkerUtilities
256 private void setMarker(final String message, final int charStart,
257 final int charEnd, final int errorLevel, final String location)
258 throws CoreException {
259 if (fFileToParse != null) {
260 setMarker(fFileToParse, message, charStart, charEnd, errorLevel,
266 * This will set a marker.
269 * the file that generated the marker
273 * the starting character
277 * the error level ({@link ExternalPHPParser#ERROR},
278 * {@link ExternalPHPParser#INFO},
279 * {@link ExternalPHPParser#WARNING})
281 * the location of the error
282 * @throws CoreException
283 * an exception throwed by the MarkerUtilities
285 private void setMarker(final IFile file, final String message,
286 final int charStart, final int charEnd, final int errorLevel,
287 final String location) throws CoreException {
289 final Hashtable attributes = new Hashtable();
290 MarkerUtilities.setMessage(attributes, message);
291 switch (errorLevel) {
293 attributes.put(IMarker.SEVERITY, new Integer(
294 IMarker.SEVERITY_ERROR));
297 attributes.put(IMarker.SEVERITY, new Integer(
298 IMarker.SEVERITY_WARNING));
301 attributes.put(IMarker.SEVERITY, new Integer(
302 IMarker.SEVERITY_INFO));
305 attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
308 attributes.put(IMarker.LOCATION, location);
309 MarkerUtilities.setCharStart(attributes, charStart);
310 MarkerUtilities.setCharEnd(attributes, charEnd);
311 MarkerUtilities.createMarker(file, attributes, PROBLEM_ID); //IMarker.PROBLEM);
315 private String getParserOutput(String command, String consoleMessage) {
317 PHPConsole console = null;
319 console = PHPConsole.getInstance();
320 if (console != null) {
321 console.write(consoleMessage + command + "\n");
323 } catch (Throwable th) {
327 Runtime runtime = Runtime.getRuntime();
330 Process p = runtime.exec(command);
332 // gets the input stream to have the post-compile-time information
333 InputStream stream = p.getInputStream();
335 // get the string from Stream
336 String consoleOutput = PHPConsole.getStringFromStream(stream);
338 // prints out the information
339 if (console != null) {
340 console.write(consoleOutput);
342 return consoleOutput;
344 } catch (IOException e) {
346 .openInformation(null, "IOException: ", e.getMessage());