1 package annotations.tools;
2 
3 /*>>>
4 import org.checkerframework.checker.nullness.qual.*;
5 */
6 
7 import java.io.*;
8 
9 import annotations.el.AScene;
10 import annotations.el.DefException;
11 import annotations.io.IndexFileParser;
12 import annotations.io.IndexFileWriter;
13 import annotations.io.JavapParser;
14 import annotations.io.classfile.ClassFileReader;
15 import annotations.io.classfile.ClassFileWriter;
16 import plume.FileIOException;
17 
18 /** Concatenates multiple descriptions of annotations into a single one. */
19 public class Anncat {
20     private static void usage() {
21         System.err.print(
22                 "anncat, part of the Annotation File Utilities\n" +
23                 "(https://checkerframework.org/annotation-file-utilities/)\n" +
24                 "usage: anncat <inspec>* [ --out <outspec> ], where:\n" +
25                 "    <inspec> ::=\n" +
26                 "        ( --javap <in.javap> )\n" +
27                 "        | ( --index <in.jaif> )\n" +
28                 "        | ( --class <in.class> )\n" +
29                 "    <outspec> ::=\n" +
30                 "        ( --index <out.jaif> )\n" +
31                 "        | ( --class [ --overwrite ] <orig.class> [ --to <out.class> ] )\n" +
32         "If outspec is omitted, default is index file to stdout.\n");
33     }
34 
35     private static void usageAssert(boolean b) {
36         if (!b) {
37             System.err.println("*** Usage error ***");
38             usage();
39             System.exit(3);
40         }
41     }
42 
43     public static void main(String[] args) {
44         usageAssert(0 < args.length);
45         if (args[0].equals("--help")) {
46             usage();
47             System.exit(0);
48         }
49 
50         try {
51 
52             int idx = 0;
53 
54             /*@NonNull*/ AScene theScene =
55                 new AScene();
56 
57             // Read the scene
58             while (idx < args.length && !args[idx].equals("--out")) {
59                 if (args[idx].equals("--javap")) {
60                     idx++;
61                     usageAssert(idx < args.length);
62                     String infile = args[idx++];
63                     System.out.println("Reading javap file " + infile + "...");
64                     JavapParser.parse(infile, theScene);
65                     System.out.println("Finished.");
66                 } else if (args[idx].equals("--index")) {
67                     idx++;
68                     usageAssert(idx < args.length);
69                     String infile = args[idx++];
70                     System.err.println("Reading index file " + infile + "...");
71                     IndexFileParser.parseFile(infile, theScene);
72                     System.err.println("Finished.");
73                 } else if (args[idx].equals("--class")) {
74                     idx++;
75                     usageAssert(idx < args.length);
76                     String infile = args[idx++];
77                     System.err.println("Reading class file " + infile + "...");
78                     ClassFileReader.read(theScene, infile);
79                     System.err.println("Finished.");
80                 } else {
81                     usageAssert(false);
82                 }
83             }
84 
85             // Write the scene
86             if (idx == args.length) {
87                 System.err.println("Writing index file to standard output...");
88                 IndexFileWriter.write(theScene, new OutputStreamWriter(System.out));
89                 System.err.println("Finished.");
90             } else {
91                 idx++;
92                 usageAssert(idx < args.length);
93                 if (args[idx].equals("--index")) {
94                     idx++;
95                     usageAssert(idx < args.length);
96                     String outfile = args[idx];
97                     idx++;
98                     usageAssert(idx == args.length);
99                     System.err.println("Writing index file to " + outfile + "...");
100                     IndexFileWriter.write(theScene, new FileWriter(outfile));
101                     System.err.println("Finished.");
102                 } else if (args[idx].equals("--class")) {
103                     idx++;
104                     usageAssert(idx < args.length);
105                     boolean overwrite;
106                     if (args[idx].equals("--overwrite")) {
107                         System.err.println("Overwrite mode enabled.");
108                         overwrite = true;
109                         idx++;
110                         usageAssert(idx < args.length);
111                     } else {
112                         overwrite = false;
113                     }
114                     String origfile = args[idx];
115                     idx++;
116                     if (idx < args.length) {
117                         usageAssert(args[idx].equals("--to"));
118                         idx++;
119                         usageAssert(idx < args.length);
120                         String outfile = args[idx];
121                         idx++;
122                         usageAssert(idx == args.length);
123                         System.err.println("Reading original class file " + origfile);
124                         System.err.println("and writing annotated version to " + outfile + "...");
125                         ClassFileWriter.insert(theScene, new FileInputStream(origfile), new FileOutputStream(outfile), overwrite);
126                         System.err.println("Finished.");
127                     } else {
128                         System.err.println("Rewriting class file " + origfile + " with annotations...");
129                         ClassFileWriter.insert(theScene, origfile, overwrite);
130                         System.err.println("Finished.");
131                     }
132                 } else {
133                     usageAssert(false);
134                 }
135             }
136 
137         } catch (FileIOException e) {
138             e.printStackTrace(System.err);
139             System.exit(1);
140         } catch (IOException e) {
141             e.printStackTrace(System.err);
142             System.exit(2);
143         } catch (DefException e) {
144             e.printStackTrace(System.err);
145             System.exit(1);
146         }
147         System.exit(0);
148     }
149 }
150