Source Code Cross Referenced for CodeMangler.java in  » Internationalization-Localization » icu4j » com » ibm » icu » dev » tool » docs » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Internationalization Localization » icu4j » com.ibm.icu.dev.tool.docs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         *******************************************************************************
003:         * Copyright (C) 2004-2006, International Business Machines Corporation and    *
004:         * others. All Rights Reserved.                                                *
005:         *******************************************************************************
006:         */package com.ibm.icu.dev.tool.docs;
007:
008:        import java.io.BufferedReader;
009:        import java.io.File;
010:        import java.io.FileInputStream;
011:        import java.io.FilenameFilter;
012:        import java.io.FileOutputStream;
013:        import java.io.InputStream;
014:        import java.io.InputStreamReader;
015:        import java.io.IOException;
016:        import java.io.PrintStream;
017:        import java.util.ArrayList;
018:        import java.util.Iterator;
019:        import java.util.Map;
020:        import java.util.HashMap;
021:        import java.util.TreeMap;
022:
023:        // import java.util.regex.*;
024:
025:        /**
026:         * A simple facility for adding C-like preprocessing to .java files.
027:         * This only understands a subset of the C preprocessing syntax.
028:         * Its used to manage files that with only small differences can be
029:         * compiled for different JVMs.  This changes files in place, 
030:         * commenting out lines based on the current flag settings.
031:         */
032:        public class CodeMangler {
033:            private File indir; // root of input
034:            private File outdir; // root of output
035:            private String suffix; // suffix to process, default '.jpp'
036:            private boolean recurse; // true if recurse on directories
037:            private boolean force; // true if force reprocess of files
038:            private boolean clean; // true if output is to be cleaned
039:            private boolean timestamp; // true if we read/write timestamp
040:            private HashMap map; // defines
041:            private ArrayList names; // files/directories to process
042:            private String header; // sorted list of defines passed in
043:
044:            private boolean verbose; // true if we emit debug output
045:
046:            private static final String IGNORE_PREFIX = "//##";
047:            private static final String HEADER_PREFIX = "//##header";
048:
049:            //     static final Pattern pat = Pattern.compile(
050:            //         "(?i)^(\\s*(?://+)??\\s*)#(ifdef\\s|ifndef\\s|else|endif|undef\\s|define\\s|if\\s|elif\\s)\\s*(.*)$");
051:            //     // static final Pattern pat2 = Pattern.compile("([^=!]+)\\s*([!=]?=)??\\s*(\\w+)");
052:            //     static final Pattern pat2 = Pattern.compile("\\s*(\\w+)\\s*([!=]?=)??\\s*([^\\s]?.*$)");
053:            //     static final Pattern pat3 = Pattern.compile("^(\\s*//##).*");
054:
055:            public static void main(String[] args) {
056:                //         test();
057:                new CodeMangler(args).run();
058:            }
059:
060:            //     private static final void test() {
061:            //         testPat();
062:            //         testPat2();
063:            //         testPat3();
064:            //     }
065:            //     private static final void testPat() {
066:            //         System.out.println("test pat");
067:            //         String[] tests = {
068:            //             "",
069:            //             " ",
070:            //             "#endif",
071:            //             "# endif",
072:            //             "#ENDIF",
073:            //             "#eNdIf",
074:            //             "//#endif",
075:            //             "// #endif",
076:            //             "// # endif",
077:            //             "  //  #ifdef foo",
078:            //             "  //  #ifndef foo",
079:            //             "  //  #else",
080:            //             "  //  #endif",
081:            //             "  //  #undef foo",
082:            //             "  //  #define foo bar",
083:            //             "  //  #if foo == bar",
084:            //             "  //  #elif bar != baz",
085:            //         };
086:            //         for (int i = 0; i < tests.length; ++i) {
087:            //             System.out.print("pat '" + tests[i] + "' --> ");
088:            //             Matcher m = pat.matcher(tests[i]);
089:            //             if (m.find()) {
090:            //                 System.out.println("'" + m.group(1) + "' '" + m.group(2) + "' '" + m.group(3) + "'");
091:            //             } else {
092:            //                 System.out.println("didn't match");
093:            //             }
094:            //             System.out.print("dug '" + tests[i] + "' --> ");
095:            //             String[] res = new String[3];
096:            //             if (patMatch(tests[i], res)) {
097:            //                 System.out.println("'" + res[0] + "' '" + res[1] + "' '" + res[2] + "'");
098:            //             } else {
099:            //                 System.out.println("didn't match");
100:            //             }
101:            //         }
102:            //     }
103:
104:            //     private static final void testPat2() {
105:            //         System.out.println("test pat2");
106:            //         String[] tests = {
107:            //             "",
108:            //             " ",
109:            //             "test",
110:            //             " test",
111:            //             "test ",
112:            //             " test ",
113:            //             " test ==",
114:            //             " !=",
115:            //             " !=foo",
116:            //             "foo==bar",
117:            //             "foo ==bar",
118:            //             "foo== bar",
119:            //             "foo == bar",
120:            //             "foo bar baz, wompf",
121:            //             "foo=bar=baz, wompf a loo",
122:            //         };
123:            //         for (int i = 0; i < tests.length; ++i) {
124:            //             System.out.print("pat '" + tests[i] + "' --> ");
125:            //             Matcher m2 = pat2.matcher(tests[i]);
126:            //             if (m2.find()) {
127:            //                 System.out.println("'" + m2.group(1) + "' '" + m2.group(2) + "' '" + m2.group(3) + "'");
128:            //             } else {
129:            //                 System.out.println("didn't match");
130:            //             }
131:            //             System.out.print("dug '" + tests[i] + "' --> ");
132:            //             String[] res = new String[3];
133:            //             if (pat2Match(tests[i], res)) {
134:            //                 System.out.println("'" + res[0] + "' '" + res[1] + "' '" + res[2] + "'");
135:            //             } else {
136:            //                 System.out.println("didn't match");
137:            //             }
138:            //         }
139:            //     }
140:            //     private static final void testPat3() {
141:            //         System.out.println("test pat3");
142:            //         String[] tests = {
143:            //             "",
144:            //             " ",
145:            //             " //#",
146:            //             " /##",
147:            //             "//##",
148:            //             " //##",
149:            //             " //##//",
150:            //             " /////##",
151:            //         };
152:            //         for (int i = 0; i < tests.length; ++i) {
153:            //             System.out.print("pat '" + tests[i] + "' --> ");
154:            //             Matcher m = pat3.matcher(tests[i]);
155:            //             if (m.find()) {
156:            //                 System.out.println("'" + m.group(1) + "'");
157:            //             } else {
158:            //                 System.out.println("didn't match");
159:            //             }
160:            //             System.out.print("dug '" + tests[i] + "' --> ");
161:            //             String match = pat3Match(tests[i]);
162:            //             if (match != null) {
163:            //                 System.out.println("'" + match + "'");
164:            //             } else {
165:            //                 System.out.println("didn't match");
166:            //             }
167:            //         }
168:            //     }
169:
170:            private static final String usage = "Usage:\n"
171:                    + "    CodeMangler [flags] file... dir... @argfile... \n"
172:                    + "-in[dir] path          - root directory of input files, otherwise use current directory\n"
173:                    + "-out[dir] path         - root directory of output files, otherwise use input directory\n"
174:                    + "-s[uffix] string       - suffix of inputfiles to process, otherwise use '.java' (directories only)\n"
175:                    + "-c[lean]               - remove all control flags from code on output (does not proceed if overwriting)\n"
176:                    + "-r[ecurse]             - if present, recursively process subdirectories\n"
177:                    + "-f[orce]               - force reprocessing of files even if timestamp and headers match\n"
178:                    + "-t[imestamp]           - expect/write timestamp in header\n"
179:                    + "-dNAME[=VALUE]         - define NAME with optional value VALUE\n"
180:                    + "  (or -d NAME[=VALUE])\n"
181:                    + "-help                  - print this usage message and exit.\n"
182:                    + "\n"
183:                    + "For file arguments, output '.java' files using the same path/name under the output directory.\n"
184:                    + "For directory arguments, process all files with the defined suffix in the directory.\n"
185:                    + "  (if recursing, do the same for all files recursively under each directory)\n"
186:                    + "For @argfile arguments, read the specified text file (strip the '@'), and process each line of that file as \n"
187:                    + "an argument.\n"
188:                    + "\n"
189:                    + "Directives are one of the following:\n"
190:                    + "  #ifdef, #ifndef, #else, #endif, #if, #elif, #define, #undef\n"
191:                    + "These may optionally be preceeded by whitespace or //.\n"
192:                    + "#if, #elif args are of the form 'key == value' or 'key != value'.\n"
193:                    + "Only exact character match key with value is performed.\n"
194:                    + "#define args are 'key [==] value', the '==' is optional.\n";
195:
196:            CodeMangler(String[] args) {
197:                map = new HashMap();
198:                names = new ArrayList();
199:                suffix = ".java";
200:                clean = false;
201:                timestamp = false;
202:
203:                String inname = null;
204:                String outname = null;
205:                boolean processArgs = true;
206:                String arg = null;
207:                try {
208:                    for (int i = 0; i < args.length; ++i) {
209:                        arg = args[i];
210:                        if ("--".equals(arg)) {
211:                            processArgs = false;
212:                        } else if (processArgs && arg.charAt(0) == '-') {
213:                            if (arg.startsWith("-in")) {
214:                                inname = args[++i];
215:                            } else if (arg.startsWith("-out")) {
216:                                outname = args[++i];
217:                            } else if (arg.startsWith("-d")) {
218:                                String id = arg.substring(2);
219:                                if (id.length() == 0) {
220:                                    id = args[++i];
221:                                }
222:                                String val = "";
223:                                int ix = id.indexOf('=');
224:                                if (ix >= 0) {
225:                                    val = id.substring(ix + 1);
226:                                    id = id.substring(0, ix);
227:                                }
228:                                map.put(id, val);
229:                            } else if (arg.startsWith("-s")) {
230:                                suffix = args[++i];
231:                            } else if (arg.startsWith("-r")) {
232:                                recurse = true;
233:                            } else if (arg.startsWith("-f")) {
234:                                force = true;
235:                            } else if (arg.startsWith("-c")) {
236:                                clean = true;
237:                            } else if (arg.startsWith("-t")) {
238:                                timestamp = true;
239:                            } else if (arg.startsWith("-h")) {
240:                                System.out.print(usage);
241:                                break; // stop before processing arguments, so we will do nothing
242:                            } else if (arg.startsWith("-v")) {
243:                                verbose = true;
244:                            } else {
245:                                System.err
246:                                        .println("Error: unrecognized argument '"
247:                                                + arg + "'");
248:                                System.err.println(usage);
249:                                throw new IllegalArgumentException(arg);
250:                            }
251:                        } else {
252:                            if (arg.charAt(0) == '@') {
253:                                File argfile = new File(arg.substring(1));
254:                                if (argfile.exists() && !argfile.isDirectory()) {
255:                                    try {
256:                                        BufferedReader br = new BufferedReader(
257:                                                new InputStreamReader(
258:                                                        new FileInputStream(
259:                                                                argfile)));
260:                                        ArrayList list = new ArrayList();
261:                                        for (int x = 0; x < args.length; ++x) {
262:                                            list.add(args[x]);
263:                                        }
264:                                        String line;
265:                                        while (null != (line = br.readLine())) {
266:                                            line = line.trim();
267:                                            if (line.length() > 0
268:                                                    && line.charAt(0) != '#') {
269:                                                if (verbose)
270:                                                    System.out
271:                                                            .println("adding argument: "
272:                                                                    + line);
273:                                                list.add(line);
274:                                            }
275:                                        }
276:                                        args = (String[]) list
277:                                                .toArray(new String[list.size()]);
278:                                    } catch (IOException e) {
279:                                        System.err
280:                                                .println("error reading arg file: "
281:                                                        + e);
282:                                    }
283:                                }
284:                            } else {
285:                                names.add(arg);
286:                            }
287:                        }
288:                    }
289:                } catch (IndexOutOfBoundsException e) {
290:                    String msg = "Error: argument '" + arg + "' missing value";
291:                    System.err.println(msg);
292:                    System.err.println(usage);
293:                    throw new IllegalArgumentException(msg);
294:                }
295:
296:                String username = System.getProperty("user.dir");
297:                if (inname == null) {
298:                    inname = username;
299:                } else if (!(inname.startsWith("\\") || inname.startsWith("/"))) {
300:                    inname = username + File.separator + inname;
301:                }
302:                indir = new File(inname);
303:                try {
304:                    indir = indir.getCanonicalFile();
305:                } catch (IOException e) {
306:                    // continue, but most likely we'll fail later
307:                }
308:                if (!indir.exists()) {
309:                    throw new IllegalArgumentException("Input directory '"
310:                            + indir.getAbsolutePath() + "' does not exist.");
311:                } else if (!indir.isDirectory()) {
312:                    throw new IllegalArgumentException("Input path '"
313:                            + indir.getAbsolutePath() + "' is not a directory.");
314:                }
315:                if (verbose)
316:                    System.out.println("indir: " + indir.getAbsolutePath());
317:
318:                if (outname == null) {
319:                    outname = inname;
320:                } else if (!(outname.startsWith("\\") || outname
321:                        .startsWith("/"))) {
322:                    outname = username + File.separator + outname;
323:                }
324:                outdir = new File(outname);
325:                try {
326:                    outdir = outdir.getCanonicalFile();
327:                } catch (IOException e) {
328:                    // continue, but most likely we'll fail later
329:                }
330:                if (!outdir.exists()) {
331:                    throw new IllegalArgumentException("Output directory '"
332:                            + outdir.getAbsolutePath() + "' does not exist.");
333:                } else if (!outdir.isDirectory()) {
334:                    throw new IllegalArgumentException("Output path '"
335:                            + outdir.getAbsolutePath()
336:                            + "' is not a directory.");
337:                }
338:                if (verbose)
339:                    System.out.println("outdir: " + outdir.getAbsolutePath());
340:
341:                if (clean && suffix.equals(".java")) {
342:                    try {
343:                        if (outdir.getCanonicalPath().equals(
344:                                indir.getCanonicalPath())) {
345:                            throw new IllegalArgumentException(
346:                                    "Cannot use 'clean' to overwrite .java files in same directory tree");
347:                        }
348:                    } catch (IOException e) {
349:                        System.err.println("possible overwrite, error: "
350:                                + e.getMessage());
351:                        throw new IllegalArgumentException(
352:                                "Cannot use 'clean' to overrwrite .java files");
353:                    }
354:                }
355:
356:                if (names.isEmpty()) {
357:                    names.add(".");
358:                }
359:
360:                TreeMap sort = new TreeMap(String.CASE_INSENSITIVE_ORDER);
361:                sort.putAll(map);
362:                Iterator iter = sort.entrySet().iterator();
363:                StringBuffer buf = new StringBuffer();
364:                while (iter.hasNext()) {
365:                    Map.Entry e = (Map.Entry) iter.next();
366:                    if (buf.length() > 0) {
367:                        buf.append(", ");
368:                    }
369:                    buf.append(e.getKey());
370:                    String v = (String) e.getValue();
371:                    if (v != null && v.length() > 0) {
372:                        buf.append('=');
373:                        buf.append(v);
374:                    }
375:                }
376:                header = buf.toString();
377:            }
378:
379:            public int run() {
380:                return process("", (String[]) names.toArray(new String[names
381:                        .size()]));
382:            }
383:
384:            public int process(String path, String[] filenames) {
385:                if (verbose)
386:                    System.out.println("path: '" + path + "'");
387:                int count = 0;
388:                for (int i = 0; i < filenames.length; ++i) {
389:                    if (verbose)
390:                        System.out
391:                                .println("name " + i + " of "
392:                                        + filenames.length + ": '"
393:                                        + filenames[i] + "'");
394:                    String name = path + filenames[i];
395:                    File fin = new File(indir, name);
396:                    try {
397:                        fin = fin.getCanonicalFile();
398:                    } catch (IOException e) {
399:                    }
400:                    if (!fin.exists()) {
401:                        System.err.println("File " + fin.getAbsolutePath()
402:                                + " does not exist.");
403:                        continue;
404:                    }
405:                    if (fin.isFile()) {
406:                        if (verbose)
407:                            System.out.println("processing file: '"
408:                                    + fin.getAbsolutePath() + "'");
409:                        String oname;
410:                        int ix = name.lastIndexOf(".");
411:                        if (ix != -1) {
412:                            oname = name.substring(0, ix);
413:                        } else {
414:                            oname = name;
415:                        }
416:                        oname += ".java";
417:                        File fout = new File(outdir, oname);
418:                        if (processFile(fin, fout)) {
419:                            ++count;
420:                        }
421:                    } else if (fin.isDirectory()) {
422:                        if (verbose)
423:                            System.out.println("recursing on directory '"
424:                                    + fin.getAbsolutePath() + "'");
425:                        String npath = ".".equals(name) ? path : path
426:                                + fin.getName() + File.separator;
427:                        count += process(npath, fin.list(filter)); // recursive call
428:                    }
429:                }
430:                return count;
431:            }
432:
433:            private final FilenameFilter filter = new FilenameFilter() {
434:                public boolean accept(File dir, String name) {
435:                    File f = new File(dir, name);
436:                    return (f.isFile() && name.endsWith(suffix))
437:                            || (f.isDirectory() && recurse);
438:                }
439:            };
440:
441:            public boolean processFile(File infile, File outfile) {
442:                File backup = null;
443:
444:                class State {
445:                    int lc;
446:                    String line;
447:                    boolean emit = true;
448:                    boolean tripped;
449:                    private State next;
450:
451:                    public String toString() {
452:                        return "line " + lc + ": '" + line + "' (emit: " + emit
453:                                + " tripped: " + tripped + ")";
454:                    }
455:
456:                    void trip(boolean trip) {
457:                        if (!tripped & trip) {
458:                            tripped = true;
459:                            emit = next != null ? next.emit : true;
460:                        } else {
461:                            emit = false;
462:                        }
463:                    }
464:
465:                    State push(int lc, String line, boolean trip) {
466:                        this .lc = lc;
467:                        this .line = line;
468:                        State ret = new State();
469:                        ret.next = this ;
470:                        ret.emit = this .emit & trip;
471:                        ret.tripped = trip;
472:                        return ret;
473:                    }
474:
475:                    State pop() {
476:                        return next;
477:                    }
478:                }
479:
480:                HashMap oldMap = null;
481:
482:                long outModTime = 0;
483:
484:                try {
485:                    PrintStream outstream = null;
486:                    InputStream instream = new FileInputStream(infile);
487:
488:                    BufferedReader reader = new BufferedReader(
489:                            new InputStreamReader(instream));
490:                    int lc = 0;
491:                    State state = new State();
492:                    String line;
493:                    while ((line = reader.readLine()) != null) {
494:                        if (lc == 0) { // check and write header for output file if needed
495:                            boolean hasHeader = line.startsWith(HEADER_PREFIX);
496:                            if (hasHeader && !force) {
497:                                long expectLastModified = ((infile
498:                                        .lastModified() + 999) / 1000) * 1000;
499:                                String headerline = HEADER_PREFIX
500:                                        + ' '
501:                                        + (timestamp ? String
502:                                                .valueOf(expectLastModified)
503:                                                : "") + ' ' + header;
504:                                headerline = headerline.trim();
505:                                if (line.equals(headerline)) {
506:                                    if (verbose)
507:                                        System.out
508:                                                .println("no changes necessary to "
509:                                                        + infile
510:                                                                .getCanonicalPath());
511:                                    instream.close();
512:                                    return false; // nothing to do
513:                                }
514:                                if (verbose) {
515:                                    System.out
516:                                            .println("  old header:  " + line);
517:                                    System.out.println("  != expected: "
518:                                            + headerline);
519:                                }
520:                            }
521:
522:                            // create output file directory structure
523:                            String outpname = outfile.getParent();
524:                            if (outpname != null) {
525:                                File outp = new File(outpname);
526:                                if (!(outp.exists() || outp.mkdirs())) {
527:                                    System.err
528:                                            .println("could not create directory: '"
529:                                                    + outpname + "'");
530:                                    return false;
531:                                }
532:                            }
533:
534:                            // if we're overwriting, use a temporary file
535:                            if (suffix.equals(".java")) {
536:                                backup = outfile;
537:                                try {
538:                                    outfile = File.createTempFile(outfile
539:                                            .getName(), null, outfile
540:                                            .getParentFile());
541:                                } catch (IOException ex) {
542:                                    System.err.println(ex.getMessage());
543:                                    return false;
544:                                }
545:                            }
546:
547:                            outModTime = ((outfile.lastModified() + 999) / 1000) * 1000; // round up
548:                            outstream = new PrintStream(new FileOutputStream(
549:                                    outfile));
550:                            String headerline = HEADER_PREFIX
551:                                    + ' '
552:                                    + (timestamp ? String.valueOf(outModTime)
553:                                            : "") + ' ' + header;
554:                            headerline = headerline.trim();
555:                            outstream.println(headerline);
556:                            if (verbose)
557:                                System.out.println("header: " + headerline);
558:
559:                            // discard the old header if we had one, otherwise match this line like any other
560:                            if (hasHeader) {
561:                                ++lc; // mark as having read a line so we never reexecute this block
562:                                continue;
563:                            }
564:                        }
565:
566:                        String[] res = new String[3];
567:                        if (patMatch(line, res)) {
568:                            String lead = res[0];
569:                            String key = res[1];
570:                            String val = res[2];
571:
572:                            //                 Matcher m = pat.matcher(line);
573:                            //                 if (m.find()) {
574:                            //                     String lead = m.group(1);
575:                            //                     String key = m.group(2).toLowerCase().trim();
576:                            //                     String val = m.group(3).trim();
577:
578:                            if (verbose)
579:                                System.out.println("directive: " + line
580:                                        + " key: '" + key + "' val: '" + val
581:                                        + "' " + state);
582:                            if (key.equals("ifdef")) {
583:                                state = state.push(lc, line,
584:                                        map.get(val) != null);
585:                            } else if (key.equals("ifndef")) {
586:                                state = state.push(lc, line,
587:                                        map.get(val) == null);
588:                            } else if (key.equals("else")) {
589:                                state.trip(true);
590:                            } else if (key.equals("endif")) {
591:                                state = state.pop();
592:                            } else if (key.equals("undef")) {
593:                                if (state.emit) {
594:                                    if (oldMap == null) {
595:                                        oldMap = (HashMap) map.clone();
596:                                    }
597:                                    map.remove(val);
598:                                }
599:                            } else { // #define, #if, #elif
600:                                if (pat2Match(val, res)) {
601:                                    String key2 = res[0];
602:                                    boolean neq = "!=".equals(res[1]); // optional
603:                                    String val2 = res[2];
604:
605:                                    //                         Matcher m2 = pat2.matcher(val);
606:                                    //                         if (m2.find()) {
607:                                    //                             String key2 = m2.group(1).trim();
608:                                    //                             boolean neq = "!=".equals(m2.group(2)); // optional
609:                                    //                             String val2 = m2.group(3).trim();
610:                                    if (verbose)
611:                                        System.out.println("val2: '" + val2
612:                                                + "' neq: '" + neq
613:                                                + "' key2: '" + key2 + "'");
614:                                    if (key.equals("if")) {
615:                                        state = state.push(lc, line, val2
616:                                                .equals(map.get(key2)) != neq);
617:                                    } else if (key.equals("elif")) {
618:                                        state
619:                                                .trip(val2
620:                                                        .equals(map.get(key2)) != neq);
621:                                    } else if (key.equals("define")) {
622:                                        if (state.emit) {
623:                                            if (oldMap == null) {
624:                                                oldMap = (HashMap) map.clone();
625:                                            }
626:                                            map.put(key2, val2);
627:                                        }
628:                                    }
629:                                }
630:                            }
631:                            if (!clean) {
632:                                lc++;
633:                                if (!lead.equals("//")) {
634:                                    outstream.print("//");
635:                                    line = line.substring(lead.length());
636:                                }
637:                                outstream.println(line);
638:                            }
639:                            continue;
640:                        }
641:
642:                        lc++;
643:                        String found = pat3Match(line);
644:                        boolean hasIgnore = found != null;
645:                        if (state.emit == hasIgnore) {
646:                            if (state.emit) {
647:                                line = line.substring(found.length());
648:                            } else {
649:                                line = IGNORE_PREFIX + line;
650:                            }
651:                        } else if (hasIgnore && !found.equals(IGNORE_PREFIX)) {
652:                            line = IGNORE_PREFIX
653:                                    + line.substring(found.length());
654:                        }
655:                        //                 m = pat3.matcher(line);
656:                        //                 boolean hasIgnore = m.find();
657:                        //                 if (state.emit == hasIgnore) {
658:                        //                     if (state.emit) {
659:                        //                         line = line.substring(m.group(1).length());
660:                        //                     } else {
661:                        //                         line = IGNORE_PREFIX + line;
662:                        //                     }
663:                        //                 } else if (hasIgnore && !m.group(1).equals(IGNORE_PREFIX)) {
664:                        //                     line = IGNORE_PREFIX + line.substring(m.group(1).length());
665:                        //                 }
666:                        if (!clean || state.emit) {
667:                            outstream.println(line);
668:                        }
669:                    }
670:
671:                    state = state.pop();
672:                    if (state != null) {
673:                        System.err.println("Error: unclosed directive(s):");
674:                        do {
675:                            System.err.println(state);
676:                        } while ((state = state.pop()) != null);
677:                        System.err.println(" in file: "
678:                                + outfile.getCanonicalPath());
679:                        if (oldMap != null) {
680:                            map = oldMap;
681:                        }
682:                        outstream.close();
683:                        return false;
684:                    }
685:
686:                    outstream.close();
687:                    instream.close();
688:
689:                    if (backup != null) {
690:                        if (backup.exists()) {
691:                            backup.delete();
692:                        }
693:                        outfile.renameTo(backup);
694:                    }
695:
696:                    if (timestamp) {
697:                        outfile.setLastModified(outModTime); // synch with timestamp
698:                    }
699:
700:                    if (oldMap != null) {
701:                        map = oldMap;
702:                    }
703:                } catch (IOException e) {
704:                    System.err.println(e);
705:                    return false;
706:                }
707:                return true;
708:            }
709:
710:            /**
711:             * Perform same operation as matching on pat.  on exit
712:             * leadKeyValue contains the three strings lead, key, and value.
713:             * 'lead' is the portion before the #ifdef directive.  'key' is
714:             * the directive.  'value' is the portion after the directive.  if
715:             * there is a match, return true, else return false.
716:             */
717:            static boolean patMatch(String line, String[] leadKeyValue) {
718:                //       final Pattern pat = Pattern.compile(
719:                //         "(?i)^(\\s*(?://+)??\\s*)#(ifdef\\s|ifndef\\s|else|endif|undef\\s|define\\s|if\\s|elif\\s)\\s*(.*)$");
720:
721:                if (line.length() == 0) {
722:                    return false;
723:                }
724:                if (!line.endsWith("\n")) {
725:                    line = line + '\n';
726:                }
727:                int mark = 0;
728:                int state = 0;
729:                loop: for (int i = 0; i < line.length(); ++i) {
730:                    char c = line.charAt(i);
731:                    switch (state) {
732:                    case 0: // at start of line, haven't seen anything but whitespace yet
733:                        if (c == ' ' || c == '\t' || c == '\r')
734:                            continue;
735:                        if (c == '/') {
736:                            state = 1;
737:                            continue;
738:                        }
739:                        if (c == '#') {
740:                            state = 4;
741:                            continue;
742:                        }
743:                        return false;
744:                    case 1: // have seen a single slash after start of line
745:                        if (c == '/') {
746:                            state = 2;
747:                            continue;
748:                        }
749:                        return false;
750:                    case 2: // have seen two or more slashes
751:                        if (c == '/')
752:                            continue;
753:                        if (c == ' ' || c == '\t' || c == '\r') {
754:                            state = 3;
755:                            continue;
756:                        }
757:                        if (c == '#') {
758:                            state = 4;
759:                            continue;
760:                        }
761:                        return false;
762:                    case 3: // have seen a space after two or more slashes
763:                        if (c == ' ' || c == '\t' || c == '\r')
764:                            continue;
765:                        if (c == '#') {
766:                            state = 4;
767:                            continue;
768:                        }
769:                        return false;
770:                    case 4: // have seen a '#' 
771:                        leadKeyValue[0] = line.substring(mark, i - 1);
772:                        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
773:                            mark = i;
774:                            state = 5;
775:                            continue;
776:                        }
777:                        return false;
778:                    case 5: // an ascii char followed the '#'
779:                        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
780:                            continue;
781:                        if (c == ' ' || c == '\t' || c == '\n') {
782:                            String key = line.substring(mark, i).toLowerCase();
783:                            if (key.equals("ifdef") || key.equals("ifndef")
784:                                    || key.equals("else")
785:                                    || key.equals("endif")
786:                                    || key.equals("undef")
787:                                    || key.equals("define") || key.equals("if")
788:                                    || key.equals("elif")) {
789:                                leadKeyValue[1] = key;
790:                                mark = i;
791:                                state = 6;
792:                                break loop;
793:                            }
794:                        }
795:                        return false;
796:                    default:
797:                        throw new IllegalStateException();
798:                    }
799:                }
800:                if (state == 6) {
801:                    leadKeyValue[2] = line.substring(mark, line.length())
802:                            .trim();
803:                    return true;
804:                }
805:                return false; // never reached, does the compiler know this?
806:            }
807:
808:            /**
809:             * Perform same operation as matching on pat2.  on exit
810:             * keyRelValue contains the three strings key, rel, and value.
811:             * 'key' is the portion before the relation (or final word).  'rel' is
812:             * the relation, if present, either == or !=.  'value' is the final
813:             * word.  if there is a match, return true, else return false.
814:             */
815:            static boolean pat2Match(String line, String[] keyRelVal) {
816:                //       final Pattern pat2 = Pattern.compile("([^=!]+)\\s*([!=]?=)??\\s*(\\w+)");
817:                // hmmm, this pattern doesn't look right.  a pattern consisting of 'abcd' should
818:                // return {"abcd", "", ""} but it looks like it returns {"", "", "abcd"}.
819:
820:                if (line.length() == 0) {
821:                    return false;
822:                }
823:                keyRelVal[0] = keyRelVal[1] = keyRelVal[2] = "";
824:                int mark = 0;
825:                int state = 0;
826:                loop: for (int i = 0; i < line.length(); ++i) {
827:                    char c = line.charAt(i);
828:                    switch (state) {
829:                    case 0: // saw beginning or space, no rel yet
830:                        if (c == ' ' || c == '\t' || c == '\n') {
831:                            continue;
832:                        }
833:                        if ((c == '!' || c == '=')) {
834:                            return false;
835:                        }
836:                        state = 1;
837:                        continue;
838:                    case 1: // saw start of a word
839:                        if (c == ' ' || c == '\t') {
840:                            state = 2;
841:                        } else if (c == '!' || c == '=') {
842:                            state = 3;
843:                        }
844:                        continue;
845:                    case 2: // saw end of word, and space
846:                        if (c == ' ' || c == '\t') {
847:                            continue;
848:                        } else if (c == '!' || c == '=') {
849:                            state = 3;
850:                            continue;
851:                        }
852:                        keyRelVal[0] = line.substring(0, i - 1).trim();
853:                        mark = i;
854:                        state = 4;
855:                        break loop;
856:                    case 3: // saw end of word, and '!' or '='
857:                        if (c == '=') {
858:                            keyRelVal[0] = line.substring(0, i - 1).trim();
859:                            keyRelVal[1] = line.substring(i - 1, i + 1);
860:                            mark = i + 1;
861:                            state = 4;
862:                            break loop;
863:                        }
864:                        return false;
865:                    default:
866:                        break;
867:                    }
868:                }
869:                switch (state) {
870:                case 0:
871:                    return false; // found nothing
872:                case 1:
873:                case 2:
874:                    keyRelVal[0] = line.trim();
875:                    break; // found only a word
876:                case 3:
877:                    return false; // found a word and '!' or '=" then end of line, incomplete
878:                case 4:
879:                    keyRelVal[2] = line.substring(mark).trim();
880:                    break; // found a word, possible rel, and who knows what
881:                default:
882:                    throw new IllegalStateException();
883:                }
884:                return true;
885:            }
886:
887:            static String pat3Match(String line) {
888:                int state = 0;
889:                loop: for (int i = 0; i < line.length(); ++i) {
890:                    char c = line.charAt(i);
891:                    switch (state) {
892:                    case 0:
893:                        if (c == ' ' || c == '\t')
894:                            continue;
895:                        if (c == '/') {
896:                            state = 1;
897:                            continue;
898:                        }
899:                        break loop;
900:                    case 1:
901:                        if (c == '/') {
902:                            state = 2;
903:                            continue;
904:                        }
905:                        break loop;
906:                    case 2:
907:                        if (c == '#') {
908:                            state = 3;
909:                            continue;
910:                        }
911:                        break loop;
912:                    case 3:
913:                        if (c == '#')
914:                            return line.substring(0, i + 1);
915:                        break loop;
916:                    default:
917:                        break loop;
918:                    }
919:                }
920:                return null;
921:            }
922:
923:            //       final Pattern pat3 = Pattern.compile("^(\\s*//##).*");
924:
925:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.