| 1 | // Copyright © 2004-2006 University of Helsinki, Department of Computer Science | |
| 2 | // Copyright © 2012 various contributors | |
| 3 | // This software is released under GNU Lesser General Public License 2.1. | |
| 4 | // The license text is at http://www.gnu.org/licenses/lgpl-2.1.html | |
| 5 | package fi.helsinki.cs.titokone; | |
| 6 | ||
| 7 | import fi.helsinki.cs.ttk91.*; | |
| 8 | ||
| 9 | import java.io.*; | |
| 10 | import java.text.ParseException; | |
| 11 | import java.util.ResourceBundle; | |
| 12 | import java.util.logging.Logger; | |
| 13 | ||
| 14 | /** | |
| 15 | * Control class offers the extenal interface to titokone. Using the | |
| 16 | * methods of this class one can compile and emulate the execution | |
| 17 | * process of a ttk91-program from a text file or straight from a | |
| 18 | * string object, which contain symbolic ttk91 machine code, A | |
| 19 | * complete debugging and trackability of compilation, loading and | |
| 20 | * execution cycles are provided with CompileInfo, LoadInfo and | |
| 21 | * RunInfo objects, which can be used to get information of what had | |
| 22 | * just happened. | |
| 23 | * <p/> | |
| 24 | * This doesn't take a position on how to show the output. That's | |
| 25 | * left for the GUI, actually a piece of code between Control | |
| 26 | * and the GUI, which prepares the output provided here to be shown | |
| 27 | * in GUI. In this software that piece of code is the GUIBrain class. | |
| 28 | */ | |
| 29 | public class Control implements TTK91Core { | |
| 30 | /** | |
| 31 | * This is the memory size that will be used by default, unless | |
| 32 | * a higher class (GUIBrain) chooses to change the size later. | |
| 33 | * The size is expressed as "the power of two which will give the | |
| 34 | * wanted memory size"; here 15 means that the actual memory will be | |
| 35 | * 2^15 = 32768 words long. | |
| 36 | */ | |
| 37 | public static final int DEFAULT_MEMORY_SIZE = 15; | |
| 38 | ||
| 39 | /** | |
| 40 | * This field set directs handling of an array containing file | |
| 41 | * definitions set in the application. See getApplicationDefinitions(). | |
| 42 | */ | |
| 43 | public static final int DEF_STDIN_POS = 0; | |
| 44 | public static final int DEF_STDOUT_POS = 1; | |
| 45 | public static final int DEF_HOME_POS = 2; | |
| 46 | ||
| 47 | /** | |
| 48 | * This has control to all the files this program has opened. | |
| 49 | */ | |
| 50 | private FileHandler fileHandler; | |
| 51 | ||
| 52 | private Processor processor; | |
| 53 | ||
| 54 | private Compiler compiler; | |
| 55 | ||
| 56 | private Application application; | |
| 57 | ||
| 58 | private File defaultStdInFile, defaultStdOutFile, currentStdOutFile, | |
| 59 | sourceFile; | |
| 60 | ||
| 61 | 1 | private LoadInfo pendingLoadInfo = null; |
| 62 | ||
| 63 | /** | |
| 64 | * This constructor sets up the Control instance. | |
| 65 | */ | |
| 66 | public Control(File defaultStdInFile, File defaultStdOutFile) { | |
| 67 | Logger logger = Logger.getLogger(getClass().getPackage().getName()); | |
| 68 | ||
| 69 | 1 | if (defaultStdInFile == null) { |
| 70 | logger.info(new Message("No default STDIN file set.").toString()); | |
| 71 | } | |
| 72 | 1 | if (defaultStdOutFile == null) { |
| 73 | logger.info(new Message("No default STDOUT file set.").toString()); | |
| 74 | } | |
| 75 | 2 | fileHandler = new FileHandler(); |
| 76 | 2 | compiler = new Compiler(); |
| 77 | // Create a new processor with a memory size of 2^9. | |
| 78 | 3 | changeMemorySize(DEFAULT_MEMORY_SIZE); |
| 79 | 1 | this.defaultStdInFile = defaultStdInFile; |
| 80 | 1 | this.defaultStdOutFile = defaultStdOutFile; |
| 81 | 1 | currentStdOutFile = defaultStdOutFile; |
| 82 | } | |
| 83 | ||
| 84 | /** | |
| 85 | * Compiles a symbolic TTK91-assembly language to binary executable | |
| 86 | * application. Defined by TTK91Core. It throws exceptions if the | |
| 87 | * compilation (eg. Compiler) throws them. | |
| 88 | * | |
| 89 | * @param source The source code to be compiled. | |
| 90 | * @return The binary executable code. | |
| 91 | * @throws TTK91CompileException If the compiler throws one. | |
| 92 | * @throws TTK91Exception Never in this implementation. (Except for | |
| 93 | * TTK91CompileExceptions, which inherit it.) | |
| 94 | */ | |
| 95 | public TTK91Application compile(TTK91CompileSource source) | |
| 96 | throws TTK91Exception, TTK91CompileException { | |
| 97 | 2 | compiler.compile(source.getSource()); |
| 98 | // Compile lines, basically ignoring the output, until no more | |
| 99 | // CompileInfos are returned. | |
| 100 | 2 | while (compileLine() != null) { |
| 101 | ; // All is done in compileLine(). | |
| 102 | } | |
| 103 | 2 | application = compiler.getApplication(); |
| 104 | 1 | return application; |
| 105 | } | |
| 106 | ||
| 107 | /** | |
| 108 | * This method loads an application that has been either compiled | |
| 109 | * or read from binary earlier. It calls Loader's | |
| 110 | * setApplicationToLoad and then loadApplication methods. It also | |
| 111 | * sets up the STDIN contents from the default file to the Application. | |
| 112 | * If this fails, a ParseException is thrown just before the method | |
| 113 | * should return. It can be ignored until it leads to a | |
| 114 | * TTK91NoStdInData exception when a program tries to read from STDIN. | |
| 115 | * | |
| 116 | * @throws TTK91OutOfMemory If the memory cannot fit the | |
| 117 | * application. | |
| 118 | * @throws TTK91NoStdInData If the current STDIN file contains invalid | |
| 119 | * STDIN input or the file cannot be opened. | |
| 120 | * @throws IllegalStateException If application is null. | |
| 121 | */ | |
| 122 | public LoadInfo load() | |
| 123 | throws TTK91AddressOutOfBounds, TTK91NoStdInData { | |
| 124 | String errorMessage = ""; | |
| 125 | 2 | boolean pendingException = false; |
| 126 | File[] appDefinitions; | |
| 127 | LoadInfo result; | |
| 128 | 1 | pendingLoadInfo = null; |
| 129 | 1 | if (application == null) { |
| 130 | 2 | errorMessage = new Message("No application to load.").toString(); |
| 131 | 1 | throw new IllegalStateException(errorMessage); |
| 132 | } | |
| 133 | // Fetch STDIN/STDOUT filenames from Application's symboltable. | |
| 134 | 1 | appDefinitions = getApplicationDefinitions(); |
| 135 | 3 | if (appDefinitions[DEF_STDOUT_POS] != null) { |
| 136 | 3 | currentStdOutFile = appDefinitions[DEF_STDOUT_POS]; |
| 137 | } | |
| 138 | try { | |
| 139 | 3 | insertStdinToApplication(appDefinitions[DEF_STDIN_POS]); |
| 140 | } catch (IOException fileProblem) { | |
| 141 | 3 | errorMessage = new Message("STDIN data file " + |
| 142 | "unreadable: {0}", | |
| 143 | fileProblem.getMessage()).toString(); | |
| 144 | // The exception will be thrown when everything else is | |
| 145 | // finished; it can be ignored since it will be thrown later | |
| 146 | // again *if* someone tries to read the stdin data. | |
| 147 | 2 | pendingException = true; |
| 148 | } catch (ParseException dataInvalid) { | |
| 149 | 3 | errorMessage = new Message("STDIN data file contains " + |
| 150 | "invalid data: {0}", | |
| 151 | dataInvalid.getMessage()).toString(); | |
| 152 | // The exception will be thrown when everything else is | |
| 153 | // finished; it can be ignored since it will be thrown later | |
| 154 | // again *if* someone tries to read the stdin data. | |
| 155 | 2 | pendingException = true; |
| 156 | } | |
| 157 | 1 | Loader loader = new Loader(processor); |
| 158 | 1 | loader.setApplicationToLoad(application); |
| 159 | 1 | result = loader.loadApplication(); |
| 160 | 1 | if (pendingException) { |
| 161 | 1 | pendingLoadInfo = result; |
| 162 | 1 | throw new TTK91NoStdInData(errorMessage); |
| 163 | } | |
| 164 | 1 | return result; |
| 165 | } | |
| 166 | ||
| 167 | /** | |
| 168 | * Sometimes load() throws an exception when the situation is not | |
| 169 | * really requiring an error message. This causes the caller to | |
| 170 | * not recieve their LoadInfo. To avoid causing unnecessary | |
| 171 | * suffering, the LoadInfo can be fetched by calling this | |
| 172 | * method. The LoadInfo will be null if the loading was really | |
| 173 | * not successful or if there has been no load. | |
| 174 | */ | |
| 175 | public LoadInfo getPendingLoadInfo() { | |
| 176 | 1 | return pendingLoadInfo; |
| 177 | } | |
| 178 | ||
| 179 | /** | |
| 180 | * This method does the actual inserting STDIN datat to an application. | |
| 181 | * | |
| 182 | * @param applicationStdin The application's suggestion for a file | |
| 183 | * to read the stdin data from. If null, the data is read from the | |
| 184 | * set default stdin file. | |
| 185 | * @throws IOException If the current STDIN file cannot be opened. | |
| 186 | * @throws ParseException If the current STDIN file contains | |
| 187 | * invalid input. | |
| 188 | */ | |
| 189 | private void insertStdinToApplication(File applicationStdin) | |
| 190 | throws ParseException, IOException { | |
| 191 | String contents, errorMessage, preparedStdinData; | |
| 192 | File stdinFile = defaultStdInFile; | |
| 193 | File[] appDefinitions; | |
| 194 | Logger logger; | |
| 195 | ||
| 196 | 1 | if (applicationStdin != null) { |
| 197 | stdinFile = applicationStdin; | |
| 198 | } | |
| 199 | // If the stdin file is not set by default (in Control's constructor) | |
| 200 | // and not by the application, we assume it should not be used. | |
| 201 | 1 | if (stdinFile == null) { |
| 202 | logger = Logger.getLogger(getClass().getPackage().getName()); | |
| 203 | logger.info(new Message("STDIN files were null, data not inserted " + | |
| 204 | "to the application.").toString()); | |
| 205 | return; | |
| 206 | } | |
| 207 | 2 | contents = fileHandler.loadStdIn(stdinFile).toString(); |
| 208 | // We use a brutal way of testing the input in order to get | |
| 209 | // more detailed information on *where* the input fails. | |
| 210 | // Otherwise, should use Application's static boolean checkInput(). | |
| 211 | try { | |
| 212 | 1 | application.setStdIn(contents); |
| 213 | } catch (IllegalArgumentException syntaxErrorInStdinData) { | |
| 214 | 4 | throw new ParseException(syntaxErrorInStdinData.getMessage(), -1); |
| 215 | } | |
| 216 | } | |
| 217 | ||
| 218 | /** | |
| 219 | * This helper method gets the definitions in the currently loaded | |
| 220 | * application. It assumes the definitions are file paths. | |
| 221 | * | |
| 222 | * @return A File-array containing STDIN, STDOUT and HOME definitions | |
| 223 | * or nulls if the values have not been defined in the application. | |
| 224 | * The positions of the values in the array are determined by the | |
| 225 | * constants DEF_STDIN_POS, DEF_STDOUT_POS and DEF_HOME_POS | |
| 226 | * respectively. | |
| 227 | */ | |
| 228 | public File[] getApplicationDefinitions() { | |
| 229 | SymbolTable symbols; | |
| 230 | String[] definitions; | |
| 231 | 2 | File[] result = new File[3]; |
| 232 | Logger logger; | |
| 233 | ||
| 234 | 1 | symbols = application.getSymbolTable(); |
| 235 | 1 | definitions = symbols.getAllDefinitions(); |
| 236 | 5 | for (int i = 0; i < definitions.length; i++) { |
| 237 | 2 | if (definitions[i].equalsIgnoreCase("STDIN")) { |
| 238 | 4 | result[DEF_STDIN_POS] = |
| 239 | new File(symbols.getDefinition(definitions[i])); | |
| 240 | 2 | } else if (definitions[i].equalsIgnoreCase("STDOUT")) { |
| 241 | 4 | result[DEF_STDOUT_POS] = |
| 242 | new File(symbols.getDefinition(definitions[i])); | |
| 243 | 2 | } else if (definitions[i].equalsIgnoreCase("HOME")) { |
| 244 | 4 | result[DEF_HOME_POS] = |
| 245 | new File(symbols.getDefinition(definitions[i])); | |
| 246 | } else { | |
| 247 | logger = Logger.getLogger(getClass().getPackage().getName()); | |
| 248 | logger.warning(new Message("Application contained an odd " + | |
| 249 | "definition key '{0}'.", | |
| 250 | definitions[i]).toString()); | |
| 251 | } | |
| 252 | } | |
| 253 | 1 | return result; |
| 254 | } | |
| 255 | ||
| 256 | /** | |
| 257 | * Runs a given app for <steps> steps at a time and updates its state. | |
| 258 | * Problem: the CPU and Memory states might need to somehow be attached | |
| 259 | * to this thing, unless there is some sort of a 'resume running current' | |
| 260 | * method added. Defined by TTK91Core. | |
| 261 | * | |
| 262 | * @param app Application to be run. | |
| 263 | * @param steps Number of steps the application will be run. | |
| 264 | * @throws TTK91NoStdInData If the STDIN data file is unreadable or | |
| 265 | * syntactically incorrect even if the file is not really needed. | |
| 266 | * @throws TTK91ExecutionOverrun if program overruns the limit set in steps | |
| 267 | */ | |
| 268 | public void run(TTK91Application app, int steps) | |
| 269 | throws TTK91Exception, TTK91RuntimeException { | |
| 270 | String errorMessage = ""; | |
| 271 | RunInfo info = null; | |
| 272 | int counter; | |
| 273 | 4 | boolean pendingException = false, gotException = false; |
| 274 | try { | |
| 275 | 1 | this.application = (Application) app; |
| 276 | } catch (ClassCastException unsupportedTypeOfApplication) { | |
| 277 | 2 | errorMessage = new Message("Trying to run an unsupported " + |
| 278 | "type of application. (The " + | |
| 279 | "application must be created " + | |
| 280 | "using the same program.)").toString(); | |
| 281 | 1 | throw new IllegalArgumentException(errorMessage); |
| 282 | } | |
| 283 | try { | |
| 284 | 1 | load(); |
| 285 | } catch (TTK91NoStdInData stdinDataWillNotBeAvailable) { | |
| 286 | // Ignore it; we'll just see how it goes to run it. | |
| 287 | // (On the other hand, TTK91AddressOutOfBounds thrown by | |
| 288 | // load() will be thrown upwards from here.) | |
| 289 | } | |
| 290 | // Run the program a line at a time until the counter becomes | |
| 291 | // equal to the step count. (The counter is incremented before | |
| 292 | // comparing to the steps variable.) If the steps was 0, run | |
| 293 | // infinitely. | |
| 294 | 2 | if (steps < 0) { |
| 295 | return; | |
| 296 | } | |
| 297 | 2 | counter = 1; |
| 298 | // We then always run at least one step; 0 steps would mean "run | |
| 299 | // infinitely". | |
| 300 | do { | |
| 301 | try { | |
| 302 | 1 | info = runLine(); // See runLine(). It does various things. |
| 303 | } catch (TTK91FailedWrite err) { | |
| 304 | // If the write fails, it fails after all else, so we just | |
| 305 | // inform of it happening afterwards. | |
| 306 | 1 | errorMessage = err.getMessage(); |
| 307 | 2 | pendingException = true; |
| 308 | 2 | gotException = true; |
| 309 | } | |
| 310 | } | |
| 311 | 6 | while ((info != null || gotException) && |
| 312 | (steps == 0 || ++counter <= steps)); | |
| 313 | ||
| 314 | // Added by Kohahdus project 2006-11-23 | |
| 315 | 3 | if ((steps != 0) && (counter > steps)) { |
| 316 | 7 | throw new TTK91ExecutionOverrun("Program execution killed after " |
| 317 | + steps + " instructions. Likely an " | |
| 318 | + "infinite loop"); | |
| 319 | } | |
| 320 | ||
| 321 | ||
| 322 | 1 | if (pendingException) { |
| 323 | 1 | throw new TTK91FailedWrite(errorMessage); |
| 324 | } | |
| 325 | } | |
| 326 | ||
| 327 | /** | |
| 328 | * Returns a reference to the RandomAccessMemory object which is | |
| 329 | * attached to the current Processor object. Defined by TTK91Core. | |
| 330 | * | |
| 331 | * @return The reference to the RandomAccessMemory object. | |
| 332 | */ | |
| 333 | public TTK91Memory getMemory() { | |
| 334 | 2 | return processor.getMemory(); |
| 335 | } | |
| 336 | ||
| 337 | public TTK91Memory getPhysicalMemory() { | |
| 338 | 2 | return processor.getPhysicalMemory(); |
| 339 | } | |
| 340 | ||
| 341 | /** | |
| 342 | * Returns a reference to the Processor object. Defined by TTK91Core. | |
| 343 | * | |
| 344 | * @return The reference to the Processor object. | |
| 345 | */ | |
| 346 | public TTK91Cpu getCpu() { | |
| 347 | 1 | return processor; |
| 348 | } | |
| 349 | ||
| 350 | /** | |
| 351 | * Returns a string that contains the binary presentation of the | |
| 352 | * application. Defined by TTK91Core. | |
| 353 | * | |
| 354 | * @param app The application that is to be transformed into | |
| 355 | * binary. | |
| 356 | * @return Returns the application in the form a string, which | |
| 357 | * contains the binary code. | |
| 358 | */ | |
| 359 | public String getBinary(TTK91Application app) { | |
| 360 | String errorMessage; | |
| 361 | try { | |
| 362 | 3 | return new Binary((Application) app).toString(); |
| 363 | } catch (ClassCastException invalidApplicationFormat) { | |
| 364 | 2 | errorMessage = new Message("Cannot form a binary out of an " + |
| 365 | "unsupported type of an application. " + | |
| 366 | "(The application must be created " + | |
| 367 | "using the same program.)").toString(); | |
| 368 | 1 | throw new IllegalArgumentException(errorMessage); |
| 369 | } | |
| 370 | } | |
| 371 | ||
| 372 | ||
| 373 | /** | |
| 374 | * Returns a TTK91Application object of the given string, which | |
| 375 | * should contain proper binary code. If it doesn't, however, a | |
| 376 | * ParseException is thrown. Defined by TTK91Core. | |
| 377 | * | |
| 378 | * @param binary The binary to be compiled. | |
| 379 | * @return Returns a TTK91Application object of the binary string. | |
| 380 | */ | |
| 381 | public TTK91Application loadBinary(String binary) | |
| 382 | throws ParseException { | |
| 383 | // (Binary's methods may throw the ParseException.) | |
| 384 | 3 | return new Binary(binary).toApplication(); |
| 385 | } | |
| 386 | ||
| 387 | /** | |
| 388 | * Changes the size of memory measured in words. | |
| 389 | * | |
| 390 | * @param powerOfTwo Implies the total size of memory which is | |
| 391 | * 2^powerOfTwo. Legitimate values are | |
| 392 | * 9,...,16. | |
| 393 | * @throws IllegalArgumentException if powerOfTwo is not between | |
| 394 | * 9 and 16. | |
| 395 | */ | |
| 396 | public void changeMemorySize(int powerOfTwo) { | |
| 397 | String errorMessage; | |
| 398 | 8 | if (powerOfTwo < 9 || powerOfTwo > 16) { |
| 399 | // Translate the error message and store in the same variable. | |
| 400 | 6 | errorMessage = new Message("Memory size must be between 2^9 and " + |
| 401 | "2^16, a change to 2^{0} failed.", | |
| 402 | "" + powerOfTwo).toString(); | |
| 403 | 1 | throw new IllegalArgumentException(errorMessage); |
| 404 | } | |
| 405 | 5 | processor = new Processor((int) Math.pow(2, powerOfTwo)); |
| 406 | } | |
| 407 | ||
| 408 | /** | |
| 409 | * Erases the memory ie. fills it with zeros. | |
| 410 | */ | |
| 411 | public void eraseMemory() { | |
| 412 | 1 | processor.eraseMemory(); |
| 413 | } | |
| 414 | ||
| 415 | /** | |
| 416 | * This compiles one next line of the t91 program that has been | |
| 417 | * opened recently and hasn't yet been compiled to binary code. | |
| 418 | * | |
| 419 | * @return Returns CompileInfo object of the last line compiled. | |
| 420 | */ | |
| 421 | public CompileInfo compileLine() | |
| 422 | throws TTK91CompileException { | |
| 423 | 1 | CompileInfo info = compiler.compileLine(); |
| 424 | // If the compilation is finished, let's store the application. | |
| 425 | 1 | if (info == null) { |
| 426 | 2 | application = compiler.getApplication(); |
| 427 | } | |
| 428 | 1 | return info; |
| 429 | } | |
| 430 | ||
| 431 | /** | |
| 432 | * This runs one next line of the program that is currently | |
| 433 | * loaded into the TTK91's memory. | |
| 434 | * | |
| 435 | * @return Returns RunInfo object of the last line executed. | |
| 436 | */ | |
| 437 | public RunInfo runLine() | |
| 438 | throws TTK91RuntimeException { | |
| 439 | RunInfo info; | |
| 440 | int data; | |
| 441 | int[] outData; | |
| 442 | String errorMessage; | |
| 443 | ||
| 444 | 1 | if (application == null) { |
| 445 | 2 | errorMessage = new Message("There is no application available " + |
| 446 | "to run from!").toString(); | |
| 447 | 1 | throw new IllegalStateException(errorMessage); |
| 448 | } | |
| 449 | try { | |
| 450 | 1 | info = processor.runLine(); |
| 451 | 1 | if (info != null) { |
| 452 | // OutData becomes an array where slot 0 is the device | |
| 453 | // number and slot 1 the value written there. | |
| 454 | 1 | outData = info.whatOUT(); |
| 455 | 3 | if (info.isExternalOp() && outData != null) { |
| 456 | 3 | if (outData[0] == Processor.CRT) { |
| 457 | 3 | application.writeToCrt(outData[1]); |
| 458 | } | |
| 459 | 5 | if (outData[0] == Processor.STDOUT) { |
| 460 | 3 | application.writeToStdOut(outData[1]); |
| 461 | 7 | writeToStdoutFile("" + outData[1]); |
| 462 | } | |
| 463 | } | |
| 464 | } | |
| 465 | 1 | return info; |
| 466 | } catch (TTK91NoKbdData needMoreData) { | |
| 467 | // Application may throw a new TTK91NoKbdData exception, | |
| 468 | // in which case it will just be thrown upwards. | |
| 469 | 1 | data = application.readNextFromKbd(); |
| 470 | 1 | processor.keyboardInput(data); |
| 471 | 2 | return runLine(); // Try again with the CPU buffer filled. |
| 472 | } catch (TTK91NoStdInData needMoreData) { | |
| 473 | // Application may throw a new TTK91NoStdinData exception, | |
| 474 | // in which case it will just be thrown upwards. | |
| 475 | 1 | data = application.readNextFromStdIn(); |
| 476 | 1 | processor.stdinInput(data); |
| 477 | 2 | return runLine(); // Try again with the CPU buffer filled. |
| 478 | } | |
| 479 | } | |
| 480 | ||
| 481 | /** | |
| 482 | * This method appends the given data to the current stdout file. | |
| 483 | * | |
| 484 | * @param data The data to append to the stdout file. | |
| 485 | * @throws TTK91FailedWrite If there was an I/O error. | |
| 486 | */ | |
| 487 | void writeToStdoutFile(String data) | |
| 488 | throws TTK91FailedWrite { | |
| 489 | Logger logger = Logger.getLogger(getClass().getPackage().getName()); | |
| 490 | // The default stdout file is set at the constructor and may | |
| 491 | // be null. If the application does not set it either, we | |
| 492 | // interpret it as the stdout file being disabled. | |
| 493 | 1 | if (currentStdOutFile == null) { |
| 494 | logger.info(new Message("No STDOUT file set, not writing to " + | |
| 495 | "it.").toString()); | |
| 496 | return; | |
| 497 | } | |
| 498 | try { | |
| 499 | 1 | fileHandler.appendDataToStdOut(data, currentStdOutFile); |
| 500 | } catch (IOException writeFailed) { | |
| 501 | 2 | throw new TTK91FailedWrite(writeFailed.getMessage()); |
| 502 | } | |
| 503 | } | |
| 504 | ||
| 505 | /** | |
| 506 | * This is called when user the has changed language to another one by | |
| 507 | * choosing it from a dialog after selecting Set language from the | |
| 508 | * GUI menu, and has chosen a special file to load. | |
| 509 | * | |
| 510 | * @param languageFile The language file to load into a | |
| 511 | * ResourceBundle. | |
| 512 | * @return The ResourceBundle represented by the file. | |
| 513 | * @throws ResourceLoadFailedException If opening the resourcebundle | |
| 514 | * from the file failed. | |
| 515 | */ | |
| 516 | public ResourceBundle loadLanguageFile(File languageFile) | |
| 517 | throws ResourceLoadFailedException { | |
| 518 | 2 | return fileHandler.loadResourceBundle(languageFile); |
| 519 | } | |
| 520 | ||
| 521 | /** | |
| 522 | * This is called when the user has changed the file from which the stdin | |
| 523 | * operations will be read. | |
| 524 | * | |
| 525 | * @param stdinFile The stdin file. | |
| 526 | * @throws IOException If an I/O error occurs. | |
| 527 | * @throws ParseException *After* everything else is done, if the | |
| 528 | * contents of the file are invalid. This exception can be ignored | |
| 529 | * until it leads into TTK91NoStdInData when an application tries | |
| 530 | * to read from STDIN. | |
| 531 | */ | |
| 532 | public void setDefaultStdIn(File stdinFile) | |
| 533 | throws IOException, | |
| 534 | ParseException { | |
| 535 | String contents; | |
| 536 | 1 | defaultStdInFile = stdinFile; |
| 537 | 2 | contents = fileHandler.loadStdIn(stdinFile).toString(); |
| 538 | 2 | if (!Application.checkInput(contents)) { |
| 539 | 5 | throw new ParseException(new Message("StdIn file contents are " + |
| 540 | "invalid; the file should " + | |
| 541 | "contain only integers and " + | |
| 542 | "separators.").toString(), | |
| 543 | -1); | |
| 544 | } | |
| 545 | } | |
| 546 | ||
| 547 | /** | |
| 548 | * This is called when the user has changed the file into which the stdout | |
| 549 | * operations will be written. | |
| 550 | * | |
| 551 | * @param stdoutFile The stdout file. | |
| 552 | */ | |
| 553 | public void setDefaultStdOut(File stdoutFile) | |
| 554 | throws IOException { | |
| 555 | String errorMessage; | |
| 556 | 1 | defaultStdOutFile = stdoutFile; |
| 557 | // Check whether we can really write to the file without writing | |
| 558 | // to it. (We just append, really.) TestAccess throws exceptions. | |
| 559 | 3 | fileHandler.testAccess(stdoutFile, FileHandler.APPEND_ACCESS); |
| 560 | } | |
| 561 | ||
| 562 | /** | |
| 563 | * This is called when a source file is opened from GUI. | |
| 564 | * This method passes the file to FileHandler and prepares to | |
| 565 | * compile the contents. | |
| 566 | * | |
| 567 | * @param openedFile The file. | |
| 568 | * @return The source string. | |
| 569 | */ | |
| 570 | public String openSource(File openedFile) | |
| 571 | throws IOException { | |
| 572 | 2 | String sourceString = fileHandler.loadSource(openedFile).getSource(); |
| 573 | 1 | compiler.compile(sourceString); // Prepare the compiler. |
| 574 | 1 | sourceFile = openedFile; |
| 575 | 1 | application = null; |
| 576 | 1 | currentStdOutFile = defaultStdOutFile; |
| 577 | 1 | return sourceString; |
| 578 | } | |
| 579 | ||
| 580 | /** | |
| 581 | * This method makes it possible to re-open the same source file, | |
| 582 | * only modified. The opened file stays the same, the new string is | |
| 583 | * passed to the compiler and the modifications are saved in | |
| 584 | * the source file. | |
| 585 | * | |
| 586 | * @param modifiedSource The modified source as a string array, one | |
| 587 | * line per cell. The format is optimized for GUI/GUIBrain use. The | |
| 588 | * source must not be null. | |
| 589 | * @return The source string. | |
| 590 | * @throws IOException Just before the last return if the saving of | |
| 591 | * the modified source failed. | |
| 592 | * @throws IllegalStateException If there is no source file set. | |
| 593 | * The method openSource() must be called before this method. | |
| 594 | */ | |
| 595 | public String modifySource(String[] modifiedSource) | |
| 596 | throws IOException { | |
| 597 | 1 | StringBuffer result = new StringBuffer(); |
| 598 | String sourceString; | |
| 599 | File targetFile = sourceFile; | |
| 600 | 1 | if (modifiedSource == null) { |
| 601 | 3 | throw new IllegalArgumentException(new Message("Modified source " + |
| 602 | "was null.").toString()); | |
| 603 | } | |
| 604 | 1 | if (sourceFile == null) { |
| 605 | 3 | throw new IllegalStateException(new Message("No source file set, " + |
| 606 | "use openSource " + | |
| 607 | "first.").toString()); | |
| 608 | } | |
| 609 | 5 | for (int i = 0; i < modifiedSource.length; i++) { |
| 610 | 5 | result.append(modifiedSource[i] + "\n"); |
| 611 | } | |
| 612 | 1 | sourceString = result.toString(); |
| 613 | 1 | compiler.compile(sourceString); // Prepare the compiler. |
| 614 | 1 | application = null; |
| 615 | 1 | currentStdOutFile = defaultStdOutFile; |
| 616 | 2 | fileHandler.saveSource(new Source(sourceString), targetFile); |
| 617 | 1 | return sourceString; |
| 618 | } | |
| 619 | ||
| 620 | /** | |
| 621 | * This method saves the opened source file to a binary of the | |
| 622 | * same filename as the previous source file was loaded from, | |
| 623 | * with the extension changed (probably from .k91) to .b91. | |
| 624 | * If you wish to select the filename yourself, use saveBinary(File). | |
| 625 | * | |
| 626 | * @throws IllegalStateException If the method is called before | |
| 627 | * a source file has been opened or if there is no application | |
| 628 | * to save. | |
| 629 | */ | |
| 630 | public void saveBinary() | |
| 631 | throws IOException { | |
| 632 | String errorMessage; | |
| 633 | 1 | if (sourceFile == null) { |
| 634 | 2 | errorMessage = new Message("Cannot deduce the file to " + |
| 635 | "store the binary into; no source " + | |
| 636 | "file has been loaded.").toString(); | |
| 637 | 1 | throw new IllegalStateException(errorMessage); |
| 638 | } | |
| 639 | 2 | saveBinary(fileHandler.changeExtension(sourceFile, "b91")); |
| 640 | } | |
| 641 | ||
| 642 | /** | |
| 643 | * This method saves the current application to a given file. It | |
| 644 | * throws any IOExceptions upwards. Often saveBinary() with no | |
| 645 | * parameters is sufficient; it guesses the file to save to from | |
| 646 | * the source filename. | |
| 647 | * | |
| 648 | * @param specialFile A filename to save the binary to. | |
| 649 | * @throws IllegalStateException If there is no application to save. | |
| 650 | */ | |
| 651 | public void saveBinary(File specialFile) | |
| 652 | throws IOException { | |
| 653 | String errorMessage; | |
| 654 | 1 | if (application == null) { |
| 655 | 2 | errorMessage = new Message("Cannot save binary to file; no " + |
| 656 | "application has been compiled or " + | |
| 657 | "loaded.").toString(); | |
| 658 | 1 | throw new IllegalStateException(errorMessage); |
| 659 | } | |
| 660 | 2 | fileHandler.saveBinary(new Binary(application), specialFile); |
| 661 | } | |
| 662 | ||
| 663 | /** | |
| 664 | * This is called when a binary file is opened from GUI. | |
| 665 | * This method passes the file to FileHandler, has the contents | |
| 666 | * interpreted by Binary and prepares to load the result Application. | |
| 667 | * | |
| 668 | * @param openedFile The file. | |
| 669 | */ | |
| 670 | public void openBinary(File openedFile) | |
| 671 | throws IOException, ParseException { | |
| 672 | 1 | sourceFile = null; |
| 673 | 3 | application = fileHandler.loadBinary(openedFile).toApplication(); |
| 674 | } | |
| 675 | ||
| 676 | /** | |
| 677 | * This is called when GUIBrain wants to load the settings. | |
| 678 | * It uses FileHandler for reading them. | |
| 679 | * | |
| 680 | * @return A string representation of the Settings object stored in | |
| 681 | * the file. | |
| 682 | */ | |
| 683 | public String loadSettingsFileContents(File settingsFile) | |
| 684 | throws IOException { | |
| 685 | 3 | return fileHandler.loadSettings(settingsFile).toString(); |
| 686 | } | |
| 687 | ||
| 688 | /** | |
| 689 | * This is called when GUIBrain wants to load the settings from | |
| 690 | * a stream. It uses FileHandler for reading them. | |
| 691 | * | |
| 692 | * @return A string representation of the Settings object stored in | |
| 693 | * the input stream, or null if the stream was null. | |
| 694 | */ | |
| 695 | public String loadSettingsStreamContents(InputStream settingsStream) | |
| 696 | throws IOException { | |
| 697 | 1 | if (settingsStream == null) { |
| 698 | 1 | return null; |
| 699 | } else { | |
| 700 | 3 | return fileHandler.loadSettings(settingsStream).toString(); |
| 701 | } | |
| 702 | } | |
| 703 | ||
| 704 | /** | |
| 705 | * This method stores the settings string to the given file. | |
| 706 | * It passes the parameters to FileHandler. | |
| 707 | * | |
| 708 | * @param currentSettings A string representation of the current | |
| 709 | * settings. | |
| 710 | * @param settingsFile The file to store the settings to. | |
| 711 | * @throws IOException if FileHandler throws one to indicate an I/O | |
| 712 | * error. | |
| 713 | */ | |
| 714 | public void saveSettings(String currentSettings, File settingsFile) | |
| 715 | throws IOException { | |
| 716 | 1 | fileHandler.saveSettings(currentSettings, |
| 717 | settingsFile); | |
| 718 | } | |
| 719 | ||
| 720 | /** | |
| 721 | * GUIBrain calls this when it has recieved the TTK91NoKbdData | |
| 722 | * exception. The input is passed on to the processor. Note that | |
| 723 | * primarily input is searched for in the Application instance. | |
| 724 | * | |
| 725 | * @param inputValue The input to pass on. | |
| 726 | */ | |
| 727 | public void keyboardInput(int inputValue) { | |
| 728 | 1 | processor.keyboardInput(inputValue); |
| 729 | } | |
| 730 | ||
| 731 | /** | |
| 732 | * RunLine() calls this, when the processor wants to write a | |
| 733 | * value to CRT. | |
| 734 | * | |
| 735 | * @param inputValue The input to CRT. | |
| 736 | */ | |
| 737 | private void writeToCRT(int inputValue) { | |
| 738 | 1 | application.writeToCrt(inputValue); |
| 739 | } | |
| 740 | ||
| 741 | /** | |
| 742 | * RunLine() calls this, when the processor wants to write a | |
| 743 | * value to StdOut. | |
| 744 | * | |
| 745 | * @param inputValue The inpuit to StdOut. | |
| 746 | */ | |
| 747 | private void writeToStdOut(int inputValue) { | |
| 748 | 1 | application.writeToStdOut(inputValue); |
| 749 | } | |
| 750 | ||
| 751 | } | |
Mutations | ||
| 61 |
Removed assignment to member variable pendingLoadInfo : SURVIVED |
|
| 69 |
negated conditional : SURVIVED |
|
| 72 |
negated conditional : SURVIVED |
|
| 75 |
Removed assignment to member variable fileHandler : KILLED -> fi.helsinki.cs.titokone.ControlTest.testOpenSource(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/FileHandler::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testOpenSource(fi.helsinki.cs.titokone.ControlTest) |
|
| 76 |
removed call to fi/helsinki/cs/titokone/Compiler::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Removed assignment to member variable compiler : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 78 |
removed call to fi/helsinki/cs/titokone/Control::changeMemorySize : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 15 with 16 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testConstructorAndChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) Replaced constant value of 15 with 16 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testConstructorAndChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) |
|
| 79 |
Removed assignment to member variable defaultStdInFile : SURVIVED |
|
| 80 |
Removed assignment to member variable defaultStdOutFile : SURVIVED |
|
| 81 |
Removed assignment to member variable currentStdOutFile : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 97 |
removed call to fi/helsinki/cs/ttk91/TTK91CompileSource::getSource : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Compiler::compile : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 100 |
removed call to fi/helsinki/cs/titokone/Control::compileLine : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 103 |
Removed assignment to member variable application : SURVIVED removed call to fi/helsinki/cs/titokone/Compiler::getApplication : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 104 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::compile to ( if (x != null) null else throw new RuntimeException ) : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 125 |
Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 128 |
Removed assignment to member variable pendingLoadInfo : SURVIVED |
|
| 129 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 130 |
removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE |
|
| 131 |
removed call to java/lang/IllegalStateException::<init> : NO_COVERAGE |
|
| 134 |
removed call to fi/helsinki/cs/titokone/Control::getApplicationDefinitions : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 135 |
Substituted 1 with 0 : SURVIVED negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 1 with 0 : SURVIVED |
|
| 136 |
Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Removed assignment to member variable currentStdOutFile : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 139 |
removed call to fi/helsinki/cs/titokone/Control::insertStdinToApplication : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 141 |
removed call to fi/helsinki/cs/titokone/Message::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Message::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) removed call to java/io/IOException::getMessage : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 147 |
Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 149 |
removed call to fi/helsinki/cs/titokone/Message::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Message::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) removed call to java/text/ParseException::getMessage : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 155 |
Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 157 |
removed call to fi/helsinki/cs/titokone/Loader::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 158 |
removed call to fi/helsinki/cs/titokone/Loader::setApplicationToLoad : SURVIVED |
|
| 159 |
removed call to fi/helsinki/cs/titokone/Loader::loadApplication : SURVIVED |
|
| 160 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 161 |
Removed assignment to member variable pendingLoadInfo : SURVIVED |
|
| 162 |
removed call to fi/helsinki/cs/ttk91/TTK91NoStdInData::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 164 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::load to ( if (x != null) null else throw new RuntimeException ) : SURVIVED |
|
| 176 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::getPendingLoadInfo to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |
|
| 196 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 201 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 207 |
removed call to fi/helsinki/cs/titokone/FileHandler::loadStdIn : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) removed call to java/lang/StringBuffer::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 212 |
removed call to fi/helsinki/cs/titokone/Application::setStdIn : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 214 |
removed call to java/text/ParseException::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted -1 with 0 : SURVIVED Substituted -1 with 1 : SURVIVED removed call to java/lang/IllegalArgumentException::getMessage : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 231 |
Substituted 3 with 4 : SURVIVED Substituted 3 with 4 : SURVIVED |
|
| 234 |
removed call to fi/helsinki/cs/titokone/Application::getSymbolTable : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 235 |
removed call to fi/helsinki/cs/titokone/SymbolTable::getAllDefinitions : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 236 |
Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) changed conditional boundary : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Changed increment from 1 to -1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 237 |
removed call to java/lang/String::equalsIgnoreCase : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 238 |
removed call to java/io/File::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 0 with 1 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/SymbolTable::getDefinition : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 240 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) removed call to java/lang/String::equalsIgnoreCase : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 241 |
removed call to fi/helsinki/cs/titokone/SymbolTable::getDefinition : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) removed call to java/io/File::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) Substituted 1 with 0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 243 |
removed call to java/lang/String::equalsIgnoreCase : NO_COVERAGE negated conditional : NO_COVERAGE |
|
| 244 |
Substituted 2 with 3 : NO_COVERAGE removed call to java/io/File::<init> : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE removed call to fi/helsinki/cs/titokone/SymbolTable::getDefinition : NO_COVERAGE |
|
| 253 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::getApplicationDefinitions to ( if (x != null) null else throw new RuntimeException ) : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 273 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 275 |
Removed assignment to member variable application : NO_COVERAGE |
|
| 277 |
removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE |
|
| 281 |
removed call to java/lang/IllegalArgumentException::<init> : NO_COVERAGE |
|
| 284 |
removed call to fi/helsinki/cs/titokone/Control::load : NO_COVERAGE |
|
| 294 |
negated conditional : NO_COVERAGE changed conditional boundary : NO_COVERAGE |
|
| 297 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 302 |
removed call to fi/helsinki/cs/titokone/Control::runLine : NO_COVERAGE |
|
| 306 |
removed call to fi/helsinki/cs/ttk91/TTK91FailedWrite::getMessage : NO_COVERAGE |
|
| 307 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 308 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 311 |
negated conditional : NO_COVERAGE changed conditional boundary : NO_COVERAGE negated conditional : NO_COVERAGE negated conditional : NO_COVERAGE negated conditional : NO_COVERAGE Changed increment from 1 to -1 : NO_COVERAGE |
|
| 315 |
changed conditional boundary : NO_COVERAGE negated conditional : NO_COVERAGE negated conditional : NO_COVERAGE |
|
| 316 |
removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to java/lang/StringBuilder::toString : NO_COVERAGE removed call to fi/helsinki/cs/ttk91/TTK91ExecutionOverrun::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE |
|
| 322 |
negated conditional : NO_COVERAGE |
|
| 323 |
removed call to fi/helsinki/cs/ttk91/TTK91FailedWrite::<init> : NO_COVERAGE |
|
| 334 |
removed call to fi/helsinki/cs/titokone/Processor::getMemory : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) mutated return of Object value for fi/helsinki/cs/titokone/Control::getMemory to ( if (x != null) null else throw new RuntimeException ) : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) |
|
| 338 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::getPhysicalMemory to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Processor::getPhysicalMemory : NO_COVERAGE |
|
| 347 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::getCpu to ( if (x != null) null else throw new RuntimeException ) : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 362 |
removed call to fi/helsinki/cs/titokone/Binary::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetBinary(fi.helsinki.cs.titokone.ControlTest) mutated return of Object value for fi/helsinki/cs/titokone/Control::getBinary to ( if (x != null) null else throw new RuntimeException ) : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetBinary(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Binary::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetBinary(fi.helsinki.cs.titokone.ControlTest) |
|
| 364 |
removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE |
|
| 368 |
removed call to java/lang/IllegalArgumentException::<init> : NO_COVERAGE |
|
| 384 |
removed call to fi/helsinki/cs/titokone/Binary::toApplication : NO_COVERAGE mutated return of Object value for fi/helsinki/cs/titokone/Control::loadBinary to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Binary::<init> : NO_COVERAGE |
|
| 398 |
changed conditional boundary : SURVIVED negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 16 with 17 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) Substituted 9 with 10 : SURVIVED changed conditional boundary : SURVIVED Replaced constant value of 16 with 17 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) Replaced constant value of 9 with 10 : SURVIVED |
|
| 400 |
removed call to java/lang/StringBuilder::append : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) removed call to java/lang/StringBuilder::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) removed call to java/lang/StringBuilder::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Message::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Message::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) removed call to java/lang/StringBuilder::append : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) |
|
| 403 |
removed call to java/lang/IllegalArgumentException::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) |
|
| 405 |
Removed assignment to member variable processor : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) Replaced constant value of 2.0 with 1.0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) Substituted 2.0 with 1.0 : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Processor::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) removed call to java/lang/Math::pow : KILLED -> fi.helsinki.cs.titokone.ControlTest.testChangeMemorySize(fi.helsinki.cs.titokone.ControlTest) |
|
| 412 |
removed call to fi/helsinki/cs/titokone/Processor::eraseMemory : SURVIVED |
|
| 423 |
removed call to fi/helsinki/cs/titokone/Compiler::compileLine : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 425 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 426 |
Removed assignment to member variable application : SURVIVED removed call to fi/helsinki/cs/titokone/Compiler::getApplication : SURVIVED |
|
| 428 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::compileLine to ( if (x != null) null else throw new RuntimeException ) : KILLED -> fi.helsinki.cs.titokone.ControlTest.testGetApplicationDefinitions(fi.helsinki.cs.titokone.ControlTest) |
|
| 444 |
negated conditional : NO_COVERAGE |
|
| 445 |
removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE |
|
| 447 |
removed call to java/lang/IllegalStateException::<init> : NO_COVERAGE |
|
| 450 |
removed call to fi/helsinki/cs/titokone/Processor::runLine : NO_COVERAGE |
|
| 451 |
negated conditional : NO_COVERAGE |
|
| 454 |
removed call to fi/helsinki/cs/titokone/RunInfo::whatOUT : NO_COVERAGE |
|
| 455 |
negated conditional : NO_COVERAGE negated conditional : NO_COVERAGE removed call to fi/helsinki/cs/titokone/RunInfo::isExternalOp : NO_COVERAGE |
|
| 456 |
Substituted 0 with 1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE negated conditional : NO_COVERAGE |
|
| 457 |
removed call to fi/helsinki/cs/titokone/Application::writeToCrt : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE |
|
| 459 |
Replaced constant value of 7 with 8 : NO_COVERAGE Substituted 7 with 8 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE negated conditional : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE |
|
| 460 |
Substituted 1 with 0 : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Application::writeToStdOut : NO_COVERAGE |
|
| 461 |
Substituted 1 with 0 : NO_COVERAGE removed call to java/lang/StringBuilder::<init> : NO_COVERAGE Substituted 1 with 0 : NO_COVERAGE removed call to java/lang/StringBuilder::toString : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Control::writeToStdoutFile : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE |
|
| 465 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::runLine to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |
|
| 469 |
removed call to fi/helsinki/cs/titokone/Application::readNextFromKbd : NO_COVERAGE |
|
| 470 |
removed call to fi/helsinki/cs/titokone/Processor::keyboardInput : NO_COVERAGE |
|
| 471 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::runLine to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Control::runLine : NO_COVERAGE |
|
| 475 |
removed call to fi/helsinki/cs/titokone/Application::readNextFromStdIn : NO_COVERAGE |
|
| 476 |
removed call to fi/helsinki/cs/titokone/Processor::stdinInput : NO_COVERAGE |
|
| 477 |
removed call to fi/helsinki/cs/titokone/Control::runLine : NO_COVERAGE mutated return of Object value for fi/helsinki/cs/titokone/Control::runLine to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |
|
| 493 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 499 |
removed call to fi/helsinki/cs/titokone/FileHandler::appendDataToStdOut : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 501 |
removed call to java/io/IOException::getMessage : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/ttk91/TTK91FailedWrite::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testLoad(fi.helsinki.cs.titokone.ControlTest) |
|
| 518 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::loadLanguageFile to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE removed call to fi/helsinki/cs/titokone/FileHandler::loadResourceBundle : NO_COVERAGE |
|
| 536 |
Removed assignment to member variable defaultStdInFile : SURVIVED |
|
| 537 |
removed call to java/lang/StringBuffer::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSetDefaultStdin(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/FileHandler::loadStdIn : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSetDefaultStdin(fi.helsinki.cs.titokone.ControlTest) |
|
| 538 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSetDefaultStdin(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Application::checkInput : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSetDefaultStdin(fi.helsinki.cs.titokone.ControlTest) |
|
| 539 |
Substituted -1 with 1 : SURVIVED removed call to fi/helsinki/cs/titokone/Message::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSetDefaultStdin(fi.helsinki.cs.titokone.ControlTest) Substituted -1 with 0 : SURVIVED removed call to fi/helsinki/cs/titokone/Message::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSetDefaultStdin(fi.helsinki.cs.titokone.ControlTest) removed call to java/text/ParseException::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSetDefaultStdin(fi.helsinki.cs.titokone.ControlTest) |
|
| 556 |
Removed assignment to member variable defaultStdOutFile : NO_COVERAGE |
|
| 559 |
removed call to fi/helsinki/cs/titokone/FileHandler::testAccess : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE Substituted 2 with 3 : NO_COVERAGE |
|
| 572 |
removed call to fi/helsinki/cs/titokone/Source::getSource : KILLED -> fi.helsinki.cs.titokone.ControlTest.testOpenSource(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/FileHandler::loadSource : KILLED -> fi.helsinki.cs.titokone.ControlTest.testOpenSource(fi.helsinki.cs.titokone.ControlTest) |
|
| 573 |
removed call to fi/helsinki/cs/titokone/Compiler::compile : SURVIVED |
|
| 574 |
Removed assignment to member variable sourceFile : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryGuessFilename(fi.helsinki.cs.titokone.ControlTest) |
|
| 575 |
Removed assignment to member variable application : SURVIVED |
|
| 576 |
Removed assignment to member variable currentStdOutFile : SURVIVED |
|
| 577 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::openSource to ( if (x != null) null else throw new RuntimeException ) : KILLED -> fi.helsinki.cs.titokone.ControlTest.testOpenSource(fi.helsinki.cs.titokone.ControlTest) |
|
| 597 |
removed call to java/lang/StringBuffer::<init> : NO_COVERAGE |
|
| 600 |
negated conditional : NO_COVERAGE |
|
| 601 |
removed call to java/lang/IllegalArgumentException::<init> : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE |
|
| 604 |
negated conditional : NO_COVERAGE |
|
| 605 |
removed call to fi/helsinki/cs/titokone/Message::toString : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Message::<init> : NO_COVERAGE removed call to java/lang/IllegalStateException::<init> : NO_COVERAGE |
|
| 609 |
Substituted 0 with 1 : NO_COVERAGE negated conditional : NO_COVERAGE Changed increment from 1 to -1 : NO_COVERAGE Substituted 0 with 1 : NO_COVERAGE changed conditional boundary : NO_COVERAGE |
|
| 610 |
removed call to java/lang/StringBuilder::append : NO_COVERAGE removed call to java/lang/StringBuffer::append : NO_COVERAGE removed call to java/lang/StringBuilder::toString : NO_COVERAGE removed call to java/lang/StringBuilder::<init> : NO_COVERAGE removed call to java/lang/StringBuilder::append : NO_COVERAGE |
|
| 612 |
removed call to java/lang/StringBuffer::toString : NO_COVERAGE |
|
| 613 |
removed call to fi/helsinki/cs/titokone/Compiler::compile : NO_COVERAGE |
|
| 614 |
Removed assignment to member variable application : NO_COVERAGE |
|
| 615 |
Removed assignment to member variable currentStdOutFile : NO_COVERAGE |
|
| 616 |
removed call to fi/helsinki/cs/titokone/FileHandler::saveSource : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Source::<init> : NO_COVERAGE |
|
| 617 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::modifySource to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |
|
| 633 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryGuessFilename(fi.helsinki.cs.titokone.ControlTest) |
|
| 634 |
removed call to fi/helsinki/cs/titokone/Message::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryGuessFilename(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Message::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryGuessFilename(fi.helsinki.cs.titokone.ControlTest) |
|
| 637 |
removed call to java/lang/IllegalStateException::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryGuessFilename(fi.helsinki.cs.titokone.ControlTest) |
|
| 639 |
removed call to fi/helsinki/cs/titokone/FileHandler::changeExtension : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryGuessFilename(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Control::saveBinary : SURVIVED |
|
| 654 |
negated conditional : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryGuessFilename(fi.helsinki.cs.titokone.ControlTest) |
|
| 655 |
removed call to fi/helsinki/cs/titokone/Message::toString : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryFileName(fi.helsinki.cs.titokone.ControlTest) removed call to fi/helsinki/cs/titokone/Message::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryFileName(fi.helsinki.cs.titokone.ControlTest) |
|
| 658 |
removed call to java/lang/IllegalStateException::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryFileName(fi.helsinki.cs.titokone.ControlTest) |
|
| 660 |
removed call to fi/helsinki/cs/titokone/FileHandler::saveBinary : SURVIVED removed call to fi/helsinki/cs/titokone/Binary::<init> : KILLED -> fi.helsinki.cs.titokone.ControlTest.testSaveBinaryGuessFilename(fi.helsinki.cs.titokone.ControlTest) |
|
| 672 |
Removed assignment to member variable sourceFile : NO_COVERAGE |
|
| 673 |
Removed assignment to member variable application : NO_COVERAGE removed call to fi/helsinki/cs/titokone/Binary::toApplication : NO_COVERAGE removed call to fi/helsinki/cs/titokone/FileHandler::loadBinary : NO_COVERAGE |
|
| 685 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::loadSettingsFileContents to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE removed call to java/lang/StringBuffer::toString : NO_COVERAGE removed call to fi/helsinki/cs/titokone/FileHandler::loadSettings : NO_COVERAGE |
|
| 697 |
negated conditional : NO_COVERAGE |
|
| 698 |
mutated return of Object value for fi/helsinki/cs/titokone/Control::loadSettingsStreamContents to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |
|
| 700 |
removed call to fi/helsinki/cs/titokone/FileHandler::loadSettings : NO_COVERAGE removed call to java/lang/StringBuffer::toString : NO_COVERAGE mutated return of Object value for fi/helsinki/cs/titokone/Control::loadSettingsStreamContents to ( if (x != null) null else throw new RuntimeException ) : NO_COVERAGE |
|
| 716 |
removed call to fi/helsinki/cs/titokone/FileHandler::saveSettings : NO_COVERAGE |
|
| 728 |
removed call to fi/helsinki/cs/titokone/Processor::keyboardInput : NO_COVERAGE |
|
| 738 |
removed call to fi/helsinki/cs/titokone/Application::writeToCrt : NO_COVERAGE |
|
| 748 |
removed call to fi/helsinki/cs/titokone/Application::writeToStdOut : NO_COVERAGE |