diff options
-rw-r--r-- | etc/global.xml | 4 | ||||
-rw-r--r-- | etc/targets/global-tar.xml | 28 | ||||
-rw-r--r-- | lib/runtime/getopt/gnu.getopt.jar | bin | 0 -> 13625 bytes | |||
-rw-r--r-- | src/java/org/anarres/cpp/LexerSource.java | 23 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/Main.java | 273 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/Preprocessor.java | 10 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/Version.java | 51 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/Warning.java | 12 | ||||
-rw-r--r-- | src/scripts/release.sh | 8 |
9 files changed, 377 insertions, 32 deletions
diff --git a/etc/global.xml b/etc/global.xml index 052ea6b..41bf829 100644 --- a/etc/global.xml +++ b/etc/global.xml @@ -9,11 +9,9 @@ <property file="${global.dir.etc}/log4j.properties" /> <path id="compile-classpath"> - <!-- <fileset dir="${global.dir.lib}"> - <include name="**/*.jar"/> + <include name="runtime/**/*.jar"/> </fileset> - --> </path> <path id="runtime-classpath"> diff --git a/etc/targets/global-tar.xml b/etc/targets/global-tar.xml index 1b053ae..05412be 100644 --- a/etc/targets/global-tar.xml +++ b/etc/targets/global-tar.xml @@ -2,7 +2,7 @@ <project name="global-tar" basedir="."> - <target name="global-tar" depends="global-jar,global-javadoc"> + <target name="global-tar-dir" depends="global-jar"> <mkdir dir="${global.dir.build.dist}" /> <mkdir dir="${global.dir.build.tar}/lib" /> <mkdir dir="${global.dir.build.tar}/bin" /> @@ -12,6 +12,9 @@ <fileset dir="${global.dir.lib}/log4j"> <include name="**/*.jar" /> </fileset> + <fileset dir="${global.dir.lib}/runtime"> + <include name="**/*.jar" /> + </fileset> <mapper type="flatten" /> </copy> @@ -24,19 +27,6 @@ </fileset> </copy> - <copy todir="${global.dir.build.tar}/docs/api"> - <fileset dir="${global.dir.build.javadoc}" /> - </copy> - -<!-- - <copy todir="${global.dir.build.tar}/docs/examples"> - <fileset - dir="${global.dir.build.java}/org/anarres/cpp/examples"> - <include name="**" /> - </fileset> - </copy> ---> - <chmod perm="a+x"> <fileset dir="${global.dir.build.tar}/bin"> <include name="**/*.pl"/> @@ -44,9 +34,19 @@ <fileset dir="${global.dir.build.tar}"> <include name="*.sh"/> </fileset> + <fileset dir="${global.dir.build.tar}"> + <include name="jcpp"/> + </fileset> </chmod> <!-- <runtarget target="global-inject" /> --> + </target> + + <target name="global-tar" depends="global-tar-dir,global-javadoc"> + + <copy todir="${global.dir.build.tar}/docs/api"> + <fileset dir="${global.dir.build.javadoc}" /> + </copy> <tar destfile="${global.file.bintar}" diff --git a/lib/runtime/getopt/gnu.getopt.jar b/lib/runtime/getopt/gnu.getopt.jar Binary files differnew file mode 100644 index 0000000..1aea24b --- /dev/null +++ b/lib/runtime/getopt/gnu.getopt.jar diff --git a/src/java/org/anarres/cpp/LexerSource.java b/src/java/org/anarres/cpp/LexerSource.java index a291bff..51b5c07 100644 --- a/src/java/org/anarres/cpp/LexerSource.java +++ b/src/java/org/anarres/cpp/LexerSource.java @@ -297,7 +297,7 @@ public class LexerSource extends Source { if (e != '\'') { unread(e); error("Illegal character constant"); - /* XXX We could do some patching up here? */ + /* XXX We should consume the rest of the line here. */ return new Token(ERROR, text.toString(), null); } text.append('\''); @@ -306,8 +306,6 @@ public class LexerSource extends Source { text.toString(), Character.valueOf((char)d)); } - /* XXX This strips the enclosing quotes from the - * returned value. */ private Token string(char open, char close) throws IOException, LexerException { @@ -558,11 +556,24 @@ public class LexerSource extends Source { break; case '%': - tok = cond('=', MOD_EQ, '%'); + d = read(); + if (d == '=') + tok = new Token(MOD_EQ); + else if (d == '>') + tok = new Token('}'); // digraph + else if (d == ':') + tok = new Token('#'); // digraph + else // XXX Deal with %:%: -> ## + unread(d); break; case ':': /* :: */ + d = read(); + if (d == '>') + tok = new Token(']'); // digraph + else + unread(d); break; case '<': @@ -575,6 +586,10 @@ public class LexerSource extends Source { tok = new Token(LE); else if (d == '<') tok = cond('=', LSH_EQ, LSH); + else if (d == ':') + tok = new Token('['); // digraph + else if (d == '%') + tok = new Token('{'); // digraph else unread(d); } diff --git a/src/java/org/anarres/cpp/Main.java b/src/java/org/anarres/cpp/Main.java index cec7a37..cf61ecd 100644 --- a/src/java/org/anarres/cpp/Main.java +++ b/src/java/org/anarres/cpp/Main.java @@ -24,12 +24,17 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Stack; +import gnu.getopt.Getopt; +import gnu.getopt.LongOpt; + import static org.anarres.cpp.Token.*; /** @@ -37,7 +42,275 @@ import static org.anarres.cpp.Token.*; */ public class Main { + protected static class Option extends LongOpt { + private String eg; + private String help; + public Option(String word, int arg, int ch, + String eg, String help) { + super(word, arg, null, ch); + this.eg = eg; + this.help = help; + } + } + + private List<String> i_default; + private List<String> i_system; + private List<String> i_user; + private List<String> i_quote; + private Map<String,String> d_default; + private Map<String,String> d_user; + private Set<Warning> warnings; + private List<String> f_include; + + private static final Option[] OPTS = new Option[] { + new Option("help", LongOpt.NO_ARGUMENT, 'h', null, + "Displays help and usage information."), + new Option("define", LongOpt.REQUIRED_ARGUMENT, 'D', "name=definition", + "Defines the given macro."), + new Option("undefine", LongOpt.REQUIRED_ARGUMENT, 'U', "name", + "Undefines the given macro, previously either builtin or defined using -D."), + new Option("incdir", LongOpt.REQUIRED_ARGUMENT, 'I', "dir", + "Adds the directory dir to the list of directories to be searched for header files."), + new Option("warning", LongOpt.REQUIRED_ARGUMENT, 'W', "type", + "Enables the named warning class (" + getWarnings() + ")."), + new Option("nowarnings", LongOpt.NO_ARGUMENT, 'w', null, + "Disables ALL warnings."), + new Option("version", LongOpt.NO_ARGUMENT, 'V', null, + "Prints jcpp's version number (" + Version.getVersion() + ")"), + }; + + private static CharSequence getWarnings() { + StringBuilder buf = new StringBuilder(); + for (Warning w : Warning.values()) { + if (buf.length() > 0) + buf.append(", "); + String name = w.name().toLowerCase(); + buf.append(name.replace('_', '-')); + } + return buf; + } + public static void main(String[] args) throws Exception { + (new Main()).run(OPTS, args); + } + + public Main() { + i_default = new ArrayList<String>(); + i_system = new ArrayList<String>(); + i_user = new ArrayList<String>(); + i_quote = new ArrayList<String>(); + d_default = new HashMap<String,String>(); + d_user = new HashMap<String,String>(); + warnings = EnumSet.noneOf(Warning.class); + } + + public void run(Option[] opts, String[] args) throws Exception { + String sopts = getShortOpts(opts); + Getopt g = new Getopt("jcpp", args, sopts, opts); + int c; + String arg; + int idx; + + GETOPT: while ((c = g.getopt()) != -1) { + switch (c) { + case 'D': + arg = g.getOptarg(); + idx = arg.indexOf('='); + if (idx == -1) + d_user.put(arg, "1"); + else + d_user.put(arg.substring(0, idx), + arg.substring(idx + 1)); + break; + case 'U': + d_default.remove(g.getOptarg()); + d_user.remove(g.getOptarg()); + break; + case 'I': + i_user.add(g.getOptarg()); + break; + case 'W': + arg = g.getOptarg().toUpperCase(); + arg = arg.replace('-', '_'); + if (arg.equals("all")) + warnings = EnumSet.allOf(Warning.class); + else + warnings.add(Enum.valueOf(Warning.class, arg)); + break; + case 'w': + warnings = EnumSet.noneOf(Warning.class); + break; + case 'V': + System.out.println("Anarres Java C Preprocessor version " + Version.getVersion()); + System.exit(0); + throw new Exception("Exited"); + case 'h': + usage(getClass().getName(), opts); + System.exit(1); + throw new Exception("Exited"); + default: + case '?': + throw new Exception("Illegal option " + c); + } + } + + File file = new File(args[g.getOptind()]); + Source source = new FileLexerSource(file); + Preprocessor pp = new Preprocessor(source); + + /* XXX Warnings, include-path, include-files. */ + + for (int i = g.getOptind() + 1; i < args.length; i++) { + /* XXX Wrong, needs to concat them not push them. */ + /* XXX Reverse this list. */ + pp.addSource(new FileLexerSource(new File(args[i]))); + } + + for (Map.Entry<String,String> e : d_default.entrySet()) + pp.addMacro(e.getKey(), e.getValue()); + for (Map.Entry<String,String> e : d_user.entrySet()) + pp.addMacro(e.getKey(), e.getValue()); + + /* XXX Include paths. */ + + try { + for (;;) { + Token tok = pp.token(); + if (tok != null && tok.getType() == Token.EOF) + break; + System.out.print(tok.getText()); + } + } + catch (Exception e) { + e.printStackTrace(); + Source s = pp.getSource(); + while (s != null) { + System.out.println(" -> " + s); + s = s.getParent(); + } + } + + } + + + private static String getShortOpts(Option[] opts) + throws Exception { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < opts.length; i++) { + char c = (char)opts[i].getVal(); + for (int j = 0; j < buf.length(); j++) + if (buf.charAt(j) == c) + throw new Exception( + "Duplicate short option " + c + ); + buf.append(c); + switch (opts[i].getHasArg()) { + case LongOpt.NO_ARGUMENT: + break; + case LongOpt.OPTIONAL_ARGUMENT: + buf.append("::"); + break; + case LongOpt.REQUIRED_ARGUMENT: + buf.append(":"); + break; + } + } + return buf.toString(); + } + + /* This is incomplete but nearly there. */ + /** + * Wraps a string. + * + * The output form is: + * <pre> + * prefix in[0] + * <--indent-> in[1] + * <--indent-> in[2] + * <-----width----> + * </pre> + */ + /* XXX There's some of this in commons. */ + private static String wrap(String in, String prefix, + int indent, int width) { + StringBuilder buf = new StringBuilder(prefix); + + while (buf.length() < indent) + buf.append(' '); + + int start = 0; + + while (start < in.length()) { + while (start < in.length() && + Character.isWhitespace(in.charAt(start))) + start++; + + int end = start + width - indent; + + if (end > in.length()) { + buf.append(in.substring(start)); + break; + } + + int idx = end; + while (!Character.isWhitespace(in.charAt(idx))) + idx--; + + if (idx == start) { + idx = end - 1; + buf.append(in.substring(start, idx)); + buf.append('-'); + } + else { + buf.append(in.substring(start, idx)); + start = idx; + } + + start = idx; + } + + return buf.toString(); + } + + private static void usage(String command, Option[] options) { + StringBuilder text = new StringBuilder("Usage: "); + text.append(command).append('\n'); + for (int i = 0; i < options.length; i++) { + StringBuilder line = new StringBuilder(); + Option opt = options[i]; + line.append(" --").append(opt.getName()); + switch (opt.getHasArg()) { + case LongOpt.NO_ARGUMENT: + break; + case LongOpt.OPTIONAL_ARGUMENT: + line.append("[=").append(opt.eg).append(']'); + break; + case LongOpt.REQUIRED_ARGUMENT: + line.append('=').append(opt.eg); + break; + } + line.append(" (-").append((char)opt.getVal()).append(")"); + if (line.length() < 30) { + while (line.length() < 30) + line.append(' '); + } + else { + line.append('\n'); + for (int j = 0; j < 30; j++) + line.append(' '); + } + /* This should use wrap. */ + line.append(opt.help); + line.append('\n'); + text.append(line); + } + + System.out.println(text); + } + + + + public static void oldmain(String[] args) throws Exception { List<String> path = new ArrayList<String>(); path.add("/usr/include"); path.add("/usr/local/include"); diff --git a/src/java/org/anarres/cpp/Preprocessor.java b/src/java/org/anarres/cpp/Preprocessor.java index de6d01b..17d6c04 100644 --- a/src/java/org/anarres/cpp/Preprocessor.java +++ b/src/java/org/anarres/cpp/Preprocessor.java @@ -329,7 +329,6 @@ public class Preprocessor { LexerException { Token tok; do { - /* XXX This _should_ never be a NL token, I think. */ tok = source_token(); } while (isWhite(tok)); return tok; @@ -769,7 +768,7 @@ public class Preprocessor { dir = new File("/"); File file = new File(dir, name); // System.err.println("Include: " + file); - if (file.exists()) { + if (file.exists() && file.isFile()) { push_source(new FileLexerSource(file), true); return; } @@ -780,7 +779,7 @@ public class Preprocessor { File file = new File( path.get(i) + File.separator + name ); - if (file.exists()) { + if (file.exists() && file.isFile()) { // System.err.println("Include: " + file); push_source(new FileLexerSource(file), true); return; @@ -807,11 +806,8 @@ public class Preprocessor { * Backslashes must not be treated as escapes here. */ StringBuilder buf = new StringBuilder((String)tok.getValue()); HEADER: for (;;) { - tok = _token(); /* Do macros but nothing else. */ + tok = token_nonwhite(); switch (tok.getType()) { - case WHITESPACE: - case COMMENT: - continue; case STRING: buf.append((String)tok.getValue()); break; diff --git a/src/java/org/anarres/cpp/Version.java b/src/java/org/anarres/cpp/Version.java new file mode 100644 index 0000000..6780506 --- /dev/null +++ b/src/java/org/anarres/cpp/Version.java @@ -0,0 +1,51 @@ +package org.anarres.cpp; + +/** + * System version metadata for Anarres Java C Preprocessor ${version}. + * + * This class contains a main() and may be run to print the version. + */ +public class Version { + + /* Don't instantiate me */ + private Version() { + } + + private static final String VERSION = "${version}"; + + private static final int major; + private static final int minor; + private static final int patch; + + static { + String[] tmp = VERSION.split("\\."); + major = Integer.parseInt(tmp[0]); + minor = Integer.parseInt(tmp[1]); + patch = Integer.parseInt(tmp[2]); + } + + public static String getVersion() { + return VERSION; + } + + public static int getMajor() { + return major; + } + + public static int getMinor() { + return minor; + } + + public static int getPatch() { + return patch; + } + + public static void main(String[] args) { + System.out.println("Version " + VERSION); + System.out.println("getVersion() returns " + getVersion()); + System.out.println("getMajor() returns " + getMajor()); + System.out.println("getMinor() returns " + getMinor()); + System.out.println("getPatch() returns " + getPatch()); + } + +} diff --git a/src/java/org/anarres/cpp/Warning.java b/src/java/org/anarres/cpp/Warning.java new file mode 100644 index 0000000..a6450fb --- /dev/null +++ b/src/java/org/anarres/cpp/Warning.java @@ -0,0 +1,12 @@ +package org.anarres.cpp; + +public enum Warning { + TRIGRAPHS, + TRADITIONAL, + IMPORT, + UNDEF, + UNUSED_MACROS, + ENDIF_LABELS, + ERROR, + SYSTEM_HEADERS +} diff --git a/src/scripts/release.sh b/src/scripts/release.sh index 6393a95..620ce96 100644 --- a/src/scripts/release.sh +++ b/src/scripts/release.sh @@ -1,4 +1,4 @@ -scp build/dist/anarres-cpp-*.tar.gz [email protected]:public_html/projects/jcpp -scp -r build/javadoc/ [email protected]:public_html/projects/jcpp -cp build/tar/lib/anarres-cpp.jar /home/shevek/java/iengine/lib/jcpp -cp build/tar/lib/anarres-cpp.jar /home/shevek/java/karma/trunk/lib/dp +scp build/dist/anarres-cpp-*.tar.gz [email protected]:public_html/projects/jcpp/ +scp -r build/javadoc/ [email protected]:public_html/projects/jcpp/ +cp build/tar/lib/anarres-cpp.jar /home/shevek/java/iengine/lib/runtime/jcpp/ +cp build/tar/lib/anarres-cpp.jar /home/shevek/java/karma/trunk/lib/dp/ |