2003/08/10 06:30:03
[org.ibex.core.git] / src / org / xwt / util / Preprocessor.java
1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
2 package org.xwt.util;
3
4 import java.util.*;
5 import java.io.*;
6
7 /**
8  *   A VERY crude, inefficient Java preprocessor
9  *
10  *   //#define FOO bar baz       -- replace all instances of token FOO with "bar baz"
11  *   //#replace foo/bar baz/bop  -- DUPLICATE everything between here and //#end,
12  *                                  replacing foo with bar and baz with bop in the *second* copy
13  *
14  *   Replacements are done on a token basis.  Tokens are defined as a
15  *   sequence of characters which all belong to a single class.  The
16  *   two character classes are:
17  *
18  *     - [a-zA-Z0-9_]
19  *     - all other non-whitespace characters
20  */
21 public class Preprocessor {
22
23     static Hashtable replace = new Hashtable();
24     static Hashtable repeatreplace = null;
25     static Vector sinceLastRepeat = null;
26
27     public static void main(String[] args) throws IOException {
28         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
29         String s = null;
30
31         while((s = br.readLine()) != null) {
32             if (sinceLastRepeat != null) sinceLastRepeat.addElement(s);
33             String trimmed = s.trim();
34             if (trimmed.startsWith("//#define ")) {
35                 trimmed = trimmed.substring(10).trim();
36                 String key = trimmed.substring(0, trimmed.indexOf(' '));
37                 String val = trimmed.substring(trimmed.indexOf(' ')).trim();
38                 replace.put(key, val);
39                 System.out.println(); // preserve line numbers
40                 
41             } else if (trimmed.startsWith("//#repeat ")) {
42                 StringTokenizer st = new StringTokenizer(trimmed.substring(9), " ");
43                 repeatreplace = (Hashtable)replace.clone();
44                 while (st.hasMoreTokens()) {
45                     String tok = st.nextToken().trim();
46                     String key = tok.substring(0, tok.indexOf('/'));
47                     String val = tok.substring(tok.indexOf('/') + 1);
48                     repeatreplace.put(key, val);
49                 }
50                 sinceLastRepeat = new Vector();
51                 System.out.println(); // preserve line numbers
52
53             } else if (trimmed.startsWith("//#end")) {
54                 Hashtable save = replace;
55                 replace = repeatreplace;
56                 System.out.println();
57                 for(int i=0; i<sinceLastRepeat.size() - 1; i++) processLine((String)sinceLastRepeat.elementAt(i), true);
58                 sinceLastRepeat = null;
59                 replace = save;
60
61             } else {
62                 processLine(s, false);
63             }
64            
65         }
66
67     }
68
69     static void processLine(String s, boolean deleteLineEndings) throws IOException {
70         if (deleteLineEndings && s.indexOf("//") != -1) s = s.substring(0, s.indexOf("//"));
71         for(int i=0; i<s.length(); i++) {
72             char c = s.charAt(i);
73             if (!Character.isLetter(c) && !Character.isDigit(c) && c != '_') {
74                 System.out.print(c);
75                 continue;
76             }
77             int j;
78             for(j = i; j < s.length(); j++) {
79                 c = s.charAt(j);
80                 if (!Character.isLetter(c) && !Character.isDigit(c) && c != '_') break;
81             }
82             String tok = s.substring(i, j);
83             String val = (String)replace.get(tok);
84             if (val != null) System.out.print(val);
85             else System.out.print(tok);
86             i = j - 1;
87         }
88         if (!deleteLineEndings) System.out.println();
89     }
90 }
91