diff --git a/ChangeLog b/ChangeLog index b47aec2..da220ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +Wed May 13 01:22:12 2009 Minero Aoki + + * net/loveruby/cflat/utils/CommandUtils.java: accept a list of + string instead of CommandArg. + + * net/loveruby/cflat/sysdep/Linker.java: ditto. + + * net/loveruby/cflat/sysdep/LinkerOptions.java: ditto. + + * net/loveruby/cflat/sysdep/GNULinker.java: ditto. + + * net/loveruby/cflat/sysdep/AssemblerOptions.java: ditto. + + * net/loveruby/cflat/sysdep/GNUAssembler.java: ditto. + + * net/loveruby/cflat/utils/CommandArgStr.java -> + compiler/LdOption.java + + * net/loveruby/cflat/utils/CommandArg.java -> compiler/LdArg.java + + * net/loveruby/cflat/compiler/SourceFile.java: CommandArg -> + LdArg. + + * net/loveruby/cflat/compiler/Compiler.java: ditto. + + * net/loveruby/cflat/compiler/Options.java: ditto. + Mon May 11 03:17:32 2009 Minero Aoki * net/loveruby/cflat/compiler/Compiler.java: objectify assembler. diff --git a/net/loveruby/cflat/compiler/Compiler.java b/net/loveruby/cflat/compiler/Compiler.java index b8ea8bf..f1140c3 100644 --- a/net/loveruby/cflat/compiler/Compiler.java +++ b/net/loveruby/cflat/compiler/Compiler.java @@ -197,13 +197,13 @@ public class Compiler { } private void generateExecutable(Options opts) throws IPCException { - opts.linker(errorHandler) - .generateExecutable(opts.exeFileName(), opts.ldOptions()); + opts.linker(errorHandler).generateExecutable( + opts.exeFileName(), opts.ldArgs(), opts.ldOptions()); } private void generateSharedLibrary(Options opts) throws IPCException { - opts.linker(errorHandler) - .generateSharedLibrary(opts.soFileName(), opts.ldOptions()); + opts.linker(errorHandler).generateSharedLibrary( + opts.soFileName(), opts.ldArgs(), opts.ldOptions()); } private void writeFile(String path, String str) diff --git a/net/loveruby/cflat/compiler/LdArg.java b/net/loveruby/cflat/compiler/LdArg.java new file mode 100644 index 0000000..2c519d1 --- /dev/null +++ b/net/loveruby/cflat/compiler/LdArg.java @@ -0,0 +1,6 @@ +package net.loveruby.cflat.compiler; + +interface LdArg { + String toString(); + boolean isSourceFile(); +} diff --git a/net/loveruby/cflat/utils/CommandArgStr.java b/net/loveruby/cflat/compiler/LdOption.java similarity index 59% rename from net/loveruby/cflat/utils/CommandArgStr.java rename to net/loveruby/cflat/compiler/LdOption.java index 75a86dd..2b3f069 100644 --- a/net/loveruby/cflat/utils/CommandArgStr.java +++ b/net/loveruby/cflat/compiler/LdOption.java @@ -1,9 +1,9 @@ -package net.loveruby.cflat.utils; +package net.loveruby.cflat.compiler; -public class CommandArgStr implements CommandArg { +class LdOption implements LdArg { private String arg; - public CommandArgStr(String arg) { + LdOption(String arg) { this.arg = arg; } diff --git a/net/loveruby/cflat/compiler/Options.java b/net/loveruby/cflat/compiler/Options.java index d015d2e..0dac6eb 100644 --- a/net/loveruby/cflat/compiler/Options.java +++ b/net/loveruby/cflat/compiler/Options.java @@ -3,15 +3,16 @@ import net.loveruby.cflat.parser.LibraryLoader; import net.loveruby.cflat.type.TypeTable; import net.loveruby.cflat.asm.*; import net.loveruby.cflat.sysdep.*; -import net.loveruby.cflat.sysdep.X86Linux; -import net.loveruby.cflat.utils.CommandArg; import net.loveruby.cflat.utils.ErrorHandler; import net.loveruby.cflat.exception.*; -import java.util.*; -import java.io.*; +import java.util.List; +import java.util.ListIterator; +import java.util.ArrayList; +import java.util.Arrays; +import java.io.PrintStream; class Options { - CompilerMode mode; + CompilerMode mode = CompilerMode.Link; LibraryLoader loader = new LibraryLoader(); Platform platform = new X86Linux(); String outputFileName; @@ -20,6 +21,8 @@ class Options { CodeGeneratorOptions genOptions = new CodeGeneratorOptions(); AssemblerOptions asOptions = new AssemblerOptions(); LinkerOptions ldOptions = new LinkerOptions(); + List ldArgs; + List sourceFiles; CompilerMode mode() { return mode; @@ -45,29 +48,20 @@ class Options { return getOutputFileName(".so"); } + static private final String DEFAULT_OUTPUT_FILE_NAME = "a.out"; + private String getOutputFileName(String newExt) { if (outputFileName != null) { return outputFileName; } - List srcs = sourceFiles(); - if (srcs.size() == 1) { - return srcs.get(0).linkedFileName(this, newExt); + if (sourceFiles.size() == 1) { + return sourceFiles.get(0).linkedFileName(this, newExt); } else { - return "a.out"; + return DEFAULT_OUTPUT_FILE_NAME; } } - private List sourceFiles() { - List result = new ArrayList(); - for (CommandArg arg : ldOptions.args()) { - if (arg.isSourceFile()) { - result.add((SourceFile)arg); - } - } - return result; - } - String outputFileName() { return this.outputFileName; } @@ -108,13 +102,21 @@ class Options { return ldOptions; } + List ldArgs() { + List result = new ArrayList(); + for (LdArg arg : ldArgs) { + result.add(arg.toString()); + } + return result; + } + boolean isGeneratingSharedLibrary() { return ldOptions.generatingSharedLibrary; } - /** Returns List. */ List parse(List argsList) { - List srcs = new ArrayList(); + sourceFiles = new ArrayList(); + ldArgs = new ArrayList(); ListIterator args = argsList.listIterator(); while (args.hasNext()) { String arg = args.next(); @@ -166,7 +168,7 @@ class Options { asOptions.addArg(nextArg(arg, args)); } else if (arg.equals("-static")) { - ldOptions.addArg(arg); + addLdArg(arg); } else if (arg.equals("-shared")) { ldOptions.generatingSharedLibrary = true; @@ -175,18 +177,18 @@ class Options { ldOptions.generatingPIE = true; } else if (arg.equals("--readonly-plt")) { - ldOptions.addArg("-z"); - ldOptions.addArg("combreloc"); - ldOptions.addArg("-z"); - ldOptions.addArg("now"); - ldOptions.addArg("-z"); - ldOptions.addArg("relro"); + addLdArg("-z"); + addLdArg("combreloc"); + addLdArg("-z"); + addLdArg("now"); + addLdArg("-z"); + addLdArg("relro"); } else if (arg.startsWith("-L")) { - ldOptions.addArg("-L" + getOptArg(arg, args)); + addLdArg("-L" + getOptArg(arg, args)); } else if (arg.startsWith("-l")) { - ldOptions.addArg("-l" + getOptArg(arg, args)); + addLdArg("-l" + getOptArg(arg, args)); } else if (arg.equals("-nostartfiles")) { ldOptions.noStartFiles = true; @@ -200,11 +202,11 @@ class Options { } else if (arg.startsWith("-Wl,")) { for (String opt : parseCommaSeparatedOptions(arg)) { - ldOptions.addArg(opt); + addLdArg(opt); } } else if (arg.equals("-Xlinker")) { - ldOptions.addArg(nextArg(arg, args)); + addLdArg(nextArg(arg, args)); } else if (arg.equals("-v")) { verbose = true; @@ -225,33 +227,42 @@ class Options { } } else { - // source file - addSourceFile(srcs, arg); + ldArgs.add(new SourceFile(arg)); } } // args has more arguments when "--" is appeared. while (args.hasNext()) { - addSourceFile(srcs, args.next()); + ldArgs.add(new SourceFile(args.next())); } - if (srcs.isEmpty()) parseError("no input file"); - if (mode == null) { - mode = CompilerMode.Link; + + sourceFiles = selectSourceFiles(ldArgs); + if (sourceFiles.isEmpty()) { + parseError("no input file"); } - if (! isLinkRequired() && outputFileName != null && srcs.size() > 1) { - parseError("-o option requires only 1 input not on linking"); + if (outputFileName != null + && sourceFiles.size() > 1 + && ! isLinkRequired()) { + parseError("-o option requires only 1 input (except linking)"); } - return srcs; + return sourceFiles; } private void parseError(String msg) { throw new OptionParseError(msg); } - private void addSourceFile(List srcs, String sourceName) { - SourceFile src = new SourceFile(sourceName); - srcs.add(src); - // Original argument order does matter when linking. - ldOptions.addArg(src); + private void addLdArg(String arg) { + ldArgs.add(new LdOption(arg)); + } + + private List selectSourceFiles(List args) { + List result = new ArrayList(); + for (LdArg arg : args) { + if (arg.isSourceFile()) { + result.add((SourceFile)arg); + } + } + return result; } private String getOptArg(String opt, ListIterator args) { diff --git a/net/loveruby/cflat/compiler/SourceFile.java b/net/loveruby/cflat/compiler/SourceFile.java index 1e58f62..0c4d33d 100644 --- a/net/loveruby/cflat/compiler/SourceFile.java +++ b/net/loveruby/cflat/compiler/SourceFile.java @@ -1,66 +1,72 @@ package net.loveruby.cflat.compiler; -import net.loveruby.cflat.utils.CommandArg; import java.io.File; -// package private -class SourceFile implements CommandArg { +class SourceFile implements LdArg { private String originalName; private String currentName; - public SourceFile(String name) { + SourceFile(String name) { this.originalName = name; this.currentName = name; } - public String name() { + public boolean isSourceFile() { + return true; + } + + public String toString() { + return currentName; + } + + String name() { return originalName(); } - public String originalName() { + String originalName() { return this.originalName; } - public String currentName() { + String currentName() { return this.currentName; } - public void setCurrentName(String name) { + void setCurrentName(String name) { this.currentName = name; } - public boolean isCflatSource() { + boolean isCflatSource() { return extName(currentName).equals(".cb"); } - public boolean isAssemblySource() { + boolean isAssemblySource() { return extName(currentName).equals(".s"); } - public boolean isObjectFile() { + boolean isObjectFile() { return extName(currentName).equals(".o"); } - public boolean isSharedLibrary() { + boolean isSharedLibrary() { return extName(currentName).equals(".so"); } - public boolean isStaticLibrary() { + boolean isStaticLibrary() { return extName(currentName).equals(".a"); } - public boolean isExecutable() { + boolean isExecutable() { return extName(currentName).equals(""); } - public String asmFileName(Options opts) { + String asmFileName(Options opts) { return or(opts.outputFileNameFor(CompilerMode.Compile), replaceExt(".s")); } - public String objFileName(Options opts) { + String objFileName(Options opts) { return or(opts.outputFileNameFor(CompilerMode.Assemble), replaceExt(".o")); } - public String linkedFileName(Options opts, String newExt) { + String linkedFileName(Options opts, String newExt) { return or(opts.outputFileName, replaceExt(newExt)); } @@ -90,12 +96,4 @@ class SourceFile implements CommandArg { if (idx < 0) return ""; return path.substring(idx); } - - public boolean isSourceFile() { - return true; - } - - public String toString() { - return currentName; - } } diff --git a/net/loveruby/cflat/sysdep/AssemblerOptions.java b/net/loveruby/cflat/sysdep/AssemblerOptions.java index c700c2f..79efbc0 100644 --- a/net/loveruby/cflat/sysdep/AssemblerOptions.java +++ b/net/loveruby/cflat/sysdep/AssemblerOptions.java @@ -1,18 +1,12 @@ package net.loveruby.cflat.sysdep; -import net.loveruby.cflat.utils.CommandArg; -import net.loveruby.cflat.utils.CommandArgStr; import java.util.List; import java.util.ArrayList; public class AssemblerOptions { public boolean verbose = false; - List args = new ArrayList(); + List args = new ArrayList(); public void addArg(String a) { - args.add(new CommandArgStr(a)); - } - - public void addArg(CommandArg a) { args.add(a); } } diff --git a/net/loveruby/cflat/sysdep/GNUAssembler.java b/net/loveruby/cflat/sysdep/GNUAssembler.java index 1b33684..633bc8b 100644 --- a/net/loveruby/cflat/sysdep/GNUAssembler.java +++ b/net/loveruby/cflat/sysdep/GNUAssembler.java @@ -1,7 +1,5 @@ package net.loveruby.cflat.sysdep; import net.loveruby.cflat.utils.CommandUtils; -import net.loveruby.cflat.utils.CommandArg; -import net.loveruby.cflat.utils.CommandArgStr; import net.loveruby.cflat.utils.ErrorHandler; import net.loveruby.cflat.exception.IPCException; import java.util.List; @@ -16,16 +14,12 @@ class GNUAssembler implements Assembler { public void assemble(String srcPath, String destPath, AssemblerOptions opts) throws IPCException { - List cmd = new ArrayList(); - cmd.add(arg("as")); + List cmd = new ArrayList(); + cmd.add("as"); cmd.addAll(opts.args); - cmd.add(arg("-o")); - cmd.add(arg(destPath)); - cmd.add(arg(srcPath)); + cmd.add("-o"); + cmd.add(destPath); + cmd.add(srcPath); CommandUtils.invoke(cmd, errorHandler, opts.verbose); } - - private CommandArg arg(String a) { - return new CommandArgStr(a); - } } diff --git a/net/loveruby/cflat/sysdep/GNULinker.java b/net/loveruby/cflat/sysdep/GNULinker.java index 14f2c91..fffc6b9 100644 --- a/net/loveruby/cflat/sysdep/GNULinker.java +++ b/net/loveruby/cflat/sysdep/GNULinker.java @@ -1,7 +1,5 @@ package net.loveruby.cflat.sysdep; import net.loveruby.cflat.utils.CommandUtils; -import net.loveruby.cflat.utils.CommandArg; -import net.loveruby.cflat.utils.CommandArgStr; import net.loveruby.cflat.utils.ErrorHandler; import net.loveruby.cflat.exception.IPCException; import java.util.List; @@ -20,56 +18,52 @@ class GNULinker implements Linker { this.errorHandler = errorHandler; } - public void generateExecutable( - String destPath, LinkerOptions opts) throws IPCException { - List cmd = new ArrayList(); - cmd.add(arg("ld")); - cmd.add(arg("-dynamic-linker")); - cmd.add(arg(DYNAMIC_LINKER)); + public void generateExecutable(String destPath, + List args, LinkerOptions opts) throws IPCException { + List cmd = new ArrayList(); + cmd.add("ld"); + cmd.add("-dynamic-linker"); + cmd.add(DYNAMIC_LINKER); if (opts.generatingPIE) { - cmd.add(arg("-pie")); + cmd.add("-pie"); } if (! opts.noStartFiles) { - cmd.add(arg(opts.generatingPIE + cmd.add(opts.generatingPIE ? C_RUNTIME_START_PIE - : C_RUNTIME_START)); - cmd.add(arg(C_RUNTIME_INIT)); + : C_RUNTIME_START); + cmd.add(C_RUNTIME_INIT); } - cmd.addAll(opts.args); + cmd.addAll(args); if (! opts.noDefaultLibs) { - cmd.add(arg("-lc")); - cmd.add(arg("-lcbc")); + cmd.add("-lc"); + cmd.add("-lcbc"); } if (! opts.noStartFiles) { - cmd.add(arg(C_RUNTIME_FINI)); + cmd.add(C_RUNTIME_FINI); } - cmd.add(arg("-o")); - cmd.add(arg(destPath)); + cmd.add("-o"); + cmd.add(destPath); CommandUtils.invoke(cmd, errorHandler, opts.verbose); } - public void generateSharedLibrary( - String destPath, LinkerOptions opts) throws IPCException { - List cmd = new ArrayList(); - cmd.add(arg("ld")); - cmd.add(arg("-shared")); + public void generateSharedLibrary(String destPath, + List args, LinkerOptions opts) throws IPCException { + List cmd = new ArrayList(); + cmd.add("ld"); + cmd.add("-shared"); if (! opts.noStartFiles) { - cmd.add(arg(C_RUNTIME_INIT)); + cmd.add(C_RUNTIME_INIT); } - cmd.addAll(opts.args); + cmd.addAll(args); if (! opts.noDefaultLibs) { - cmd.add(arg("-lc")); - cmd.add(arg("-lcbc")); + cmd.add("-lc"); + cmd.add("-lcbc"); } if (! opts.noStartFiles) { - cmd.add(arg(C_RUNTIME_FINI)); + cmd.add(C_RUNTIME_FINI); } - cmd.add(arg("-o")); - cmd.add(arg(destPath)); + cmd.add("-o"); + cmd.add(destPath); CommandUtils.invoke(cmd, errorHandler, opts.verbose); } - - private CommandArg arg(String a) { - return new CommandArgStr(a); - } } diff --git a/net/loveruby/cflat/sysdep/Linker.java b/net/loveruby/cflat/sysdep/Linker.java index f0fbf8f..77d97c7 100644 --- a/net/loveruby/cflat/sysdep/Linker.java +++ b/net/loveruby/cflat/sysdep/Linker.java @@ -1,7 +1,10 @@ package net.loveruby.cflat.sysdep; import net.loveruby.cflat.exception.IPCException; +import java.util.List; public interface Linker { - void generateExecutable(String destPath, LinkerOptions opts) throws IPCException; - void generateSharedLibrary(String destPath, LinkerOptions opts) throws IPCException; + void generateExecutable(String destPath, + List args, LinkerOptions opts) throws IPCException; + void generateSharedLibrary(String destPath, + List args, LinkerOptions opts) throws IPCException; } diff --git a/net/loveruby/cflat/sysdep/LinkerOptions.java b/net/loveruby/cflat/sysdep/LinkerOptions.java index a498012..aa8f767 100644 --- a/net/loveruby/cflat/sysdep/LinkerOptions.java +++ b/net/loveruby/cflat/sysdep/LinkerOptions.java @@ -1,8 +1,4 @@ package net.loveruby.cflat.sysdep; -import net.loveruby.cflat.utils.CommandArg; -import net.loveruby.cflat.utils.CommandArgStr; -import java.util.List; -import java.util.ArrayList; public class LinkerOptions { public boolean generatingSharedLibrary = false; @@ -10,17 +6,4 @@ public class LinkerOptions { public boolean noStartFiles = false; public boolean noDefaultLibs = false; public boolean verbose = false; - List args = new ArrayList(); - - public void addArg(String a) { - args.add(new CommandArgStr(a)); - } - - public void addArg(CommandArg a) { - args.add(a); - } - - public List args() { - return this.args; - } } diff --git a/net/loveruby/cflat/utils/CommandArg.java b/net/loveruby/cflat/utils/CommandArg.java deleted file mode 100644 index f8526d1..0000000 --- a/net/loveruby/cflat/utils/CommandArg.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.loveruby.cflat.utils; - -public interface CommandArg { - public String toString(); - public boolean isSourceFile(); -} diff --git a/net/loveruby/cflat/utils/CommandUtils.java b/net/loveruby/cflat/utils/CommandUtils.java index b7c55b8..e6b389e 100644 --- a/net/loveruby/cflat/utils/CommandUtils.java +++ b/net/loveruby/cflat/utils/CommandUtils.java @@ -5,13 +5,13 @@ import java.util.ArrayList; import java.io.*; abstract public class CommandUtils { - static public void invoke(List cmdArgs, + static public void invoke(List cmdArgs, ErrorHandler errorHandler, boolean debug) throws IPCException { if (debug) { dumpCommand(cmdArgs); } try { - String[] cmd = getStrings(cmdArgs); + String[] cmd = cmdArgs.toArray(new String[] {}); Process proc = Runtime.getRuntime().exec(cmd); proc.waitFor(); passThrough(proc.getInputStream()); @@ -32,20 +32,11 @@ abstract public class CommandUtils { } } - static private String[] getStrings(List list) { - String[] result = new String[list.size()]; - int idx = 0; - for (CommandArg arg : list) { - result[idx++] = arg.toString(); - } - return result; - } - - static private void dumpCommand(List args) { + static private void dumpCommand(List args) { String sep = ""; - for (CommandArg arg : args) { + for (String arg : args) { System.out.print(sep); sep = " "; - System.out.print(arg.toString()); + System.out.print(arg); } System.out.println(""); }