mirror of
https://github.com/peterdell/wudsn-ide.git
synced 2024-06-03 06:29:35 +00:00
270 lines
8.2 KiB
Java
270 lines
8.2 KiB
Java
/**
|
|
* Copyright (C) 2009 - 2019 <a href="https://www.wudsn.com" target="_top">Peter Dell</a>
|
|
*
|
|
* This file is part of WUDSN IDE.
|
|
*
|
|
* WUDSN IDE is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* WUDSN IDE is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package com.wudsn.ide.asm.compiler.dasm;
|
|
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.util.List;
|
|
import java.util.StringTokenizer;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import org.eclipse.core.resources.IMarker;
|
|
import org.eclipse.core.runtime.CoreException;
|
|
|
|
import com.wudsn.ide.asm.compiler.CompilerProcessLogParser;
|
|
import com.wudsn.ide.asm.compiler.CompilerSymbol;
|
|
import com.wudsn.ide.base.common.FileUtility;
|
|
import com.wudsn.ide.base.common.StringUtility;
|
|
|
|
/**
|
|
* Process log parser for {@link DasmCompiler}.
|
|
*
|
|
* Sample error message:
|
|
*
|
|
* <pre>
|
|
* ------- FILE C:\Users\D025328\Documents\Eclipse\workspace.jac\com.wudsn.ide.ref\ASM\Atari2600\DASM\DASM-Error-Reference.asm LEVEL 1 PASS 1
|
|
* 1 0000 ????
|
|
* ------- FILE include/DASM-Reference-Source-Include.asm LEVEL 2 PASS 1
|
|
* 0 0000 ???? include "include/DASM-Reference-Source-Include.asm"
|
|
* 1 0000 ???? ; @com.wudsn.ide.asm.mainsourcefile=../DASM-Error-Reference.asm
|
|
* 2 0000 ????
|
|
* 3 0000 ???? ; Reference source include file for DASM
|
|
* 4 0000 ????
|
|
* include/DASM-Reference-Source-Include.asm (5): error: Unknown Mnemonic 'jmp'.
|
|
* 5 0000 ???? jmp unknownTest
|
|
* ------- FILE C:\Users\D025328\Documents\Eclipse\workspace.jac\com.wudsn.ide.ref\ASM\Atari2600\DASM\DASM-Error-Reference.asm
|
|
* 3 0000 ????
|
|
* C:\Users\D025328\Documents\Eclipse\workspace.jac\com.wudsn.ide.ref\ASM\Atari2600\DASM\DASM-Error-Reference.asm (4): error: Unknown Mnemonic 'jmp'.
|
|
* 4 0000 ???? jmp nowhere
|
|
* 5 0000 ????
|
|
* </pre>
|
|
*
|
|
* @author Peter Dell
|
|
*/
|
|
final class DasmCompilerProcessLogParser extends CompilerProcessLogParser {
|
|
|
|
private Pattern pattern;
|
|
|
|
private String listLog;
|
|
private String listLogErrorMessage;
|
|
private boolean fatalErrorFound;
|
|
private boolean unresolvedSymbolsFound;
|
|
|
|
@Override
|
|
protected void initialize() {
|
|
pattern = Pattern.compile(".* (.*): error:");
|
|
|
|
File listFile = new File(files.outputFolder, files.mainSourceFile.fileNameWithoutExtension + ".lst");
|
|
if (listFile.exists()) {
|
|
try {
|
|
listLog = FileUtility.readString(listFile.getPath(), new FileInputStream(listFile),
|
|
FileUtility.MAX_SIZE_UNLIMITED);
|
|
listLogErrorMessage = null;
|
|
} catch (FileNotFoundException ex) {
|
|
listLog = "";
|
|
listLogErrorMessage = ex.getMessage();
|
|
} catch (CoreException ex) {
|
|
listLog = "";
|
|
listLogErrorMessage = ex.getStatus().getMessage();
|
|
}
|
|
} else {
|
|
listLog = "";
|
|
listLogErrorMessage = "Expected list file '"
|
|
+ listFile.getPath()
|
|
+ "' does not exist. Check the compiler preferences and make sure you have set the option '-l${outputFilePathWithoutExtension}.lst'.";
|
|
}
|
|
fatalErrorFound = false;
|
|
unresolvedSymbolsFound = false;
|
|
}
|
|
|
|
@Override
|
|
protected void findNextMarker() {
|
|
|
|
if (listLogErrorMessage != null) {
|
|
filePath = mainSourceFilePath;
|
|
lineNumber = 0;
|
|
severity = IMarker.SEVERITY_ERROR;
|
|
message = listLogErrorMessage;
|
|
markerAvailable = true;
|
|
listLogErrorMessage = null;
|
|
return;
|
|
}
|
|
|
|
int index;
|
|
String line;
|
|
Matcher matcher = pattern.matcher(listLog);
|
|
|
|
if (matcher.find()) {
|
|
index = matcher.start();
|
|
line = listLog.substring(index);
|
|
listLog = listLog.substring(matcher.end());
|
|
int numberIndex = line.indexOf(" (");
|
|
|
|
if (numberIndex > 0) {
|
|
|
|
filePath = line.substring(0, numberIndex);
|
|
|
|
String lineNumberString;
|
|
int numberEndIndex = line.indexOf(')');
|
|
if (numberEndIndex > 0) {
|
|
lineNumberString = line.substring(numberIndex + 2, numberEndIndex);
|
|
} else {
|
|
lineNumberString = "-1";
|
|
}
|
|
|
|
try {
|
|
lineNumber = Integer.parseInt(lineNumberString);
|
|
|
|
int nextIndex = line.indexOf("\n");
|
|
if (nextIndex > 0) {
|
|
message = line.substring(numberEndIndex + 10, nextIndex - 1);
|
|
}
|
|
} catch (NumberFormatException ex) {
|
|
lineNumber = -1;
|
|
message = ex.getMessage();
|
|
}
|
|
|
|
severity = IMarker.SEVERITY_ERROR;
|
|
message = message.trim();
|
|
markerAvailable = true;
|
|
return;
|
|
}
|
|
} else {
|
|
index = outputLog.indexOf("Fatal assembly error: ");
|
|
if (index > 0 && !fatalErrorFound) {
|
|
int nextIndex = outputLog.indexOf("\n", index);
|
|
if (nextIndex > 0) {
|
|
message = outputLog.substring(index, nextIndex - 1);
|
|
} else {
|
|
message = outputLog.substring(index);
|
|
}
|
|
fatalErrorFound = true;
|
|
|
|
severity = IMarker.SEVERITY_ERROR;
|
|
message = message.trim();
|
|
markerAvailable = true;
|
|
return;
|
|
}
|
|
|
|
if (fatalErrorFound) {
|
|
final String UNRESOLVED = "--- Unresolved Symbol List";
|
|
index = outputLog.lastIndexOf(UNRESOLVED);
|
|
if (index > 0) {
|
|
unresolvedSymbolsFound = true;
|
|
outputLog = outputLog.substring(index + UNRESOLVED.length()).trim();
|
|
}
|
|
}
|
|
if (unresolvedSymbolsFound) {
|
|
index = outputLog.indexOf('\n');
|
|
if (index > 0) {
|
|
line = outputLog.substring(0, index - 1);
|
|
if (!line.startsWith("--")) {
|
|
outputLog = outputLog.substring(index + 1);
|
|
severity = IMarker.SEVERITY_ERROR;
|
|
index = line.indexOf(" ");
|
|
if (index > 0) {
|
|
line = line.substring(0, index);
|
|
}
|
|
message = "Unresolved symbol " + line + ".";
|
|
markerAvailable = true;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Type tokens in labels file:<br/>
|
|
*
|
|
* ???? = unknown value<br/>
|
|
* str = symbol is a string<br/>
|
|
* eqm = symbol is an eqm macro<br/>
|
|
* (r) = symbol has been referenced <br/>
|
|
* (s) = symbol created with SET or EQM pseudo-op<br/>
|
|
*/
|
|
@Override
|
|
public void addCompilerSymbols(List<CompilerSymbol> compilerSymbols) {
|
|
final String SYMBOLS = "--- Symbol List (sorted by symbol)";
|
|
|
|
String log;
|
|
int index;
|
|
|
|
log = outputLog;
|
|
index = log.indexOf(SYMBOLS);
|
|
if (index >= 0) {
|
|
log = log.substring(index + SYMBOLS.length()).trim();
|
|
|
|
index = log.indexOf('\n');
|
|
while (index > 0) {
|
|
String line = log.substring(0, index - 1);
|
|
if (line.startsWith("--- End of Symbol List.")) {
|
|
break;
|
|
}
|
|
StringTokenizer st = new StringTokenizer(line);
|
|
String name = st.nextToken();
|
|
String hexValue = "";
|
|
if (st.hasMoreTokens()) {
|
|
hexValue = st.nextToken();
|
|
}
|
|
|
|
String token = "";
|
|
int valueType = CompilerSymbol.NUMBER;
|
|
String stringValue = "";
|
|
while (st.hasMoreTokens()) {
|
|
token = st.nextToken();
|
|
// "str" indicates that the symbol is a string value
|
|
if (token.equals("str")) {
|
|
valueType = CompilerSymbol.STRING;
|
|
}
|
|
|
|
// String values are enclosed in double quotes.
|
|
if (valueType == CompilerSymbol.STRING && token.startsWith("\"") && token.length() >= 2
|
|
&& token.endsWith("\"")) {
|
|
stringValue = token.substring(1, token.length() - 1);
|
|
}
|
|
}
|
|
|
|
switch (valueType) {
|
|
case CompilerSymbol.NUMBER:
|
|
// Ignore unnamed symbol with value "0000"
|
|
if (StringUtility.isSpecified(hexValue)) {
|
|
compilerSymbols.add(CompilerSymbol.createNumberHexSymbol(name, hexValue));
|
|
}
|
|
break;
|
|
case CompilerSymbol.STRING:
|
|
compilerSymbols.add(CompilerSymbol.createStringSymbol(name, stringValue));
|
|
break;
|
|
default:
|
|
throw new IllegalStateException("Unsupported value type '" + valueType + "'.");
|
|
}
|
|
|
|
log = log.substring(index).trim();
|
|
index = log.indexOf('\n');
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
} |