/*=======================================================
* CommandOptionList.java
*
* "A Tcl like language implementation in Java named APWTCL
* ((Java) Arnulf's Preferred Web Tcl)"
*
* APWTCL CommandOptionList class
*
* Released under same BSD license as Tcl.
* (Tcl BSD license found at <http://www.tcl.tk/software/tcltk/license.html>)
*
* Copyright 2012 Arnulf P. Wiedemann
*
*/
package org.apwtcl.lang;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
public class CommandOptionList extends Token implements Debug {
private static int oid = 0;
private int id;
private Interp interp;
public HashMap<String, CommandOption> option_list; /* this list of valid options for this command */
private int option_flags;
private HashMap<String, ApwtclObj> option_values;
private String err_msg;
private int num_processed_args;
private HashMap<Integer, String> opt_code2opt_name;
/* ==================== CommandOptionList ================================== */
public CommandOptionList(Interp interp) {
oid++;
id = oid;
this.interp = interp;
this.option_list = new HashMap<String, CommandOption>();
this.opt_code2opt_name = new HashMap<Integer, String>();
}
/* ==================== mySelf ================================== */
public String mySelf() {
String str = "CommandOptionList!"+id+"!";
return str;
}
/* ==================== toString ===================================== */
public String toString() {
return mySelf()+"!";
}
/* ==================== toDebugString ===================================== */
public String toDebugString() {
StringBuffer str = new StringBuffer(mySelf()+"\n");
return str.toString();
}
/* ==================== addOption ===================================== */
public void addOption(String option_name, int option_code, boolean has_opt_value,
ArrayList<ApwtclObj> default_value, HashMap<String, Integer>allowed_option_values) {
CommandOption option = new CommandOption(interp, option_name, option_code, has_opt_value, default_value,
allowed_option_values);
option_list.put(option_name, option);
opt_code2opt_name.put(option_code, option_name);
}
/* ==================== hasOption ===================================== */
public boolean hasOption(String option_name) {
if (option_list.get(option_name) != null) {
return true;
}
return false;
}
/* ==================== optionHasValue ===================================== */
public boolean optionHasValue(String option_name) {
CommandOption option = option_list.get(option_name);
if (option == null) {
return false;
}
return option.opt_has_value;
}
/* ==================== optionCode ===================================== */
public int optionCode(String option_name) {
CommandOption option = option_list.get(option_name);
if (option == null) {
return -1;
}
return option.opt_code;
}
/* ==================== getErrorMsg ===================================== */
public String getErrorMsg() {
return err_msg;
}
/* ==================== getOptionFlags ===================================== */
public int getOptionFlags() {
return option_flags;
}
/* ==================== getNumProcessedArgs ===================================== */
public int getNumProcessedArgs() {
return num_processed_args;
}
/* ==================== getOptionFlagNames ===================================== */
public String getOptionFlagNames() {
StringBuffer str = new StringBuffer();
String sep = "";
ArrayList<String> my_lst = new ArrayList<String>(option_list.keySet());
Collections.sort(my_lst);
for (String z: my_lst) {
str.append(sep+z);
sep = " ";
}
return str.toString();
}
/* ==================== getOptionFlagsList ===================================== */
public ApwtclObj getOptionFlagsList() {
ApwtclObj result_lst = interp.list_obj_type.newListObj(null, 0);
ArrayList<String> my_lst = new ArrayList<String>(option_list.keySet());
Collections.sort(my_lst);
for (String z: my_lst) {
interp.list_obj_type.listAppendElement(result_lst, interp.string_obj_type.newStringObj(z,-1, "COMMAND_OPTION_LIST_1"));
}
return result_lst;
}
/* ==================== getOptionValue ===================================== */
public ArrayList<ApwtclObj> getOptionValue(int opt_code) {
String opt_name = opt_code2opt_name.get(opt_code);
if (opt_name == null) {
return null;
}
ApwtclObj value = option_values.get(opt_name);
if (value != null) {
ArrayList<ApwtclObj> ll = new ArrayList<ApwtclObj>();
ll.add(value);
return ll;
}
CommandOption option = option_list.get(opt_name);
return option.default_value;
}
/* ==================== getOptionValueFromName ===================================== */
public ArrayList<ApwtclObj> getOptionValueFromName(String opt_name) {
ApwtclObj value = option_values.get(opt_name);
if (value != null) {
ArrayList<ApwtclObj> ll = new ArrayList<ApwtclObj>();
ll.add(value);
return ll;
}
CommandOption option = option_list.get(opt_name);
return option.default_value;
}
/* ==================== resetOptionValues ===================================== */
public void resetOptionValues() {
option_values = new HashMap<String, ApwtclObj>();
}
/* ==================== parseOptions ===================================== */
public int parseOptions(ArrayList<ApwtclObj> args, int start_idx, String msg_start) {
String option;
num_processed_args = 0;
option_flags = 0;
err_msg = "";
for (int i = start_idx; i < args.size(); i++) {
option = args.get(i).getString();
//print("option!"+option+"!");
if (option.charAt(0) != '-') {
/* seems to be end of options */
break;
}
if (option.equals("--")) {
/* end of options */
num_processed_args++;
i++;
break;
}
CommandOption option_info = option_list.get(option);
if (option_info == null) {
StringBuffer msg = new StringBuffer(msg_start+" bad option: '"+option+"' should be one of: '");
String sep = "";
for (String opt: option_list.keySet()) {
msg.append(sep + opt);
sep = ", ";
}
err_msg = msg.toString();
return ERROR;
}
num_processed_args++;
option_flags |= option_info.opt_code;
if (optionHasValue(option)) {
i++;
if (i == args.size()) {
err_msg = msg_start+" must be an even number of option name and option value";
return ERROR;
}
num_processed_args++;
if (option_info.allowed_option_values != null) {
if (option_info.allowed_option_values.get(args.get(i).getString()) == null) {
err_msg = msg_start+" bad value for option \""+option+"\" must be: "+option_info.getAllowedOptionValues();
return ERROR;
}
}
option_values.put(option, args.get(i));
}
}
//print("num_processed_args!"+num_processed_args+"!");
return OK;
}
}