summaryrefslogtreecommitdiff
path: root/jack_argv.py
blob: a043e7266a3754c3cf3b75183c83491accbb230f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
### 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 <zarne@users.sf.net>

### 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: <VARIABLE> <VALUE>"
                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()