wudsn-ide/com.wudsn.ide.asm/src/com/wudsn/ide/asm/compiler/CompilerFiles.java
2019-01-12 23:07:17 +01:00

256 lines
9.3 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;
import java.io.File;
import org.eclipse.core.resources.IFile;
import com.wudsn.ide.asm.AssemblerProperties;
import com.wudsn.ide.asm.AssemblerProperties.AssemblerProperty;
import com.wudsn.ide.asm.preferences.CompilerPreferences;
import com.wudsn.ide.base.common.FileUtility;
import com.wudsn.ide.base.common.StringUtility;
/**
* Container class for the folder, file names and paths of the source file, the
* output file and the symbols file.
*
* @author Peter Dell
*
*/
public final class CompilerFiles {
public final class SourceFile {
public final IFile iFile;
public final File folder;
public final String folderPath;
public final File file;
public final String filePath;
public final String fileName;
public final String fileNameWithoutExtension;
public final AssemblerProperties assemblerProperties;
SourceFile(IFile iFile, AssemblerProperties assemblerProperties) {
if (iFile == null) {
throw new IllegalArgumentException("Parameter 'iFile' must not be null.");
}
if (assemblerProperties == null) {
throw new IllegalArgumentException("Parameter 'assemblerProperties' must not be null.");
}
this.iFile = iFile;
this.assemblerProperties = assemblerProperties;
// Source file.
filePath = iFile.getLocation().toOSString();
file = FileUtility.getCanonicalFile(new File(filePath));
fileName = file.getName();
String extension = iFile.getFileExtension();
if (extension == null) {
extension = "";
}
fileNameWithoutExtension = fileName.substring(0, fileName.length() - extension.length() - 1);
// Source folder.
folder = file.getParentFile();
folderPath = folder.getPath();
}
}
/**
* The actual source file which is currently open.
*/
public final SourceFile sourceFile;
/**
* The main source file which is either the current file or the file
* indicated by the property "@com.wudsn.ide.asm.editor.MainSourceFile".
*/
public final SourceFile mainSourceFile;
public final AssemblerProperty outputFolderModeProperty;
public final String outputFolderMode;
public final AssemblerProperty outputFolderProperty;
public final File outputFolder;
public final String outputFolderPath;
public final File outputFile;
public final String outputFilePath;
public final String outputFilePathWithoutExtension;
public final AssemblerProperty outputFileProperty;
public final String outputFileName;
public final String outputFileNameWithoutExtension;
public final AssemblerProperty outputFileExtensionProperty;
public final String outputFileExtension;
public final String outputFileNameShortWithoutExtension;
public final File symbolsFile;
public final String symbolsFilePath;
public final String symbolsFileName;
public CompilerFiles(IFile mainSourceIFile, AssemblerProperties mainSourceFileAssemblerProperties,
IFile sourceIFile, AssemblerProperties sourceFileAssemblerProperties,
CompilerPreferences compilerPreferences) {
if (mainSourceIFile == null) {
throw new IllegalArgumentException("Parameter 'mainSourceIFile' must not be null.");
}
if (sourceIFile == null) {
throw new IllegalArgumentException("Parameter 'sourceIFile' must not be null.");
}
if (compilerPreferences == null) {
throw new IllegalArgumentException("Parameter 'compilerPreferences' must not be null.");
}
this.mainSourceFile = new SourceFile(mainSourceIFile, mainSourceFileAssemblerProperties);
this.sourceFile = new SourceFile(sourceIFile, sourceFileAssemblerProperties);
// Output folder mode
// Can be overridden via annotation property in main source file
String localOutputFolderPath = compilerPreferences.getOutputFolderPath();
String localOutputFolderMode = compilerPreferences.getOutputFolderMode();
String localOutputFileExtension = compilerPreferences.getOutputFileExtension();
// Properties which override the preferences
outputFolderModeProperty = mainSourceFileAssemblerProperties.get(AssemblerProperties.OUTPUT_FOLDER_MODE);
outputFolderProperty = mainSourceFileAssemblerProperties.get(AssemblerProperties.OUTPUT_FOLDER);
outputFileExtensionProperty = mainSourceFileAssemblerProperties.get(AssemblerProperties.OUTPUT_FILE_EXTENSION);
outputFileProperty = mainSourceFileAssemblerProperties.get(AssemblerProperties.OUTPUT_FILE);
// The following sequence sets the instance fields "outputFolder" and
// "outputFileNameWithoutExtension" as well as the
// "outputFileNameWithoutExtension".
// If the output file is specified explicitly, it overrides all output
// properties.
if (outputFileProperty != null) {
// Make the file an absolute file.
File file = new File(outputFileProperty.value);
if (!file.isAbsolute()) {
file = new File(mainSourceFile.file.getParentFile(), file.getPath());
}
file = FileUtility.getCanonicalFile(file);
outputFolderMode = CompilerOutputFolderMode.FIXED_FOLDER;
outputFolder = file.getParentFile();
// Split the file name and file extension.
String fileName = file.getName();
int index = fileName.lastIndexOf('.');
if (index > 0) {
outputFileNameWithoutExtension = fileName.substring(0, index);
localOutputFileExtension = fileName.substring(index);
} else {
outputFileNameWithoutExtension = fileName;
localOutputFileExtension = "";
}
} else {
// The output file extension is independent of the rest.
if (outputFileExtensionProperty != null) {
localOutputFileExtension = outputFileExtensionProperty.value;
}
// If the output folder mode is specified explicitly, it overrides
// the output
// folder mode preferences.
if (outputFolderModeProperty != null) {
localOutputFolderMode = outputFolderModeProperty.value;
}
// If the output folder is specified explicitly, it overrides the
// output folder mode and folder preferences.
if (outputFolderProperty != null) {
localOutputFolderMode = CompilerOutputFolderMode.FIXED_FOLDER;
localOutputFolderPath = outputFolderProperty.value;
}
if (localOutputFolderMode.equals(CompilerOutputFolderMode.SOURCE_FOLDER)) {
localOutputFolderPath = mainSourceFile.folderPath;
} else if (localOutputFolderMode.equals(CompilerOutputFolderMode.FIXED_FOLDER)) {
// Fallback
if (StringUtility.isEmpty(localOutputFolderPath)) {
localOutputFolderPath = System.getProperty("java.io.tmpdir");
}
} else {
localOutputFolderPath = System.getProperty("java.io.tmpdir");
}
File file = new File(localOutputFolderPath);
if (!file.isAbsolute()) {
file = new File(sourceFile.file, file.getPath());
}
file = FileUtility.getCanonicalFile(file);
outputFolderMode = localOutputFolderMode;
outputFolder = file;
// Output file.
outputFileNameWithoutExtension = mainSourceFile.fileNameWithoutExtension;
}
// Common output parts.
outputFolderPath = outputFolder.getPath();
outputFileNameShortWithoutExtension = getFileNameShort(outputFileNameWithoutExtension);
outputFileName = outputFileNameWithoutExtension + localOutputFileExtension;
outputFileExtension = localOutputFileExtension;
outputFile = new File(outputFolder, outputFileName);
outputFilePath = outputFile.getPath();
outputFilePathWithoutExtension = new File(outputFolder, outputFileNameWithoutExtension).getPath();
// Symbols file.
symbolsFileName = mainSourceFile.fileNameWithoutExtension + ".lbl";
symbolsFile = new File(outputFolder, symbolsFileName);
symbolsFilePath = symbolsFile.getPath();
}
/**
* Computes a short file consisting of at most 8 ASCII letters and digits
* which starts with a letter.
*
* @param fileName
* The file name, may be empty, not <code>null</code>.
* @return The short file, name, not empty and not <code>null</code>.
*/
private String getFileNameShort(String fileName) {
if (fileName == null) {
throw new IllegalArgumentException("Parameter 'fileName' must not be null.");
}
StringBuilder builder = new StringBuilder(fileName);
for (int i = 0; i < fileName.length() && builder.length() < 8; i++) {
char c = fileName.charAt(i);
c = Character.toUpperCase(c);
if (c >= 'A' && c <= 'Z' && (builder.length() > 0) || c >= '0' && c <= '9') {
builder.append(c);
}
}
if (builder.length() == 0) {
return "UNKNOWN";
}
return builder.toString();
}
}