generic/192: fix instability on exFAT
[xfstests-dev.git] / tools / sort-group
1 #!/usr/bin/env python
2 import sys
3
4 # Sort a group list, carefully preserving comments.
5
6 def xfstest_key(key):
7         '''Extract the numeric part of a test name if possible.'''
8         k = 0
9
10         assert type(key) == str
11
12         # No test number at all...
13         if not key[0].isdigit():
14                 return key
15
16         # ...otherwise extract as much number as we can.
17         for digit in key:
18                 if digit.isdigit():
19                         k = k * 10 + int(digit)
20                 else:
21                         return k
22         return k
23
24 def read_group(fd):
25         '''Read the group list, carefully attaching comments to the next test.'''
26         tests = {}
27         comments = None
28
29         for line in fd:
30                 sline = line.strip()
31                 tokens = sline.split()
32                 if len(tokens) == 0 or tokens[0] == '#':
33                         if comments == None:
34                                 comments = []
35                         comments.append(sline)
36                 else:
37                         tests[tokens[0]] = (comments, tokens[1:])
38                         comments = None
39         return tests
40
41 def sort_keys(keys):
42         '''Separate keys into integer and non-integer tests.'''
43         int_keys = []
44         int_xkeys = []
45         str_keys = []
46
47         # Sort keys into integer(ish) tests and other
48         for key in keys:
49                 xkey = xfstest_key(key)
50                 if type(xkey) == int:
51                         int_keys.append(key)
52                         int_xkeys.append(xkey)
53                 else:
54                         str_keys.append(key)
55         return (int_keys, int_xkeys, str_keys)
56
57 def write_sorted(tests, fd):
58         def dump_xkey(xkey):
59                 (comments, tokens) = tests[key]
60                 if comments:
61                         for c in comments:
62                                 fd.write('%s\n' % c)
63                 fd.write('%s %s\n' % (key, ' '.join(tokens)))
64         '''Print tests (and comments) in number order.'''
65
66         (int_keys, ignored, str_keys) = sort_keys(tests.keys())
67         for key in sorted(int_keys, key = xfstest_key):
68                 dump_xkey(key)
69         for key in sorted(str_keys):
70                 dump_xkey(key)
71
72 def sort_main():
73         if '--help' in sys.argv[1:]:
74                 print('Usage: %s groupfiles' % sys.argv[0])
75                 sys.exit(0)
76
77         for arg in sys.argv[1:]:
78                 with open(arg, 'r+') as fd:
79                         x = read_group(fd)
80                         fd.seek(0, 0)
81                         write_sorted(x, fd)
82
83 def nextid_main():
84         if '--help' in sys.argv[1:]:
85                 print('Usage: %s group[/startid] ' % sys.argv[0])
86                 sys.exit(0)
87
88         if len(sys.argv) != 2:
89                 print('Specify exactly one group name.')
90                 sys.exit(1)
91
92         c = sys.argv[1].split('/')
93         if len(c) > 1:
94                 startid = int(c[1])
95         else:
96                 startid = 1
97         group = c[0]
98
99         with open('tests/%s/group' % group, 'r') as fd:
100                 x = read_group(fd)
101                 xkeys = {int(x) for x in sort_keys(x.keys())[1]}
102
103                 xid = startid
104                 while xid in xkeys:
105                         xid += 1
106                 print('%s/%03d' % (group, xid))
107
108 if __name__ == '__main__':
109         if 'nextid' in sys.argv[0]:
110                 nextid_main()
111         else:
112                 sort_main()