/* getopts.java Copyright 1998 Kyle R. Burton This is free software; you can redistribute it and/or modify it under the tearms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with log_daemon; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * description: command line switch parser implemented in java. * * author: Kyle R. Burton * mortis@voicenet.com * http://www.voicenet.com/~mortis * Copyright 1998, Kyle R. Burton, all rights reserved. * * revision list: * Wed Apr 22 17:34:56 EDT 1998 KRB - created v1.0 * Sun Apr 26 13:58:10 EDT 1998 KRB - fixed the packed options problem and * turned off show_diagonstics by default. I think this version is good * enough to be considered the first release. * Mon Apr 27 17:39:58 EDT 1998 KRB - added num_parsed, and remainder... * * notes: * - grep for the string 'revisit' and fix those areas * */ public class getopts { public static final String TRUE = "true"; public static final String FALSE = "false"; public boolean show_diagnostics = false; // change to false for release java.util.Hashtable settings; java.util.Hashtable switches; public String remainder[] = null; public int num_parsed; // default constructor public getopts() { if( show_diagnostics ) { System.out.println("getopts::getopts()"); } switches = new java.util.Hashtable(); settings = new java.util.Hashtable(); } // constructor w/initializers public getopts( String opts, String args[] ) { if( show_diagnostics ) { System.out.println("getopts::getopts(String,String[])"); } switches = new java.util.Hashtable(); settings = new java.util.Hashtable(); parse_args(opts,args); } // down and dirty work of getting the arguments... public boolean parse_args( String opts, String args[] ) { if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[])"); } if( null == opts || null == args ) { return false; } int pos = 0; // no options? if( opts.length() <= 1 ) { return false; } // set up the switch hash... opt_val tmp = null; if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[]) creating settings hash: " + opts); } for( pos = 0; pos < opts.length(); pos++ ) { if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[]) adding: " + opts.charAt(pos)); } // boolean or value? if( (pos+1) < opts.length() ) { if( ':' == opts.charAt(pos+1) ) { // value if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[]) value opt: " + opts.charAt(pos) ); } tmp = new opt_val( new Character(opts.charAt(pos)).toString(), opt_val.OT_VALUE ); ++pos; } else { // boolean if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[]) boolean opt: " + opts.charAt(pos) ); } tmp = new opt_val( new Character(opts.charAt(pos)).toString(), opt_val.OT_FLAG ); } } else { // boolean if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[]) boolean opt: " + opts.charAt(pos) ); } tmp = new opt_val( new Character(opts.charAt(pos)).toString(), opt_val.OT_FLAG ); } switches.put( tmp.get_opt(), tmp ); } // now reap the args array... pos = 0; while( pos < args.length ) { // 1 character or less? if( args[pos].length() <= 1 ) break; // doesn't start with a '-'? if( '-' != args[pos].charAt(0) ) break; // by george I think we have an option! ++num_parsed; Character sw = new Character(args[pos].charAt(1)); if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[]) checking: " + sw ); } tmp = (opt_val)switches.get(sw.toString()); if( null == tmp ) { // oops, this one isn't recognized // revisit -- what to do here? if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[])" + " Unrecognized command line option: " + args[pos] ); System.out.println("getopts::parse_args(String,String[])" + " it is being ignored."); } } else { // valid option // is it a boolean flag? if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[])" + " valid switch, determing type: " + sw); } switch( tmp.get_type() ) { case opt_val.OT_FLAG: if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[])" + " type is OT_FLAG" ); } settings.put(sw.toString(),TRUE); // deprecate the option string... args[pos] = '-' + args[pos].substring(2); break; case opt_val.OT_VALUE: if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[])" + " type is OT_VALUE" ); } // is the value butted up against the switch? if( args[pos].length() > 2 ) { // yes settings.put(sw.toString(),args[pos].substring(2)); } else { // must be the next arg, is there a next arg? if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[])" + " testing for next arg. pos is: " + pos + " args.length is: " + args.length ); } if( (pos+1) < args.length ) { ++pos; settings.put(sw.toString(),args[pos]); args[pos] = "-"; } else { // oops, that was the last arg... // settings.put(sw.toString(),null); // don't set anything } } // deprecate the option string... args[pos] = "-"; break; default: // revisit -- error this can't happen? System.out.println("getopts::parse_args(String,String[])" + " Error, this can't happen." ); break; } } // do we continue? // we might be left with "-", or "-" + some more args if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[]) remainder: " + args[pos] ); } if( 0 == args[pos].compareTo("-") ) { ++pos; continue; } if( args[pos].length() <= 1 ) { ++pos; continue; } if( show_diagnostics ) { System.out.println("getopts::parse_args(String,String[]) there is " + "another switch to process: " + args[pos] ); } } if( pos != args.length ) { remainder = new String[args.length - pos]; for( int i = 0; i < (args.length - pos); ++i ) { remainder[i] = args[pos+i]; } } return (pos > 0); } public boolean opt( char ch ) { if( show_diagnostics ) { System.out.println("getopts::opt(char) " + ch); } String tmp = new String(); Character c = new Character(ch); tmp = c.toString(); return settings.containsKey(tmp); } public void set_opt( char ch, boolean flag ) { if( show_diagnostics ) { System.out.println("getopts::set_opt(char,boolean)"); } // revisit } public void set_opt( char ch, String value ) { if( show_diagnostics ) { System.out.println("getopts::set_opt(char,String)"); } // revisit } public String get_value( char ch ) { String tmp = new Character(ch).toString(); if( settings.containsKey(tmp) ) { return (String)settings.get(tmp); } return null; } } /** * * private helper class for getopts... */ class opt_val { public static final int OT_FLAG = 1; public static final int OT_VALUE = 2; public static final String TRUE = "true"; public static final String FALSE = "false"; int type; String opt; public opt_val() { opt = new String(); } public opt_val( String opt ) { this.opt = new String(opt); } public opt_val( String opt, int type ) { this.type = type; this.opt = new String(opt); } public String get_opt() { return opt; } public void set_opt( String opt ) { this.opt = opt; } public void set_opt( boolean opt ) { this.opt = opt ? TRUE : FALSE; } public int get_type() { return type; } public void set_type( int type ) { this.type = type; } }