#! /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()
