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());