|
@@ -25,18 +25,25 @@ import java.io.File;
|
|
|
import java.io.FileNotFoundException;
|
|
|
import java.io.FileOutputStream;
|
|
|
import java.io.IOException;
|
|
|
+import java.lang.annotation.Annotation;
|
|
|
import java.nio.charset.Charset;
|
|
|
import java.nio.file.Files;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
import java.util.Iterator;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Map.Entry;
|
|
|
+import java.util.Set;
|
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.reflections.Reflections;
|
|
|
+import org.reflections.util.ClasspathHelper;
|
|
|
+import org.reflections.util.ConfigurationBuilder;
|
|
|
|
|
|
+import de.mcs.tools.sps.annotations.SPSOutputter;
|
|
|
import de.mcs.tools.sps.exceptions.IllegalArgument;
|
|
|
import de.mcs.tools.sps.exceptions.SyntaxError;
|
|
|
import de.mcs.tools.sps.mnemonic.CALL;
|
|
@@ -64,10 +71,11 @@ public class SPSAssembler {
|
|
|
private static final String INCLUDE_FILE = ".include";
|
|
|
private static final String END_MACRO_DEFINITION = ".endmacro";
|
|
|
private static final String START_MACRO_DEFINITION = ".macro";
|
|
|
+ private static final String DEFAULT_PACKAGE_FILTER = "de.mcs.tools.sps"; //$NON-NLS-1$
|
|
|
private static File source;
|
|
|
private static HARDWARE destination;
|
|
|
private static File destinationFile;
|
|
|
- private static FORMAT outputFormat;
|
|
|
+ private static String outputFormat;
|
|
|
private static File includes;
|
|
|
|
|
|
private int lineNumber;
|
|
@@ -78,6 +86,7 @@ public class SPSAssembler {
|
|
|
private boolean inMacro;
|
|
|
private Macro actualMacro;
|
|
|
private Map<String, Macro> macros;
|
|
|
+ private static Outputter outputter;
|
|
|
|
|
|
@SwitchOption(shortKey = 'h', longKey = "help", name = "help", help = "show this help page", required = false, defaultValue = false)
|
|
|
public static void doHelp(boolean value) {
|
|
@@ -89,7 +98,7 @@ public class SPSAssembler {
|
|
|
|
|
|
@StringOption(shortKey = 'f', longKey = "format", name = "format", defaultValue = "HEX", help = "the output format. HEX: IntelHEX, TPSTXT: TPS programming text", required = false)
|
|
|
public static void setOutputFormat(String value) {
|
|
|
- outputFormat = FORMAT.valueOf((value.toUpperCase()));
|
|
|
+ outputFormat = value.toUpperCase();
|
|
|
}
|
|
|
|
|
|
@StringOption(shortKey = 'd', longKey = "hardware", name = "hardware system", defaultValue = "HOLTEK", help = "the hardware system to compile to. Passible options are: HOLTEK, ATMEGA8, ARDUINOSPS, TINYSPS", required = false)
|
|
@@ -127,23 +136,25 @@ public class SPSAssembler {
|
|
|
destination = HARDWARE.HOLTEK;
|
|
|
|
|
|
CommandlineProcessor.processCommandline(SPSAssembler.class, args);
|
|
|
+
|
|
|
+ registerOutputter();
|
|
|
+
|
|
|
if ((source == null) || (!source.exists())) {
|
|
|
CommandlineProcessor.showHelp(
|
|
|
String.format("source file null or not found. %s", (source == null) ? "" : source.getAbsolutePath()));
|
|
|
System.exit(-1);
|
|
|
}
|
|
|
- System.out.printf("source file: %s \r\n", source.getName());
|
|
|
+
|
|
|
if (destinationFile == null) {
|
|
|
String name = source.getName();
|
|
|
name = name.substring(0, source.getName().lastIndexOf("."));
|
|
|
- String ext = ".hex";
|
|
|
- if (outputFormat.equals(FORMAT.TPSTXT)) {
|
|
|
- ext = ".txt";
|
|
|
- }
|
|
|
+ String ext = outputter.getDefaultExtension();
|
|
|
destinationFile = new File(source.getParentFile(), name + ext);
|
|
|
}
|
|
|
+
|
|
|
+ System.out.printf("source file: %s \r\n", source.getName());
|
|
|
System.out.printf("destination file: %s \r\n", destinationFile.getName());
|
|
|
- System.out.printf("output format: %s \r\n", outputFormat.name());
|
|
|
+ System.out.printf("output format: %s \r\n", outputFormat);
|
|
|
System.out.println();
|
|
|
|
|
|
try {
|
|
@@ -170,6 +181,36 @@ public class SPSAssembler {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * @throws InstantiationException
|
|
|
+ * @throws IllegalAccessException
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ private static void registerOutputter() throws InstantiationException, IllegalAccessException, Exception {
|
|
|
+ Set<Class<?>> outputClasses = registerOutputter(SPSOutputter.class);
|
|
|
+ for (Class<?> outClass : outputClasses) {
|
|
|
+ SPSOutputter annotation = outClass.getAnnotation(SPSOutputter.class);
|
|
|
+ if (annotation.name().equalsIgnoreCase(outputFormat)) {
|
|
|
+ outputter = (Outputter) outClass.newInstance();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (outputter == null) {
|
|
|
+ throw new Exception(String.format("can't find outputter for format: %s", outputFormat));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Set<Class<?>> registerOutputter(Class<? extends Annotation>... annotationClasses) {
|
|
|
+ ConfigurationBuilder builder = new ConfigurationBuilder();
|
|
|
+ builder.addUrls(ClasspathHelper.forPackage(DEFAULT_PACKAGE_FILTER));
|
|
|
+ Reflections reflections = new Reflections(builder);
|
|
|
+ Set<Class<?>> classes = new HashSet<Class<?>>();
|
|
|
+ for (Class<? extends Annotation> class1 : annotationClasses) {
|
|
|
+ classes.addAll(reflections.getTypesAnnotatedWith(class1));
|
|
|
+ }
|
|
|
+ return classes;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* @param mnemonics
|
|
|
* @throws IOException
|
|
@@ -177,13 +218,7 @@ public class SPSAssembler {
|
|
|
*/
|
|
|
private static void outputFile(List<Mnemonic> mnemonics) throws IOException, FileNotFoundException {
|
|
|
try (FileOutputStream output = new FileOutputStream(destinationFile)) {
|
|
|
- if (outputFormat.equals(FORMAT.HEX)) {
|
|
|
- new IntelHEXOutputter().output(mnemonics, output);
|
|
|
- } else if (outputFormat.equals(FORMAT.TPSTXT)) {
|
|
|
- new TPSTextOutputter().output(mnemonics, output);
|
|
|
- } else if (outputFormat.equals(FORMAT.HEXTXT)) {
|
|
|
- new HEXTextOutputter().output(mnemonics, output);
|
|
|
- }
|
|
|
+ outputter.output(mnemonics, output);
|
|
|
} finally {
|
|
|
}
|
|
|
}
|