### jack_argv - argv parser and help printing -- part of ### jack - extract audio from a CD and MP3ify it using 3rd party software ### Copyright (C) 2002-2004 Arne Zellentin ### This program is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by ### the Free Software Foundation; either version 2 of the License, or ### (at your option) any later version. ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; 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 this program; if not, write to the Free Software ### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import sys import types import jack_utils import jack_generic from jack_globals import * from jack_misc import safe_int def show_usage(cf, long=0): l = [] for i in cf.keys(): if not long and not cf[i].has_key('help'): continue s = "" if cf[i].has_key('usage'): if not long and cf[i].has_key('vbr_only') and cf[i]['vbr_only'] != cf['_vbr']: continue if cf[i].has_key('long'): s = " --%s" % cf[i]['long'] if cf[i].has_key('short'): s = s + ", -%s" % cf[i]['short'] else: error("internal error in show_usage") x_char = " " l.append([s, cf[i]['usage'] + jack_utils.yes(cf[i])]) max_len = 0 for i in l: max_len = max(max_len, len(i[0])) l.sort() print "usage: jack [option]..." for i in l: jack_generic.indent(i[0] + " " * (max_len - len(i[0])), i[1]) if long: print """ While Jack is running, press q or Q to quit, p or P to disable ripping (you need the CD drive) p or P (again) or c or C to resume, e or E to pause/continue all encoders and r or R to pause/continue all rippers. """ else: print "These are the most common options. For a complete list, run jack --longhelp" def get_next(argv, i, extra_arg = None): if extra_arg != None: return i, extra_arg elif argv[i].find("=") > 0: return i, argv[i].split("=", 1)[1] else: i = i + 1 if len(argv) > i: return i, argv[i] else: return i, None def istrue(x): return x.upper() in ["Y", "YES", "1", "TRUE"] def parse_option(cf, argv, i, option, alt_arg, origin="argv"): ty = cf[option]['type'] if ty == 'toggle': if alt_arg: return i, istrue(alt_arg) else: return i, not cf[option]['val'] if ty == types.FloatType: i, data = get_next(argv, i, alt_arg) if data != None: try: data = float(data) return i, data except: return None, "option `%s' needs a float argument" % option else: return None, "Option `%s' needs exactly one argument" % option if ty == types.IntType: i, data = get_next(argv, i, alt_arg) if data != None: try: data = int(data) return i, data except: return None, "option `%s' needs an integer argument" % option return i, safe_int(data, "option `%s' needs an integer argument" % option) else: return None, "Option `%s' needs exactly one argument" % option if ty == types.StringType: i, data = get_next(argv, i, alt_arg) if data != None: return i, data else: return None, "Option `%s' needs exactly one string argument" % option if ty == types.ListType: l = [] if origin == "argv": while 1: i, data = get_next(argv, i, alt_arg) if data != None: if data == ";": break l.append(data) if alt_arg: # only one option in --opt=val form break else: break elif origin == "rcfile": i, data = get_next(argv, i, alt_arg) l = eval(data) if l and type(l) == types.ListType: return i, l else: return None, "option `%s' takes a non-empty list (which may be terminated by \";\")" % `option` # default return None, "unknown argument type for option `%s'." % option def parse_argv(cf, argv): argv_cf = {} allargs = {} for i in cf.keys(): if cf[i].has_key('long'): if len(cf[i]['long']) < 2 or allargs.has_key(cf[i]['long']): print "Hey Arne, don't bullshit me!" print cf[i] sys.exit(1) else: allargs[cf[i]['long']] = i if cf[i].has_key('short'): if len(cf[i]['short']) != 1 or allargs.has_key(cf[i]['short']): print "Hey Arne, don't bullshit me!" print cf[i] sys.exit(1) else: allargs[cf[i]['short']] = i i = 1 help = 0 while i < len(argv): if argv[i] in ("-h", "--help"): help = 1 i = i + 1 continue if argv[i] in ("--longhelp", "--long-help"): help = 2 i = i + 1 continue option = "" tmp_option = tmp_arg = None if argv[i].find("=") >= 2: tmp_option, tmp_arg = argv[i].split("=", 1) else: tmp_option = argv[i] if len(tmp_option) == 2 and tmp_option[0] == "-": o = tmp_option[1] if allargs.has_key(o): option = allargs[o] elif tmp_option == "--override": i, option = get_next(argv, i, tmp_arg) if option.find("=") > 0: option, tmp_arg = option.split("=", 1) if option == None: print "--override takes two arguments: " sys.exit(1) elif len(tmp_option) > 2 and tmp_option[0:2] == "--": o = tmp_option[2:] if allargs.has_key(o): option = allargs[o] if option: i, value = parse_option(cf, argv, i, option, tmp_arg) if i == None: error(value) if not argv_cf.has_key(option): argv_cf[option] = {} argv_cf[option].update({'val': value}) else: print "unknown option `%s'" % argv[i] show_usage(cf) sys.exit(1) if not i: break i = i + 1 return help, argv_cf # end of parse_argv()