Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// Copyright 2011 The Whiley Project Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package wycc.util;
import java.io.File;
import java.io.PrintStream;
import java.util.*;
/**
* A small utility for parsing command-line options. It helps to take some of
* the hassle out of building the front-end of a Whiley compiler.
*
* @author David J. Pearce
*
*/
public final class OptArg {
/**
* The long form of the option. (e.g. for "-version", the long form is
* "version")
*/
public final String option;
/**
* The short form of the option. (e.g. for "-version", the short form might
* be "v" as in "-v")
*/
public final String shortForm;
/**
* The kind of argument accepted by this option (if any).
*/
public final Kind argument;
/**
* A description of the option. This is used when printing out "usage"
* information.
*/
public final String description;
/**
* A default value for the option (assuming it accepts an argument). This
* may be null if there is no default value.
*/
public final Object defaultValue;
/**
* Construct an option object which does not accept an argument.
*
* @param option
* @param argument
* @param description
* @param defaultValue
*/
public OptArg(String option,String description) {
this.option = option;
this.shortForm = null;
this.argument = null;
this.description = description;
this.defaultValue = null;
}
/**
* Construct an option object with a short form which does not accept an argument.
*
* @param option
* @param shortForm
* @param argument
* @param description
* @param defaultValue
*/
public OptArg(String option,String shortForm, String description) {
this.option = option;
this.shortForm = shortForm;
this.argument = null;
this.description = description;
this.defaultValue = null;
}
/**
* Construct an option object which accepts an argument.
*
* @param option
* @param argument
* @param description
* @param defaultValue
*/
public OptArg(String option, Kind argument,
String description) {
this.option = option;
this.shortForm = null;
this.argument = argument;
this.description = description;
this.defaultValue = null;
}
/**
* Construct an option object with a short form which accepts an argument.
*
* @param option
* @param shortForm
* @param argument
* @param description
* @param defaultValue
*/
public OptArg(String option, String shortForm, Kind argument,
String description) {
this.option = option;
this.shortForm = shortForm;
this.argument = argument;
this.description = description;
this.defaultValue = null;
}
/**
* Construct an option object which accepts an argument and has a default value.
*
* @param option
* @param argument
* @param description
* @param defaultValue
*/
public OptArg(String option, Kind argument,
String description, Object defaultValue) {
this.option = option;
this.shortForm = null;
this.argument = argument;
this.description = description;
this.defaultValue = defaultValue;
}
/**
* Construct an option object with a short form which accepts an argument and has a default value.
*
* @param option
* @param argument
* @param description
* @param defaultValue
*/
public OptArg(String option, String shortForm, Kind argument,
String description, Object defaultValue) {
this.option = option;
this.shortForm = shortForm;
this.argument = argument;
this.description = description;
this.defaultValue = defaultValue;
}
interface Kind {
void process(String arg, String option, Map options);
}
public final static STRING STRING = new STRING();
public final static STRINGARRAY STRINGARRAY = new STRINGARRAY();
public final static INT INT = new INT();
public final static LONG LONG = new LONG();
public final static FILE FILE = new FILE();
public final static FILEDIR FILEDIR = new FILEDIR();
public final static FILELIST FILELIST = new FILELIST();
public final static OPTIONSMAP OPTIONSMAP = new OPTIONSMAP();
private static final class STRING implements Kind {
@Override
public void process(String arg, String option, Map options) {
options.put(arg,option);
}
@Override
public String toString() {
return "";
}
}
private static final class STRINGARRAY implements Kind {
@Override
public void process(String arg, String option, Map options) {
String[] array = option.split(":");
options.put(arg,array);
}
@Override
public String toString() {
return "";
}
}
private static final class INT implements Kind {
@Override
public void process(String arg, String option, Map options) {
options.put(arg,Integer.parseInt(option));
}
@Override
public String toString() {
return "";
}
}
private static final class LONG implements Kind {
@Override
public void process(String arg, String option, Map options) {
options.put(arg,Long.parseLong(option));
}
@Override
public String toString() {
return "";
}
}
private static final class FILE implements Kind {
@Override
public void process(String arg, String option,
Map options) {
options.put(arg, new File(option));
}
@Override
public String toString() {
return "";
}
}
private static final class FILEDIR implements Kind {
@Override
public void process(String arg, String option,
Map options) {
File dir = new File(option);
if(!dir.isDirectory()) {
throw new IllegalArgumentException("invalid path --- " + arg);
}
options.put(arg, dir);
}
@Override
public String toString() {
return "";
}
}
private static final class FILELIST implements Kind {
@Override
public void process(String arg, String option, Map options) {
ArrayList rs = new ArrayList<>();
for(String r : option.split(File.pathSeparator)) {
rs.add(new File(r));
}
options.put(arg, rs);
}
@Override
public String toString() {
return "";
}
}
private static final class OPTIONSMAP implements Kind {
@Override
public void process(String arg, String option, Map options) {
String[] name = option.split(":");
Map config = Collections.EMPTY_MAP;
if (name.length > 1) {
config = splitConfig(name[1]);
}
Map> values = (Map>) options.get(arg);
if(values == null) {
values = new HashMap<>();
options.put(arg, values);
}
Map attributes = values.get(name[0]);
if(attributes == null) {
values.put(name[0], config);
} else {
attributes.putAll(config);
}
}
@Override
public String toString() {
return "name:[attribute=value]+";
}
}
/**
* Parse options from the list of arguments, removing those which are
* recognised. Anything which is not recognised is left as is.
*
* @param args
* --- the list of argument strings. This is modified by removing
* those which are processed.
* @param options
* --- the list of OptArg defining which options should be
* processed
* @throws --- a RuntimeException if an unrecognised option is
* encountered (that is, a token starting with '-')..
*/
public static Map parseOptions(List args, OptArg... options) {
HashMap result = new HashMap<>();
HashMap soptmap = new HashMap<>();
HashMap loptmap = new HashMap<>();
for(OptArg opt : options) {
if(opt.defaultValue != null) {
result.put(opt.option, opt.defaultValue);
}
loptmap.put(opt.option, opt);
soptmap.put(opt.shortForm, opt);
}
Iterator iter = args.iterator();
while(iter.hasNext()) {
String arg = iter.next();
OptArg opt;
String param;
if (arg.startsWith("--")) {
Object[] p = parseLongForm(arg, iter, loptmap);
opt = (OptArg) p[0];
param = (String) p[1];
} else if(arg.startsWith("-")) {
Object[] p = parseShortForm(arg, iter, soptmap);
opt = (OptArg) p[0];
param = (String) p[1];
} else {
continue;
}
// Process option
Kind k = opt.argument;
if (k != null) {
k.process(opt.option, param, result);
} else {
result.put(opt.option, null);
}
}
return result;
}
private static Object[] parseLongForm(String arg, Iterator iter, Map opts) {
arg = arg.substring(2,arg.length());
String[] _args = arg.split("=");
OptArg opt = opts.get(_args[0]);
String param;
if(opt != null) {
// matched
iter.remove(); // remove option from args list
switch(_args.length) {
case 1:
param = null;
break;
case 2:
param = _args[1];
break;
default:
throw new IllegalArgumentException("error parsing \"" + arg + "\"");
}
} else {
throw new RuntimeException("unknown command-line option: -" + arg);
}
return new Object[] {opt,param};
}
private static Object[] parseShortForm(String arg, Iterator iter, Map opts) {
arg = arg.substring(1,arg.length());
OptArg opt = opts.get(arg);
String param;
if(opt != null) {
// matched
iter.remove(); // remove option from args list
//
if(opt.argument != null) {
param = iter.next();
iter.remove(); // remove option from args list
} else {
param = null;
}
} else {
throw new RuntimeException("unknown command-line option: -" + arg);
}
return new Object[] {opt,param};
}
public static void usage(PrintStream output, OptArg...options) {
// first, work out gap information
int gap = 0;
ArrayList opts = new ArrayList<>();
for (OptArg opt : options) {
opts.add(opt);
int len = opt.option.length();
if(opt.argument != null) {
len = len + opt.argument.toString().length();
}
if(opt.shortForm != null) {
len = len + opt.shortForm.length();
opts.add(new OptArg(opt.shortForm,opt.argument,opt.description + " [short form]"));
}
gap = Math.max(gap, len);
}
gap = gap + 1;
// now, print the information
for (OptArg opt : opts) {
output.print(" -" + opt.option);
int rest = gap - opt.option.length();
output.print(" ");
if(opt.argument != null) {
String arg = opt.argument.toString();
rest -= arg.length();
output.print(arg);
}
for (int i = 0; i < rest; ++i) {
output.print(" ");
}
output.println(opt.description);
}
}
/**
* This splits strings of the form "x=y,v=w" into distinct components and
* puts them into a map. In the case of a string like "x,y=z" then x is
* loaded with the empty string.
*
* @param str
* @return
*/
private static Map splitConfig(String str) {
HashMap options = new HashMap<>();
String[] splits = str.split(",");
for (String s : splits) {
String[] p = s.split("=");
options.put(p[0], parseValue(p[1]));
}
return options;
}
private static Object parseValue(String str) {
if(str.equals("true")) {
return Boolean.TRUE;
} else if(str.equals("false")) {
return Boolean.FALSE;
} else if(Character.isDigit(str.charAt(0))) {
if(str.charAt(str.length()-1) == 'L') {
return Long.parseLong(str.substring(0,str.length()-1));
} else {
return Integer.parseInt(str);
}
} else {
return str;
}
}
}