add ifdef support and initial system properties to preprocessor
authorcrawshaw <crawshaw@ibex.org>
Sun, 7 Nov 2004 08:59:56 +0000 (08:59 +0000)
committercrawshaw <crawshaw@ibex.org>
Sun, 7 Nov 2004 08:59:56 +0000 (08:59 +0000)
darcs-hash:20041107085956-2eb37-388d8de284fe9201d35702e63f71ed10e119d0d8.gz

src/java/ibex/tool/Preprocessor.java

index 29c96b0..1639829 100644 (file)
@@ -1,9 +1,5 @@
-// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
-//
-// You may modify, copy, and redistribute this code under the terms of
-// the GNU Library Public License version 2.1, with the exception of
-// the portion of clause 6a after the semicolon (aka the "obnoxious
-// relink clause")
+// You may modify, copy, and redistribute this code under
+// the terms of the GNU General Public License version 2.
 
 package ibex.tool;
 
@@ -21,12 +17,24 @@ import java.io.*;
  *       case "case1":
  *   //#end
  *
+ *   //#ifdef FOO                -- includes contents if FOO passed as define to preprocessor
+ *       [code]
+ *   //#endif
+ *
  *   Replacements are done on a token basis.  Tokens are defined as a
  *   sequence of characters which all belong to a single class.  The
  *   two character classes are:
  *
  *     - [a-zA-Z0-9_]
  *     - all other non-whitespace characters
+ *   
+ *   Preprocessor makes use of several optional system properties:
+ *
+ *    - ibex.tool.preprocessor.define
+ *    - ibex.tool.preprocessor.inputdir
+ *    - ibex.tool.preprocessor.outputdir
+ *
+ *   @author adam@ibex.org, crawshaw@ibex.org
  */
 public class Preprocessor {
 
@@ -44,12 +52,26 @@ public class Preprocessor {
     }
 
     public static void main(String[] args) throws Exception {
+        List defs = new ArrayList();
+
+        String define = System.getProperty("ibex.tool.preprocessor.define");
+        if (define != null) {
+            StringTokenizer st = new StringTokenizer(define.toUpperCase(), ",");
+            while (st.hasMoreTokens()) defs.add(st.nextToken().trim());
+        }
+
+        String inputdir = System.getProperty("ibex.tool.preprocessor.inputdir");
+        if (inputdir == null) inputdir = "src/";
+
+        String outputdir = System.getProperty("ibex.tool.preprocessor.outputdir");
+        if (outputdir == null) outputdir = "build/java/";
+
         if (args.length == 0) {
             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
             
             // process stdin to stdout
-            Preprocessor cc = new Preprocessor(br, bw);
+            Preprocessor cc = new Preprocessor(br, bw, defs);
             Vector err = cc.process();
             bw.flush();
             
@@ -62,13 +84,13 @@ public class Preprocessor {
             for(int i=0; i<args.length; i++) {
                 if (!args[i].endsWith(".java")) continue;
                 File source = new File(args[i]);
-                File target = new File(replaceAll(args[i], "src/", "build/java/"));
+                File target = new File(replaceAll(args[i], inputdir, outputdir));
                 if (target.exists() && target.lastModified() > source.lastModified()) continue;
                 System.err.println("preprocessing " + args[i]);
                 new File(target.getParent()).mkdirs();
                 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(source)));
                 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target)));
-                Preprocessor cc   = new Preprocessor(br, bw);
+                Preprocessor cc   = new Preprocessor(br, bw, defs);
                 Vector err = cc.process();
                 bw.flush();
                 boolean errors = false;
@@ -88,13 +110,15 @@ public class Preprocessor {
     private Hashtable repeatreplace = null;
     private Vector sinceLastRepeat = null;
     private Vector err = new Vector();
+    private List defs;
 
     private int enumSwitch = 0; // number appended to variable used in switch implementation
 
    
-    public Preprocessor(Reader reader, Writer writer) {
+    public Preprocessor(Reader reader, Writer writer, List d) {
         setReader(reader);
         setWriter(writer);
+        defs = d;
     }
 
     public void setReader(Reader reader) { r = reader; if (r != null) in = new LineNumberReader(r); }
@@ -186,6 +210,15 @@ PROCESS:
                 for(int i=0; i<sinceLastRepeat.size() - 1; i++) out.print(processLine((String)sinceLastRepeat.elementAt(i), true));
                 sinceLastRepeat = null;
                 replace = save;
+            } else if (trimmed.startsWith("//#ifdef")) {
+                String expr = trimmed.substring(8).trim().toUpperCase();
+                out.println(trimmed);
+                boolean useCode = defs.contains(expr);
+                for (trimmed = in.readLine().trim(); !trimmed.startsWith("//#endif"); trimmed = in.readLine().trim()) {
+                    if (!useCode) out.print("// ");
+                    out.print(processLine(trimmed, false));
+                }
+                out.println("//#endif "+expr);
 
             } else if (trimmed.startsWith("//#switch")) {
                 int expStart = trimmed.indexOf('(') +1;