|
| 1 | +class GetoptError(Exception): |
| 2 | + pass |
| 3 | + |
| 4 | + |
| 5 | +def w_getopt(args, options): |
| 6 | + """A getopt for Windows. |
| 7 | +
|
| 8 | + Options may start with either '-' or '/', the option names may |
| 9 | + have more than one letter (/tlb or -RegServer), and option names |
| 10 | + are case insensitive. |
| 11 | +
|
| 12 | + Returns two elements, just as getopt.getopt. The first is a list |
| 13 | + of (option, value) pairs in the same way getopt.getopt does, but |
| 14 | + there is no '-' or '/' prefix to the option name, and the option |
| 15 | + name is always lower case. The second is the list of arguments |
| 16 | + which do not belong to an option. |
| 17 | +
|
| 18 | + Different from getopt.getopt, a single argument not belonging to an option |
| 19 | + does not terminate parsing. |
| 20 | + """ |
| 21 | + opts = [] |
| 22 | + arguments = [] |
| 23 | + while args: |
| 24 | + if args[0][:1] in "/-": |
| 25 | + arg = args[0][1:] # strip the '-' or '/' |
| 26 | + arg = arg.lower() |
| 27 | + |
| 28 | + if arg + ":" in options: |
| 29 | + try: |
| 30 | + opts.append((arg, args[1])) |
| 31 | + except IndexError: |
| 32 | + raise GetoptError(f"option '{args[0]}' requires an argument") |
| 33 | + args = args[1:] |
| 34 | + elif arg in options: |
| 35 | + opts.append((arg, "")) |
| 36 | + else: |
| 37 | + raise GetoptError(f"invalid option '{args[0]}'") |
| 38 | + args = args[1:] |
| 39 | + else: |
| 40 | + arguments.append(args[0]) |
| 41 | + args = args[1:] |
| 42 | + |
| 43 | + return opts, arguments |
| 44 | + |
| 45 | + |
| 46 | +if __debug__: |
| 47 | + if __name__ == "__main__": |
| 48 | + import unittest |
| 49 | + |
| 50 | + class TestCase(unittest.TestCase): |
| 51 | + def test_1(self): |
| 52 | + args = "-embedding spam /RegServer foo /UnregSERVER blabla".split() |
| 53 | + opts, args = w_getopt(args, "regserver unregserver embedding".split()) |
| 54 | + self.assertEqual( |
| 55 | + opts, [("embedding", ""), ("regserver", ""), ("unregserver", "")] |
| 56 | + ) |
| 57 | + self.assertEqual(args, ["spam", "foo", "blabla"]) |
| 58 | + |
| 59 | + def test_2(self): |
| 60 | + args = "/TLB Hello.Tlb HELLO.idl".split() |
| 61 | + opts, args = w_getopt(args, ["tlb:"]) |
| 62 | + self.assertEqual(opts, [("tlb", "Hello.Tlb")]) |
| 63 | + self.assertEqual(args, ["HELLO.idl"]) |
| 64 | + |
| 65 | + def test_3(self): |
| 66 | + # Invalid option |
| 67 | + self.assertRaises( |
| 68 | + GetoptError, w_getopt, "/TLIB hello.tlb hello.idl".split(), ["tlb:"] |
| 69 | + ) |
| 70 | + |
| 71 | + def test_4(self): |
| 72 | + # Missing argument |
| 73 | + self.assertRaises(GetoptError, w_getopt, "/TLB".split(), ["tlb:"]) |
| 74 | + |
| 75 | + unittest.main() |
0 commit comments