summaryrefslogtreecommitdiff
path: root/tools/reformat.py
blob: 61306d0235da5b23d6f3ec07e4a417a178f09d37 (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
#! /usr/bin/python
########################################################################
#
# reorder and reformat a file in columns
#
# this utility takes lines from its standard input and reproduces them,
# partially reordered and reformatted, on its standard output.
#
# It has the same effect as a 'sort | column -t', with the exception
# that empty lines, as well as lines which start with a '#' sign, are
# not affected, i.e. they keep their position and formatting, and act
# as separators, i.e. the parts before and after them are each sorted
# separately (but overall field widths are computed across the whole
# input).
#
# Options:
#   -i:
#   --ignore-case:
#	Do not consider case when sorting.
#   -d:
#   --default:
#	What to chage empty fields to.
#    -s <N>:
#    --split=<N>:
#       Treat only the first N whitespace sequences as separators.
#       line content after the Nth separator will count as only one
#       field even if it contains whitespace.
#       Example : '-s 2' causes input 'a b c d e' to be split into
#       three fields, 'a', 'b', and 'c d e'.
#
# boards.cfg requires -ids 6.
#
########################################################################

import sys, getopt, locale

# ensure we sort using the C locale.

locale.setlocale(locale.LC_ALL, 'C')

# check options

maxsplit = 0
ignore_case = 0
default_field =''

try:
	opts, args = getopt.getopt(sys.argv[1:], "id:s:",
		["ignore-case","default","split="])
except getopt.GetoptError as err:
	print str(err) # will print something like "option -a not recognized"
	sys.exit(2)

for o, a in opts:
	if o in ("-s", "--split"):
		maxsplit = eval(a)
	elif o in ("-i", "--ignore-case"):
		ignore_case = 1
	elif o in ("-d", "--default"):
		default_field = a
	else:
		assert False, "unhandled option"

# collect all lines from standard input and, for the ones which must be
# reformatted and sorted, count their fields and compute each field's
# maximum size

input_lines = []
field_width = []

for line in sys.stdin:
	# remove final end of line
	input_line = line.strip('\n')
	if (len(input_line)>0) and (input_line[0] != '#'):
		# sortable line: split into fields
		fields = input_line.split(None,maxsplit)
		# if there are new fields, top up field_widths
		for f in range(len(field_width), len(fields)):
			field_width.append(0)
		# compute the maximum witdh of each field
		for f in range(len(fields)):
			field_width[f] = max(field_width[f],len(fields[f]))
	# collect the line for next stage
	input_lines.append(input_line)

# run through collected input lines, collect the ones which must be
# reformatted and sorted, and whenever a non-reformattable, non-sortable
# line is met, sort the collected lines before it and append them to the
# output lines, then add the non-sortable line too.

output_lines = []
sortable_lines = []
for input_line in input_lines:
	if (len(input_line)>0) and (input_line[0] != '#'):
		# this line should be reformatted and sorted
		input_fields = input_line.split(None,maxsplit)
		output_fields = [];
		# reformat each field to this field's column width
		for f in range(len(input_fields)):
			output_field = input_fields[f];
			output_fields.append(output_field.ljust(field_width[f]))
		# any missing field is set to default if it exists
		if default_field != '':
			for f in range(len(input_fields),len(field_width)):
				output_fields.append(default_field.ljust(field_width[f]))
		# join fields using two spaces, like column -t would
		output_line = '  '.join(output_fields);
		# collect line for later
		sortable_lines.append(output_line)
	else:
		# this line is non-sortable
		# sort collected sortable lines
		if ignore_case!=0:
			sortable_lines.sort(key=lambda x: str.lower(locale.strxfrm(x)))
		else:
			sortable_lines.sort(key=lambda x: locale.strxfrm(x))
		# append sortable lines to the final output
		output_lines.extend(sortable_lines)
		sortable_lines = []
		# append non-sortable line to the final output
		output_lines.append(input_line)
# maybe we had sortable lines pending, so append them to the final output
if ignore_case!=0:
	sortable_lines.sort(key=lambda x: str.lower(locale.strxfrm(x)))
else:
	sortable_lines.sort(key=lambda x: locale.strxfrm(x))
output_lines.extend(sortable_lines)

# run through output lines and print them, except rightmost whitespace

for output_line in output_lines:
	print output_line.rstrip()