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.ui.util.StringUtil;
9 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
10 import net.sourceforge.phpeclipse.views.PHPConsole;
12 import org.eclipse.core.resources.IFile;
13 import org.eclipse.core.resources.IMarker;
14 import org.eclipse.core.runtime.CoreException;
15 import org.eclipse.jface.dialogs.MessageDialog;
16 import org.eclipse.jface.preference.IPreferenceStore;
17 import org.eclipse.ui.texteditor.MarkerUtilities;
20 * Calls the external parser and generates problem markers if necessary
22 public class ExternalPHPParser {
23 private final static String PROBLEM_ID = "net.sourceforge.phpeclipse.problem";
24 // strings for external parser call
25 private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
26 private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
27 public static final int ERROR = 2;
28 public static final int WARNING = 1;
29 public static final int INFO = 0;
30 public static final int TASK = 3;
31 // TODO design error? Analyze why fileToParse must be static ???
32 final protected IFile fFileToParse;
34 public ExternalPHPParser(IFile file) {
38 * Call the php parse command ( php -l -f <filename> ) and create
39 * markers according to the external parser output.
42 * the file that will be parsed
44 public void phpExternalParse() {
45 //IFile file = (IFile) resource;
46 // final IPath path = file.getFullPath();
47 final IPreferenceStore store = PHPeclipsePlugin.getDefault()
48 .getPreferenceStore();
49 final String filename = fFileToParse.getLocation().toString();
51 final String[] arguments = {filename};
52 final MessageFormat form = new MessageFormat(store
53 .getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
54 final String command = form.format(arguments);
56 final String parserResult = getParserOutput(command,
60 // parse the buffer to find the errors and warnings
61 createMarkers(parserResult, fFileToParse);
62 } catch (CoreException e) {
67 * Create markers according to the external parser output.
70 * the external parser output
72 * the file that was parsed.
74 protected void createMarkers(final String output, final IFile file)
75 throws CoreException {
77 file.deleteMarkers(PROBLEM_ID, false, 0);
82 while ((brIndx = output.indexOf("<br />", indx)) != -1) {
83 // newer php error output (tested with 4.2.3)
84 scanLine(output, file, indx, brIndx);
89 while ((brIndx = output.indexOf("<br>", indx)) != -1) {
90 // older php error output (tested with 4.2.3)
91 scanLine(output, file, indx, brIndx);
97 private void scanLine(final String output, final IFile file,
98 final int indx, final int brIndx) throws CoreException {
100 // String outLineNumberString; never used
101 final StringBuffer lineNumberBuffer = new StringBuffer(10);
103 current = output.substring(indx, brIndx);
105 if (current.indexOf(PARSE_WARNING_STRING) != -1
106 || current.indexOf(PARSE_ERROR_STRING) != -1) {
107 final int onLine = current.indexOf("on line <b>");
109 lineNumberBuffer.delete(0, lineNumberBuffer.length());
110 for (int i = onLine; i < current.length(); i++) {
111 ch = current.charAt(i);
112 if ('0' <= ch && '9' >= ch) {
113 lineNumberBuffer.append(ch);
117 final int lineNumber = Integer.parseInt(lineNumberBuffer
120 final Hashtable attributes = new Hashtable();
122 current = StringUtil.replaceAll(current, "\n", "");
123 current = StringUtil.replaceAll(current, "<b>", "");
124 current = StringUtil.replaceAll(current, "</b>", "");
125 MarkerUtilities.setMessage(attributes, current);
127 if (current.indexOf(PARSE_ERROR_STRING) != -1)
128 attributes.put(IMarker.SEVERITY, new Integer(
129 IMarker.SEVERITY_ERROR));
130 else if (current.indexOf(PARSE_WARNING_STRING) != -1)
131 attributes.put(IMarker.SEVERITY, new Integer(
132 IMarker.SEVERITY_WARNING));
134 attributes.put(IMarker.SEVERITY, new Integer(
135 IMarker.SEVERITY_INFO));
136 MarkerUtilities.setLineNumber(attributes, lineNumber);
137 MarkerUtilities.createMarker(file, attributes, PROBLEM_ID);
143 * This will set a marker.
146 * the file that generated the marker
150 * the starting character
154 * the error level ({@link ExternalPHPParser#ERROR},
155 * {@link ExternalPHPParser#INFO},
156 * {@link ExternalPHPParser#WARNING}),
157 * {@link ExternalPHPParser#TASK})
158 * @throws CoreException
159 * an exception throwed by the MarkerUtilities
161 private void setMarker(final IFile file, final String message,
162 final int charStart, final int charEnd, final int errorLevel)
163 throws CoreException {
165 final Hashtable attributes = new Hashtable();
166 MarkerUtilities.setMessage(attributes, message);
167 switch (errorLevel) {
169 attributes.put(IMarker.SEVERITY, new Integer(
170 IMarker.SEVERITY_ERROR));
173 attributes.put(IMarker.SEVERITY, new Integer(
174 IMarker.SEVERITY_WARNING));
177 attributes.put(IMarker.SEVERITY, new Integer(
178 IMarker.SEVERITY_INFO));
181 attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
184 MarkerUtilities.setCharStart(attributes, charStart);
185 MarkerUtilities.setCharEnd(attributes, charEnd);
186 MarkerUtilities.createMarker(file, attributes, PROBLEM_ID);
191 * This will set a marker.
194 * the file that generated the marker
200 * the error level ({@link ExternalPHPParser#ERROR},
201 * {@link ExternalPHPParser#INFO},
202 * {@link ExternalPHPParser#WARNING})
203 * @throws CoreException
204 * an exception throwed by the MarkerUtilities
206 private void setMarker(final IFile file, final String message,
207 final int line, final int errorLevel, final String location)
208 throws CoreException {
210 String markerKind = PROBLEM_ID;
211 final Hashtable attributes = new Hashtable();
212 MarkerUtilities.setMessage(attributes, message);
213 switch (errorLevel) {
215 attributes.put(IMarker.SEVERITY, new Integer(
216 IMarker.SEVERITY_ERROR));
219 attributes.put(IMarker.SEVERITY, new Integer(
220 IMarker.SEVERITY_WARNING));
223 attributes.put(IMarker.SEVERITY, new Integer(
224 IMarker.SEVERITY_INFO));
227 attributes.put(IMarker.SEVERITY, new Integer(
228 IMarker.SEVERITY_INFO));
229 markerKind = IMarker.TASK;
232 attributes.put(IMarker.LOCATION, location);
233 MarkerUtilities.setLineNumber(attributes, line);
234 MarkerUtilities.createMarker(file, attributes, markerKind);
239 * This will set a marker.
244 * the starting character
248 * the error level ({@link ExternalPHPParser#ERROR},
249 * {@link ExternalPHPParser#INFO},
250 * {@link ExternalPHPParser#WARNING})
251 * @throws CoreException
252 * an exception throwed by the MarkerUtilities
254 private void setMarker(final String message, final int charStart,
255 final int charEnd, final int errorLevel, final String location)
256 throws CoreException {
257 if (fFileToParse != null) {
258 setMarker(fFileToParse, message, charStart, charEnd, errorLevel,
264 * This will set a marker.
267 * the file that generated the marker
271 * the starting character
275 * the error level ({@link ExternalPHPParser#ERROR},
276 * {@link ExternalPHPParser#INFO},
277 * {@link ExternalPHPParser#WARNING})
279 * the location of the error
280 * @throws CoreException
281 * an exception throwed by the MarkerUtilities
283 private void setMarker(final IFile file, final String message,
284 final int charStart, final int charEnd, final int errorLevel,
285 final String location) throws CoreException {
287 final Hashtable attributes = new Hashtable();
288 MarkerUtilities.setMessage(attributes, message);
289 switch (errorLevel) {
291 attributes.put(IMarker.SEVERITY, new Integer(
292 IMarker.SEVERITY_ERROR));
295 attributes.put(IMarker.SEVERITY, new Integer(
296 IMarker.SEVERITY_WARNING));
299 attributes.put(IMarker.SEVERITY, new Integer(
300 IMarker.SEVERITY_INFO));
303 attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
306 attributes.put(IMarker.LOCATION, location);
307 MarkerUtilities.setCharStart(attributes, charStart);
308 MarkerUtilities.setCharEnd(attributes, charEnd);
309 MarkerUtilities.createMarker(file, attributes, PROBLEM_ID); //IMarker.PROBLEM);
313 private String getParserOutput(String command, String consoleMessage) {
315 PHPConsole console = null;
317 console = PHPConsole.getInstance();
318 if (console != null) {
319 console.write(consoleMessage + command + "\n");
321 } catch (Throwable th) {
325 Runtime runtime = Runtime.getRuntime();
328 Process p = runtime.exec(command);
330 // gets the input stream to have the post-compile-time information
331 InputStream stream = p.getInputStream();
333 // get the string from Stream
334 String consoleOutput = PHPConsole.getStringFromStream(stream);
336 // prints out the information
337 if (console != null) {
338 console.write(consoleOutput);
340 return consoleOutput;
342 } catch (IOException e) {
344 .openInformation(null, "IOException: ", e.getMessage());