jpayne@68
|
1 package shared;
|
jpayne@68
|
2
|
jpayne@68
|
3 import java.io.FileNotFoundException;
|
jpayne@68
|
4 import java.io.PrintStream;
|
jpayne@68
|
5 import java.util.ArrayList;
|
jpayne@68
|
6 import java.util.Arrays;
|
jpayne@68
|
7
|
jpayne@68
|
8 import fileIO.ByteFile1;
|
jpayne@68
|
9 import json.JsonObject;
|
jpayne@68
|
10 import stream.NullOutputStream;
|
jpayne@68
|
11
|
jpayne@68
|
12 /**
|
jpayne@68
|
13 * Pre-parses the command line to handle:
|
jpayne@68
|
14 * Leading hyphens
|
jpayne@68
|
15 * Java flags
|
jpayne@68
|
16 * Output stream redirection
|
jpayne@68
|
17 * Help/version information
|
jpayne@68
|
18 *
|
jpayne@68
|
19 * @author Brian Bushnell
|
jpayne@68
|
20 * @date November 28, 2017
|
jpayne@68
|
21 *
|
jpayne@68
|
22 */
|
jpayne@68
|
23 public class PreParser {
|
jpayne@68
|
24
|
jpayne@68
|
25 /**
|
jpayne@68
|
26 * Auxiliary constructor.
|
jpayne@68
|
27 * @param args Command line arguments
|
jpayne@68
|
28 * @param c Class object of the caller
|
jpayne@68
|
29 * @param printVersion True if the BBTools version should be printed to the screen
|
jpayne@68
|
30 */
|
jpayne@68
|
31 public PreParser(final String[] args_, final Class<?> c, boolean printVersion){
|
jpayne@68
|
32 this(args_, System.err, c, printVersion, true, true);
|
jpayne@68
|
33 }
|
jpayne@68
|
34
|
jpayne@68
|
35 /**
|
jpayne@68
|
36 * Auxiliary constructor.
|
jpayne@68
|
37 * @param args Command line arguments
|
jpayne@68
|
38 * @param defaultPrintStream Print stream that will be used if not overridden
|
jpayne@68
|
39 * @param c Class object of the caller
|
jpayne@68
|
40 * @param printVersion True if the BBTools version should be printed to the screen
|
jpayne@68
|
41 */
|
jpayne@68
|
42 public PreParser(final String[] args_, PrintStream defaultPrintStream, final Class<?> c, boolean printVersion){
|
jpayne@68
|
43 this(args_, defaultPrintStream, c, printVersion, true, true);
|
jpayne@68
|
44 }
|
jpayne@68
|
45
|
jpayne@68
|
46 /**
|
jpayne@68
|
47 * Primary constructor.
|
jpayne@68
|
48 * @param args0 Command line arguments
|
jpayne@68
|
49 * @param defaultPrintStream Print stream that will be used if not overridden
|
jpayne@68
|
50 * @param c Class object of the caller
|
jpayne@68
|
51 * @param printVersion True if the BBTools version should be printed to the screen
|
jpayne@68
|
52 * @param removeKnown Remove parameters from args that are parsed here
|
jpayne@68
|
53 * @param autoExit Exit if there is a version or help flag
|
jpayne@68
|
54 */
|
jpayne@68
|
55 public PreParser(final String[] args0, PrintStream defaultPrintStream, final Class<?> c, boolean printVersion, boolean removeKnown, boolean autoExit){
|
jpayne@68
|
56 original=args0;
|
jpayne@68
|
57 if(Shared.COMMAND_LINE==null){Shared.COMMAND_LINE=(original==null ? null : original.clone());}
|
jpayne@68
|
58 if(Shared.mainClass==null){Shared.mainClass=c;}
|
jpayne@68
|
59
|
jpayne@68
|
60 Parser.parseHelp(args0, autoExit);
|
jpayne@68
|
61
|
jpayne@68
|
62 String[] args=Parser.parseConfig(args0);
|
jpayne@68
|
63 this.config=(args!=args0);
|
jpayne@68
|
64
|
jpayne@68
|
65 final ArrayList<String> unknown=new ArrayList<String>(args.length);
|
jpayne@68
|
66 int removed=0, hyphens=0;
|
jpayne@68
|
67
|
jpayne@68
|
68 PrintStream outstream=((defaultPrintStream == null) ? System.err : defaultPrintStream);
|
jpayne@68
|
69 boolean help=false, jflag=false, json=false;
|
jpayne@68
|
70
|
jpayne@68
|
71 for(int i=0; i<args.length; i++){
|
jpayne@68
|
72 String s=args[i];
|
jpayne@68
|
73 boolean remove=false;
|
jpayne@68
|
74 if(Parser.isJavaFlag(s)){
|
jpayne@68
|
75 jflag=true;
|
jpayne@68
|
76 remove=true;
|
jpayne@68
|
77 }else if(s==null){
|
jpayne@68
|
78 remove=true;
|
jpayne@68
|
79 }else{
|
jpayne@68
|
80
|
jpayne@68
|
81 // while(a.charAt(0)=='-' && (a.indexOf('.')<0 || i>1 || !new File(a).exists())){a=a.substring(1);} //Another possibility
|
jpayne@68
|
82
|
jpayne@68
|
83 if(s.length()>0 && s.charAt(0)=='-'){
|
jpayne@68
|
84 int cnt=1;
|
jpayne@68
|
85 while(cnt<s.length() && s.charAt(cnt)=='-'){cnt++;}
|
jpayne@68
|
86 s=s.substring(cnt);
|
jpayne@68
|
87 hyphens+=cnt;
|
jpayne@68
|
88 args[i]=s;//Note that this mutates the original. Moral: Don't use hyphens.
|
jpayne@68
|
89 }
|
jpayne@68
|
90
|
jpayne@68
|
91 final String[] split=s.split("=");
|
jpayne@68
|
92 assert(split.length<3) : "To many '=' signs: "+s;
|
jpayne@68
|
93 assert(split!=null && split.length>0) : "Please do not put spaces around = symbols.\nSyntax is 'arg=value' with no spaces.";
|
jpayne@68
|
94 final String a=split[0].toLowerCase();
|
jpayne@68
|
95 String b=split.length>1 ? split[1] : null;
|
jpayne@68
|
96 if(b==null){
|
jpayne@68
|
97 //do nothing
|
jpayne@68
|
98 }else if("null".equalsIgnoreCase(b)){//Replace "null" with nothing
|
jpayne@68
|
99 b=null;
|
jpayne@68
|
100 args[i]=s=(a+"=");
|
jpayne@68
|
101 }
|
jpayne@68
|
102
|
jpayne@68
|
103 if(a.equals("outstream")){
|
jpayne@68
|
104 outstream=parseOutstream(b);
|
jpayne@68
|
105 remove=removeKnown;
|
jpayne@68
|
106 }else if(a.equals("json")){
|
jpayne@68
|
107 json=Parse.parseBoolean(b);
|
jpayne@68
|
108 }else if(a.equals("silent")){
|
jpayne@68
|
109 silent=Parse.parseBoolean(b);
|
jpayne@68
|
110 }else if(a.equals("printexecuting")){
|
jpayne@68
|
111 printExecuting=Parse.parseBoolean(b);
|
jpayne@68
|
112 remove=true;
|
jpayne@68
|
113 }else if(a.equals("metadatafile")){
|
jpayne@68
|
114 MetadataWriter.fnameStatic=b;
|
jpayne@68
|
115 remove=true;
|
jpayne@68
|
116 }else if(a.equals("bufferbf") || a.equals("bufferbf1")){//for testing
|
jpayne@68
|
117 ByteFile1.BUFFERED=Parse.parseBoolean(b);
|
jpayne@68
|
118 remove=true;
|
jpayne@68
|
119 }
|
jpayne@68
|
120 }
|
jpayne@68
|
121
|
jpayne@68
|
122 if(remove){removed++;}
|
jpayne@68
|
123 else{unknown.add(s);}
|
jpayne@68
|
124 }
|
jpayne@68
|
125 this.args=(removed==0 ? args : unknown.toArray(new String[0]));
|
jpayne@68
|
126 this.outstream=outstream;
|
jpayne@68
|
127 this.help=help;
|
jpayne@68
|
128 this.jflag=jflag;
|
jpayne@68
|
129 this.hyphens=hyphens;
|
jpayne@68
|
130 this.json=json;
|
jpayne@68
|
131
|
jpayne@68
|
132 if(json){
|
jpayne@68
|
133 jsonObject=new JsonObject();
|
jpayne@68
|
134 if(c!=null && printExecuting){jsonObject.add("commandLine", c.getName()+" "+Arrays.toString(original));}
|
jpayne@68
|
135 if(printVersion){jsonObject.add("version", Shared.BBMAP_VERSION_STRING);}
|
jpayne@68
|
136 jsonObject.add("memory", Shared.memTotal());
|
jpayne@68
|
137 jsonObject.add("assertions", Shared.EA());
|
jpayne@68
|
138 jsonObject.add("javaVersion", Shared.javaVersion);
|
jpayne@68
|
139 jsonObject.add("JVM_args", Shared.JVM_ARGS());
|
jpayne@68
|
140 }else if(!silent){
|
jpayne@68
|
141 if(c!=null && printExecuting){outstream.println("Executing "+c.getName()+" "+Arrays.toString(original));}
|
jpayne@68
|
142 if(printVersion){outstream.println("Version "+Shared.BBMAP_VERSION_STRING );}
|
jpayne@68
|
143 if(c!=null || printVersion){outstream.println();}
|
jpayne@68
|
144 }
|
jpayne@68
|
145 }
|
jpayne@68
|
146
|
jpayne@68
|
147 public static boolean isAmino(String[] args){
|
jpayne@68
|
148 boolean amino=false;
|
jpayne@68
|
149 for(String arg : args){
|
jpayne@68
|
150 if(arg!=null && arg.startsWith("amino")){
|
jpayne@68
|
151 final String[] split=arg.split("=");
|
jpayne@68
|
152 assert(split.length<3) : "To many '=' signs: "+arg;
|
jpayne@68
|
153 final String a=split[0].toLowerCase();
|
jpayne@68
|
154 String b=split.length>1 ? split[1] : null;
|
jpayne@68
|
155 if(a.equals("amino")){amino=Parse.parseBoolean(b);}
|
jpayne@68
|
156 }
|
jpayne@68
|
157 }
|
jpayne@68
|
158 return amino;
|
jpayne@68
|
159 }
|
jpayne@68
|
160
|
jpayne@68
|
161 public static int stripHyphens(String[] args){
|
jpayne@68
|
162 int stripped=0;
|
jpayne@68
|
163 for(int i=0; i<args.length; i++){
|
jpayne@68
|
164 String arg=args[i];
|
jpayne@68
|
165 if(Parser.isJavaFlag(arg)){
|
jpayne@68
|
166 //Do nothing
|
jpayne@68
|
167 }else if(arg.length()>0 && arg.charAt(0)=='-'){
|
jpayne@68
|
168 int cnt=1;
|
jpayne@68
|
169 while(cnt<arg.length() && arg.charAt(cnt)=='-'){cnt++;}
|
jpayne@68
|
170 arg=arg.substring(cnt);
|
jpayne@68
|
171 stripped+=cnt;
|
jpayne@68
|
172 }
|
jpayne@68
|
173 }
|
jpayne@68
|
174 return stripped;
|
jpayne@68
|
175 }
|
jpayne@68
|
176
|
jpayne@68
|
177 private static PrintStream parseOutstream(final String b) {
|
jpayne@68
|
178
|
jpayne@68
|
179 try {
|
jpayne@68
|
180 if(b==null || b.equalsIgnoreCase("null")){return new PrintStream(new NullOutputStream());}
|
jpayne@68
|
181 else if(b.equalsIgnoreCase("stdout") || b.startsWith("stdout.") || b.equals("System.out") || b.equalsIgnoreCase("sysout")){return System.out;}
|
jpayne@68
|
182 else if(b.equalsIgnoreCase("stderr") || b.startsWith("stderr.") || b.equals("System.err")){return System.err;}
|
jpayne@68
|
183 else{return new PrintStream(b);}
|
jpayne@68
|
184 } catch (FileNotFoundException e) {
|
jpayne@68
|
185 e.printStackTrace();
|
jpayne@68
|
186 }
|
jpayne@68
|
187 KillSwitch.kill("Unable to process argument outstream="+b);
|
jpayne@68
|
188 return null; //Unreachable
|
jpayne@68
|
189 }
|
jpayne@68
|
190
|
jpayne@68
|
191 public final String[] original;
|
jpayne@68
|
192 public final String[] args;
|
jpayne@68
|
193 public final PrintStream outstream;
|
jpayne@68
|
194 public final boolean help;
|
jpayne@68
|
195 public final boolean config;
|
jpayne@68
|
196 public final boolean jflag;
|
jpayne@68
|
197 public final boolean json;
|
jpayne@68
|
198 public final int hyphens;
|
jpayne@68
|
199 public JsonObject jsonObject;
|
jpayne@68
|
200
|
jpayne@68
|
201 public static boolean printExecuting=true;
|
jpayne@68
|
202 public static boolean silent=false;
|
jpayne@68
|
203
|
jpayne@68
|
204 }
|