17 ) |
17 ) |
18 |
18 |
19 # Set of flags to not apply boolean negation logic on |
19 # Set of flags to not apply boolean negation logic on |
20 nevernegate = { |
20 nevernegate = { |
21 # avoid --no-noninteractive |
21 # avoid --no-noninteractive |
22 'noninteractive', |
22 b'noninteractive', |
23 # These two flags are special because they cause hg to do one |
23 # These two flags are special because they cause hg to do one |
24 # thing and then exit, and so aren't suitable for use in things |
24 # thing and then exit, and so aren't suitable for use in things |
25 # like aliases anyway. |
25 # like aliases anyway. |
26 'help', |
26 b'help', |
27 'version', |
27 b'version', |
28 } |
28 } |
29 |
29 |
30 |
30 |
31 def _earlyoptarg(arg, shortlist, namelist): |
31 def _earlyoptarg(arg, shortlist, namelist): |
32 """Check if the given arg is a valid unabbreviated option |
32 """Check if the given arg is a valid unabbreviated option |
75 >>> opt(b'-:') |
75 >>> opt(b'-:') |
76 ('', False, '', False) |
76 ('', False, '', False) |
77 >>> opt(b'-:foo') |
77 >>> opt(b'-:foo') |
78 ('', False, '', False) |
78 ('', False, '', False) |
79 """ |
79 """ |
80 if arg.startswith('--'): |
80 if arg.startswith(b'--'): |
81 flag, eq, val = arg.partition('=') |
81 flag, eq, val = arg.partition(b'=') |
82 if flag[2:] in namelist: |
82 if flag[2:] in namelist: |
83 return flag, bool(eq), val, False |
83 return flag, bool(eq), val, False |
84 if flag[2:] + '=' in namelist: |
84 if flag[2:] + b'=' in namelist: |
85 return flag, bool(eq), val, True |
85 return flag, bool(eq), val, True |
86 elif arg.startswith('-') and arg != '-' and not arg.startswith('-:'): |
86 elif arg.startswith(b'-') and arg != b'-' and not arg.startswith(b'-:'): |
87 flag, val = arg[:2], arg[2:] |
87 flag, val = arg[:2], arg[2:] |
88 i = shortlist.find(flag[1:]) |
88 i = shortlist.find(flag[1:]) |
89 if i >= 0: |
89 if i >= 0: |
90 return flag, bool(val), val, shortlist.startswith(':', i + 1) |
90 return flag, bool(val), val, shortlist.startswith(b':', i + 1) |
91 return '', False, '', False |
91 return b'', False, b'', False |
92 |
92 |
93 |
93 |
94 def earlygetopt(args, shortlist, namelist, gnu=False, keepsep=False): |
94 def earlygetopt(args, shortlist, namelist, gnu=False, keepsep=False): |
95 """Parse options like getopt, but ignores unknown options and abbreviated |
95 """Parse options like getopt, but ignores unknown options and abbreviated |
96 forms |
96 forms |
176 parsedopts = [] |
176 parsedopts = [] |
177 parsedargs = [] |
177 parsedargs = [] |
178 pos = 0 |
178 pos = 0 |
179 while pos < len(args): |
179 while pos < len(args): |
180 arg = args[pos] |
180 arg = args[pos] |
181 if arg == '--': |
181 if arg == b'--': |
182 pos += not keepsep |
182 pos += not keepsep |
183 break |
183 break |
184 flag, hasval, val, takeval = _earlyoptarg(arg, shortlist, namelist) |
184 flag, hasval, val, takeval = _earlyoptarg(arg, shortlist, namelist) |
185 if not hasval and takeval and pos + 1 >= len(args): |
185 if not hasval and takeval and pos + 1 >= len(args): |
186 # missing last argument |
186 # missing last argument |
259 class _intopt(customopt): |
259 class _intopt(customopt): |
260 def newstate(self, oldstate, newparam, abort): |
260 def newstate(self, oldstate, newparam, abort): |
261 try: |
261 try: |
262 return int(newparam) |
262 return int(newparam) |
263 except ValueError: |
263 except ValueError: |
264 abort(_('expected int')) |
264 abort(_(b'expected int')) |
265 |
265 |
266 |
266 |
267 def _defaultopt(default): |
267 def _defaultopt(default): |
268 """Returns a default opt implementation, given a default value.""" |
268 """Returns a default opt implementation, given a default value.""" |
269 |
269 |
322 else: |
322 else: |
323 short, name, default, comment = option |
323 short, name, default, comment = option |
324 # convert opts to getopt format |
324 # convert opts to getopt format |
325 onames = [name] |
325 onames = [name] |
326 onames.extend(optaliases.get(name, [])) |
326 onames.extend(optaliases.get(name, [])) |
327 name = name.replace('-', '_') |
327 name = name.replace(b'-', b'_') |
328 |
328 |
329 argmap['-' + short] = name |
329 argmap[b'-' + short] = name |
330 for n in onames: |
330 for n in onames: |
331 argmap['--' + n] = name |
331 argmap[b'--' + n] = name |
332 defmap[name] = _defaultopt(default) |
332 defmap[name] = _defaultopt(default) |
333 |
333 |
334 # copy defaults to state |
334 # copy defaults to state |
335 state[name] = defmap[name].getdefaultvalue() |
335 state[name] = defmap[name].getdefaultvalue() |
336 |
336 |
337 # does it take a parameter? |
337 # does it take a parameter? |
338 if not defmap[name]._isboolopt(): |
338 if not defmap[name]._isboolopt(): |
339 if short: |
339 if short: |
340 short += ':' |
340 short += b':' |
341 onames = [n + '=' for n in onames] |
341 onames = [n + b'=' for n in onames] |
342 elif name not in nevernegate: |
342 elif name not in nevernegate: |
343 for n in onames: |
343 for n in onames: |
344 if n.startswith('no-'): |
344 if n.startswith(b'no-'): |
345 insert = n[3:] |
345 insert = n[3:] |
346 else: |
346 else: |
347 insert = 'no-' + n |
347 insert = b'no-' + n |
348 # backout (as a practical example) has both --commit and |
348 # backout (as a practical example) has both --commit and |
349 # --no-commit options, so we don't want to allow the |
349 # --no-commit options, so we don't want to allow the |
350 # negations of those flags. |
350 # negations of those flags. |
351 if insert not in alllong: |
351 if insert not in alllong: |
352 assert ('--' + n) not in negations |
352 assert (b'--' + n) not in negations |
353 negations['--' + insert] = '--' + n |
353 negations[b'--' + insert] = b'--' + n |
354 namelist.append(insert) |
354 namelist.append(insert) |
355 if short: |
355 if short: |
356 shortlist += short |
356 shortlist += short |
357 if name: |
357 if name: |
358 namelist.extend(onames) |
358 namelist.extend(onames) |
379 state[name] = boolval |
379 state[name] = boolval |
380 else: |
380 else: |
381 |
381 |
382 def abort(s): |
382 def abort(s): |
383 raise error.Abort( |
383 raise error.Abort( |
384 _('invalid value %r for option %s, %s') |
384 _(b'invalid value %r for option %s, %s') |
385 % (pycompat.maybebytestr(val), opt, s) |
385 % (pycompat.maybebytestr(val), opt, s) |
386 ) |
386 ) |
387 |
387 |
388 state[name] = defmap[name].newstate(state[name], val, abort) |
388 state[name] = defmap[name].newstate(state[name], val, abort) |
389 |
389 |