diff --git a/de.prob.core/META-INF/MANIFEST.MF b/de.prob.core/META-INF/MANIFEST.MF index c6229c4b01e5b5a128ee8379654d9364e7f42a31..2f3d359c07ad719443a4bbc159ac0e642feb3076 100644 --- a/de.prob.core/META-INF/MANIFEST.MF +++ b/de.prob.core/META-INF/MANIFEST.MF @@ -39,7 +39,6 @@ Export-Package: de.be4.classicalb.core.parser, de.be4.ltl.core.parser.parser, de.hhu.stups.sablecc.patch, de.prob.cli, - de.prob.cli.clipatterns, de.prob.core, de.prob.core.command, de.prob.core.command.internal, diff --git a/de.prob.core/src/de/prob/cli/CliStarter.java b/de.prob.core/src/de/prob/cli/CliStarter.java index 8d987d5857900e55dfb4bd36390b9bec60a7daa3..905148c1f4d1b2069e5775663c8f9bbd08f0cc52 100644 --- a/de.prob.core/src/de/prob/cli/CliStarter.java +++ b/de.prob.core/src/de/prob/cli/CliStarter.java @@ -9,6 +9,8 @@ package de.prob.cli; import java.io.*; import java.net.*; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; @@ -16,15 +18,17 @@ import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.runtime.*; import org.osgi.framework.Bundle; -import de.prob.cli.clipatterns.*; import de.prob.core.internal.Activator; import de.prob.logging.Logger; public final class CliStarter { + private static final Pattern CLI_PORT_PATTERN = Pattern.compile("^.*Port: (\\d+)$"); + private static final Pattern CLI_USER_INTERRUPT_REFERENCE_PATTERN = Pattern.compile("^.*user interrupt reference id: *(\\d+|off) *$"); + private Process prologProcess; private int port = -1; - private Long userInterruptReference = null; + private long userInterruptReference = -1L; private OutputLoggerThread stdLogger; private OutputLoggerThread errLogger; @@ -193,11 +197,45 @@ public final class CliStarter { private void extractCliInformation(final BufferedReader input) throws CliException { - final PortPattern portPattern = new PortPattern(); - final InterruptRefPattern intPattern = new InterruptRefPattern(); - analyseStdout(input, Arrays.asList(portPattern, intPattern)); - port = portPattern.getValue(); - userInterruptReference = intPattern.getValue(); + Integer portTemp = null; + Long userInterruptReferenceTemp = null; + try { + for (String line; (line = input.readLine()) != null;) { + Logger.info("probcli startup output: " + line); + + Matcher portMatcher = CLI_PORT_PATTERN.matcher(line); + if (portMatcher.matches()) { + portTemp = Integer.parseInt(portMatcher.group(1)); + Logger.info("Received port number from CLI: " + portTemp); + } + + Matcher userInterruptReferenceMatcher = CLI_USER_INTERRUPT_REFERENCE_PATTERN.matcher(line); + if (userInterruptReferenceMatcher.matches()) { + String userInterruptReferenceString = userInterruptReferenceMatcher.group(1); + if ("off".equals(userInterruptReferenceString)) { + userInterruptReferenceTemp = -1L; + Logger.info("This ProB build has user interrupt support disabled. Interrupting ProB may not work as expected."); + } else { + userInterruptReferenceTemp = Long.parseLong(userInterruptReferenceString); + Logger.info("Received user interrupt reference from CLI: " + userInterruptReferenceTemp); + } + } + + if ((portTemp != null && userInterruptReferenceTemp != null) || line.contains("starting command loop")) { + break; + } + } + } catch (IOException | NumberFormatException e) { + throw new CliException("Error while reading information from CLI", e, false); + } + + if (portTemp == null) { + throw new CliException("Did not receive port number from CLI"); + } else if (userInterruptReferenceTemp == null) { + throw new CliException("Did not receive user interrupt reference from CLI"); + } + port = portTemp; + userInterruptReference = userInterruptReferenceTemp; } private void startOutputLogger(final BufferedReader input) { @@ -210,38 +248,6 @@ public final class CliStarter { errLogger.start(); } - private void analyseStdout(final BufferedReader input, - Collection<? extends CliPattern<?>> patterns) throws CliException { - patterns = new ArrayList<CliPattern<?>>(patterns); - try { - String line; - boolean endReached = false; - while (!endReached && (line = input.readLine()) != null) { - Logger.info("probcli startup output: " + line); - applyPatterns(patterns, line); - endReached = patterns.isEmpty() - || line.contains("starting command loop"); // printed in prob_socketserver.pl - } - } catch (IOException e) { - throw new CliException("Problem while starting ProB. Cannot read from input stream.", e, true); - } - for (CliPattern<?> p : patterns) { - p.notFound(); - } - } - - private void applyPatterns( - final Collection<? extends CliPattern<?>> patterns, - final String line) { - for (Iterator<? extends CliPattern<?>> it = patterns.iterator(); it - .hasNext();) { - final CliPattern<?> p = it.next(); - if (p.matchesLine(line)) { - it.remove(); - } - } - } - private File getCliPath() throws CliException { final Bundle bundle = Activator.getDefault().getBundle(); final URL entry = bundle.getEntry("prob"); @@ -326,7 +332,7 @@ public final class CliStarter { } public void sendUserInterruptReference() { - if (userInterruptReference != null) { + if (userInterruptReference != -1) { try { final OsSpecificInfo osInfo = getOsInfo(Platform.getOS()); final String command = getCliPath() + File.separator @@ -339,7 +345,7 @@ public final class CliStarter { Runtime.getRuntime().exec( new String[] { command, - userInterruptReference.toString() }); + String.valueOf(userInterruptReference) }); } catch (CliException e) { Logger.info("getting the os specific info failed with exception: " + e.getLocalizedMessage()); diff --git a/de.prob.core/src/de/prob/cli/clipatterns/CliPattern.java b/de.prob.core/src/de/prob/cli/clipatterns/CliPattern.java deleted file mode 100644 index 5d59454c40c9d2e9323fb6992d4213bdf8bb26c1..0000000000000000000000000000000000000000 --- a/de.prob.core/src/de/prob/cli/clipatterns/CliPattern.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * - */ -package de.prob.cli.clipatterns; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import de.prob.cli.CliException; - -/** - * Base class for doing pattern matching on the standard output on startup of - * the ProB command line executable. - * - * @author plagge - */ -public abstract class CliPattern<T> { - private final Pattern pattern; - private Matcher matcher; - - protected CliPattern(String regex) { - this.pattern = Pattern.compile(regex); - } - - /** - * Is called for each line of the standard output until this object matches - * a line or until the command loop starts. - * - * @param line - * the standard output line as string - * @return if the line matches - */ - public boolean matchesLine(String line) { - matcher = pattern.matcher(line); - final boolean hit = matcher.find(); - if (hit) { - setValue(matcher); - } - return hit; - } - - /** - * If the current line matches the pattern, this method is called with the - * resulting {@link Matcher} object. An implementation of this method should - * find a value that can be accessed via {@link #getValue()}. - * - * @param matcher - */ - protected abstract void setValue(Matcher matcher); - - /** - * Returns the resulting value determined by the input line. - * - * @return - */ - public abstract T getValue(); - - /** - * This method is called if no line matched on this pattern and the start of - * the command loop is reached. - * - * @throws CliException - */ - public abstract void notFound() throws CliException; -} diff --git a/de.prob.core/src/de/prob/cli/clipatterns/InterruptRefPattern.java b/de.prob.core/src/de/prob/cli/clipatterns/InterruptRefPattern.java deleted file mode 100644 index 65ab44dd2d3c4b0582a24ca851549d273f1dee3b..0000000000000000000000000000000000000000 --- a/de.prob.core/src/de/prob/cli/clipatterns/InterruptRefPattern.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * - */ -package de.prob.cli.clipatterns; - -import java.util.regex.Matcher; - -import de.prob.cli.CliException; -import de.prob.logging.Logger; - -/** - * Extracts the reference for user interrupt calls from the process' startup - * information. The reference must be later passed to the send_interrupt command - * when an user interrupt should be signalled. - * - * @author plagge - */ -public class InterruptRefPattern extends CliPattern<Long> { - - private Long reference; - - public InterruptRefPattern() { - super("user interrupt reference id: *(\\d+) *$"); - } - - @Override - protected void setValue(final Matcher matcher) { - reference = Long.parseLong(matcher.group(1)); - Logger.info("Server can receive user interrupts via reference " - + reference); - } - - @Override - public Long getValue() { - return reference; - } - - @Override - public void notFound() throws CliException { - Logger.notifyUser("Could not determine user interrupt reference of ProB server. " - + "You might not be able to interrupt a running calculation."); - } - -} diff --git a/de.prob.core/src/de/prob/cli/clipatterns/PortPattern.java b/de.prob.core/src/de/prob/cli/clipatterns/PortPattern.java deleted file mode 100644 index 19724b1a772a4da213176fafb3ec610ed545e30f..0000000000000000000000000000000000000000 --- a/de.prob.core/src/de/prob/cli/clipatterns/PortPattern.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * - */ -package de.prob.cli.clipatterns; - -import java.util.regex.Matcher; - -import de.prob.cli.CliException; -import de.prob.logging.Logger; - -/** - * This {@link CliPattern} looks for a network port number where the executable - * listens for commands. - * - * If no port number is found, {@link #notFound()} throws a {@link CliException} - * - * @author plagge - */ -public class PortPattern extends CliPattern<Integer> { - int port; - - public PortPattern() { - super("Port: (\\d+)$"); - } - - @Override - protected void setValue(Matcher matcher) throws IllegalArgumentException { - port = Integer.parseInt(matcher.group(1)); - Logger.info("Server has startet and listens on port " + port); - } - - /** - * Returns the port number. - */ - @Override - public Integer getValue() { - return port; - } - - @Override - public void notFound() throws CliException { - throw new CliException("Could not determine port of ProB server"); - } - -}