diff options
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.78.1/scripts/option_reducer.py')
-rwxr-xr-x | debian/uncrustify-trinity/uncrustify-trinity-0.78.1/scripts/option_reducer.py | 1125 |
1 files changed, 0 insertions, 1125 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/scripts/option_reducer.py b/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/scripts/option_reducer.py deleted file mode 100755 index 403ff92b..00000000 --- a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/scripts/option_reducer.py +++ /dev/null @@ -1,1125 +0,0 @@ -#!/usr/bin/python -""" -option_reducer.py - -reduces options in a given config file to the minimum while still maintaining -desired formatting - -:author: Daniel Chumak -:license: GPL v2+ -""" - -# Possible improvements: -# - parallelize add_back() -# - (maybe) reduce amount of written config file, see Uncrustify --set - -from __future__ import print_function # python >= 2.6 -import argparse - -from os import name as os_name, sep as os_path_sep, fdopen as os_fdopen, \ - remove as os_remove -from os.path import exists, join as path_join -from subprocess import Popen, PIPE -from sys import exit as sys_exit, stderr, stdout -from shutil import rmtree -from multiprocessing import cpu_count -from tempfile import mkdtemp, mkstemp -from contextlib import contextmanager -from collections import OrderedDict -from threading import Timer -from multiprocessing.pool import Pool -from itertools import combinations - -FLAGS = None -NULL_DEV = "/dev/null" if os_name != "nt" else "nul" - - -def enum(**enums): - return type('Enum', (), enums) - - -RESTULTSFLAG = enum(NONE=0, REMOVE=1, KEEP=2) -ERROR_CODE = enum(NONE=0, FLAGS=200, SANITY0=201, SANITY1=202) -MODES = ("reduce", "no-default") - - -@contextmanager -def make_temp_directory(): - """ - Wraps tempfile.mkdtemp to use it inside a with statement that auto deletes - the temporary directory with its content after the with block closes - - - :return: str - ---------------------------------------------------------------------------- - path to the generated directory - """ - temp_dir = mkdtemp() - try: - yield temp_dir - finally: - rmtree(temp_dir) - - -@contextmanager -def make_raw_temp_file(*args, **kwargs): - """ - Wraps tempfile.mkstemp to use it inside a with statement that auto deletes - the file after the with block closes - - - Parameters - ---------------------------------------------------------------------------- - :param args, kwargs: - arguments passed to mkstemp - - - :return: int, str - ---------------------------------------------------------------------------- - the file descriptor and the file path of the created temporary file - """ - fd, tmp_file_name = mkstemp(*args, **kwargs) - try: - yield (fd, tmp_file_name) - finally: - os_remove(tmp_file_name) - - -@contextmanager -def open_fd(*args, **kwargs): - """ - Wraps os.fdopen to use it inside a with statement that auto closes the - generated file descriptor after the with block closes - - - Parameters - ---------------------------------------------------------------------------- - :param args, kwargs: - arguments passed to os.fdopen - - - :return: TextIOWrapper - ---------------------------------------------------------------------------- - open file object connected to the file descriptor - """ - fp = os_fdopen(*args, **kwargs) - try: - yield fp - finally: - fp.close() - - -def term_proc(proc, timeout): - """ - helper function to terminate a process - - - Parameters - ---------------------------------------------------------------------------- - :param proc: process object - the process object that is going to be terminated - - :param timeout: dictionary - a dictionary (used as object reference) to set a flag that indicates - that the process is going to be terminated - """ - timeout["value"] = True - proc.terminate() - - -def uncrustify(unc_bin_path, cfg_file_path, unformatted_file_path, - lang=None, debug_file=None, check=False): - """ - executes Uncrustify and captures its stdout - - - Parameters - ---------------------------------------------------------------------------- - :param unc_bin_path: str - path to the Uncrustify binary - - :param cfg_file_path: str - path to a config file for Uncrustify - - :param unformatted_file_path: str - path to a file that is going to be formatted - - :param lang: str / None - Uncrustifys -l argument - - :param debug_file: str / None - Uncrustifys -p argument - - :param check: bool - Used to control whether Uncrustifys --check is going to be used - - - :return: str / None - ---------------------------------------------------------------------------- - returns the stdout from Uncrustify or None if the process takes to much - time (set to 5 sec) - """ - - args = [unc_bin_path, "-q", "-c", cfg_file_path, '-f', - unformatted_file_path] - if lang: - args.extend(("-l", lang)) - if debug_file: - args.extend(('-p', debug_file)) - if check: - args.append('--check') - - proc = Popen(args, stdout=PIPE, stderr=PIPE) - - timeout = {"value": False} - timer = Timer(5, term_proc, [proc, timeout]) - timer.start() - - output_b, error_txt_b = proc.communicate() - - timer.cancel() - - if timeout["value"]: - print("uncrustify proc timeout: %s" % ' '.join(args), file=stderr) - return None - - error = error_txt_b.decode("UTF-8") - if error: - print("Uncrustify %s stderr:\n %s" % (unformatted_file_path, error), - file=stderr) - - return output_b - - -def same_expected_generated(formatted_path, unc_bin_path, cfg_file_path, - input_path, lang=None): - """ - Calls uncrustify and compares its generated output with the content of a - file - - - Parameters - ---------------------------------------------------------------------------- - :param formatted_path: str - path to a file containing the expected content - - :params unc_bin_path, cfg_file_path, input_path, lang: str, str, str, - str / None - see uncrustify() - - - :return: bool - ---------------------------------------------------------------------------- - True if the strings match, False otherwise - """ - - expected_string = '' - with open(formatted_path, 'rb') as f: - expected_string = f.read() - - formatted_string = uncrustify(unc_bin_path, cfg_file_path, input_path, lang) - - return True if formatted_string == expected_string else False - - -def process_uncrustify(args): - """ - special wrapper for same_expected_generated() - - accesses global var(s): RESTULTSFLAG - - - Parameters - ---------------------------------------------------------------------------- - :param args: list / tuple< int, ... > - this function is intended to be called by multiprocessing.pool.map() - therefore all arguments are inside a list / tuple: - id: int - an index number needed by the caller to differentiate runs - - other parameters: - see same_expected_generated() - - - :return: tuple< int, RESTULTSFLAG > - ---------------------------------------------------------------------------- - returns a tuple containing the id and a RESTULTSFLAG, REMOVE if both - strings are equal, KEEP if not - """ - - id = args[0] - res = same_expected_generated(*args[1:]) - - return id, RESTULTSFLAG.REMOVE if res else RESTULTSFLAG.KEEP - - -def write_config_file(args): - """ - Writes all but one excluded option into a config file - - - Parameters - ---------------------------------------------------------------------------- - :param args: list / tuple< list< tuple< str, str > >, str, int > - this function is intended to be called by multiprocessing.pool.map() - therefore all arguments are inside a list / tuple: - - config_list: list< tuple< str, str > > - a list of tuples containing option names and values - - tmp_dir: str - path to a directory in which the config file is going to be - written - - exclude_idx: int - index for an option that is not going to be written into the - config file - """ - - config_list, tmp_dir, exclude_idx = args - - with open("%s%suncr-%d.cfg" % (tmp_dir, os_path_sep, exclude_idx), - 'w') as f: - print_config(config_list, target_file_obj=f, exclude_idx=exclude_idx) - - -def write_config_file2(args): - """ - Writes two option lists into a config file - - - Parameters - ---------------------------------------------------------------------------- - :param args: list< tuple< str, str > >, - list< tuple< str, str > >, str, int - this function is intended to be called by multiprocessing.pool.map() - therefore all arguments are inside a list / tuple: - - config_list: list< tuple< str, str > > - the first list of tuples containing option names and values - - test_list: list< tuple< str, str > > - the second list of tuples containing option names and values - - tmp_dir: str - path to a directory in which the config file is going to be - written - - idx: int - index that is going to be used for the filename - """ - - config_list0, config_list1, tmp_dir, idx = args - - with open("%s%suncr-r-%d.cfg" % (tmp_dir, os_path_sep, idx), 'w') as f: - print_config(config_list0, target_file_obj=f) - print("", end='\n', file=f) - print_config(config_list1, target_file_obj=f) - - -def gen_multi_combinations(elements, N): - """ - generator function that generates, based on a set of elements, all - combinations of 1..N elements - - - Parameters - ---------------------------------------------------------------------------- - :param elements: list / tuple - a list of elements from which the combinations will be generated - - :param N: - the max number of element in a combination - - - :return: list - ---------------------------------------------------------------------------- - yields a single combination of the elements - - >>> gen_multi_combinations(["a", "b", "c"], 3) - (a); (b); (c); (a,b); (a,c); (b,c); (a,b,c) - """ - - fields = len(elements) - if N > fields: - raise Exception("Error: N > len(options)") - if N <= 0: - raise Exception("Error: N <= 0") - - for n in range(1, N + 1): - yield combinations(elements, n) - - -def add_back(unc_bin_path, input_files, formatted_files, langs, options_r, - options_k, tmp_dir): - """ - lets Uncrustify format files with generated configs files until all - formatted files match their according expected files. - - Multiple config files are generated based on a (base) list of Uncrustify - options combined with additional (new) options derived from combinations of - another list of options. - - - accesses global var(s): RESTULTSFLAG - - - Parameters - ---------------------------------------------------------------------------- - :param unc_bin_path: str - path to the Uncrustify binary - - :param input_files: list / tuple< str > - a list containing paths to a files that are going to be formatted - - :param formatted_files: list / tuple< str > - a list containing paths to files containing the expected contents - - :param langs: list / tuple< str > / None - a list of languages the files, used as Uncrustifys -l argument - can be None or shorter than the amount of provided files - - :param options_r: list< tuple< str, str > > - the list of options from which combinations will be derived - - :param options_k: list< tuple< str, str > > - the (base) list of Uncrustify options - - :param tmp_dir: str - the directory in which the config files will be written to - - - :return: list< tuple< str, str > > / None - ---------------------------------------------------------------------------- - list of additional option that were needed to generate matching file - contents - """ - - lang_max_idx = -1 if langs is None else len(langs) - 1 - file_len = len(input_files) - - if len(formatted_files) != file_len: - raise Exception("len(input_files) != len(formatted_files)") - - for m_combination in gen_multi_combinations(options_r, len(options_r)): - for idx, (r_combination) in enumerate(m_combination): - write_config_file2((options_k, r_combination, tmp_dir, idx)) - - cfg_file_path = "%s%suncr-r-%d.cfg" % (tmp_dir, os_path_sep, idx) - res = [] - - for file_idx in range(file_len): - lang = None if idx > lang_max_idx else langs[file_idx] - - r = process_uncrustify( - (0, formatted_files[file_idx], unc_bin_path, cfg_file_path, - input_files[file_idx], lang)) - res.append(r[1]) - - # all files, flag = remove -> option can be removed -> equal output - if res.count(RESTULTSFLAG.REMOVE) == len(res): - return r_combination - return None - - -def sanity_raw_run(args): - """ - wrapper for same_expected_generated(), prints error message if the config - file does not generate the expected result - - Parameters - ---------------------------------------------------------------------------- - :param args: - see same_expected_generated - - - :return: - ---------------------------------------------------------------------------- - see same_expected_generated - """ - res = same_expected_generated(*args) - - if not res: - formatted_file_path = args[0] - config_file_path = args[2] - input_file_path = args[3] - - print("\nprovided config does not create formatted source file:\n" - " %s\n %s\n->| %s" - % (input_file_path, config_file_path, formatted_file_path), - file=stderr) - return res - - -def sanity_run(args): - """ - wrapper for same_expected_generated(), prints error message if the config - file does not generate the expected result - - - Parameters - ---------------------------------------------------------------------------- - :param args: - see same_expected_generated - - - :return: - ---------------------------------------------------------------------------- - see same_expected_generated - """ - res = same_expected_generated(*args) - - if not res: - formatted_file_path = args[0] - input_file_path = args[3] - - print("\ngenerated config does not create formatted source file:\n" - " %s\n %s" - % (input_file_path, formatted_file_path), file=stderr) - return res - - -def sanity_run_splitter(uncr_bin, config_list, input_files, formatted_files, - langs, tmp_dir, jobs): - """ - writes config option into a file and tests if every input file is formatted - so that is matches the content of the according expected file - - - Parameters - ---------------------------------------------------------------------------- - :param uncr_bin: str - path to the Uncrustify binary - - :param config_list: list< tuple< str, str > > - a list of tuples containing option names and values - - :param input_files: list / tuple< str > - a list containing paths to a files that are going to be formatted - - :param formatted_files: list / tuple< str > - a list containing paths to files containing the expected contents - - :param langs: list / tuple< str > / None - a list of languages the files, used as Uncrustifys -l argument - can be None or shorter than the amount of provided files - - :param tmp_dir: str - the directory in which the config files will be written to - - :param jobs: int - number of processes to use - - - :return: bool - ---------------------------------------------------------------------------- - True if all files generate correct results, False oterhwise - """ - - file_len = len(input_files) - if len(formatted_files) != file_len: - raise Exception("len(input_files) != len(formatted_files)") - - gen_cfg_path = path_join(tmp_dir, "gen.cfg") - with open(gen_cfg_path, 'w') as f: - print_config(config_list, target_file_obj=f) - - lang_max_idx = -1 if langs is None else len(langs) - 1 - args = [] - - for idx in range(file_len): - lang = None if idx > lang_max_idx else langs[idx] - - args.append((formatted_files[idx], uncr_bin, gen_cfg_path, - input_files[idx], lang)) - - pool = Pool(processes=jobs) - sr = pool.map(sanity_run, args) - - return False not in sr - - -def print_config(config_list, target_file_obj=stdout, exclude_idx=()): - """ - prints config options into a config file - - - Parameters - ---------------------------------------------------------------------------- - :param config_list: list< tuple< str, str > > - a list containing pairs of option names and option values - - :param target_file_obj: file object - see file param of print() - - :param exclude_idx: int / list< int > - index of option(s) that are not going to be printed - """ - - if not config_list: - return - config_list_len = len(config_list) - - # check if exclude_idx list is empty -> assign len - if type(exclude_idx) in (list, tuple) and not exclude_idx: - exclude_idx = [config_list_len] - else: - # sort it, unless it is an int -> transform into a list - try: - exclude_idx = sorted(exclude_idx) - except TypeError: - exclude_idx = [exclude_idx] - - # extracted first loop round: - # do not print '\n' for the ( here non-existing) previous line - if exclude_idx[0] != 0: - print("%s = %s" % (config_list[0][0].ljust(31, ' '), config_list[0][1]), - end='', file=target_file_obj) - # also print space if a single option was provided and it is going to be - # excluded. This is done in order to be able to differentiate between - # --empty-nochange and the case where all options can be removed - elif config_list_len == 1: - print(' ', end='', file=target_file_obj) - return - - start_idx = 1 - for end in exclude_idx: - end = min(end, config_list_len) - - for idx in range(start_idx, end): - print("\n%s = %s" - % (config_list[idx][0].ljust(31, ' '), config_list[idx][1]), - end='', file=target_file_obj) - - start_idx = min(end + 1, config_list_len) - - # after - for idx in range(start_idx, config_list_len): - print("\n%s = %s" - % (config_list[idx][0].ljust(31, ' '), config_list[idx][1]), - end='', file=target_file_obj) - - -def get_non_default_options(unc_bin_path, cfg_file_path): - """ - calls Uncrustify to generate a debug file from which a config only with - non default valued options are extracted - - accesses global var(s): NULL_DEV - - - Parameters - ---------------------------------------------------------------------------- - :param unc_bin_path: str - path to the Uncrustify binary - - :param cfg_file_path: str - path to a config file for Uncrustify - - - :return: list< str > - ---------------------------------------------------------------------------- - amount of lines in the provided and shortened config - """ - lines = [] - - with make_raw_temp_file(suffix='.unc') as (fd, file_path): - # make debug file - uncrustify(unc_bin_path, cfg_file_path, NULL_DEV, debug_file=file_path, - check=True) - - # extract non comment lines -> non default config lines - with open_fd(fd, 'r') as fp: - lines = fp.read().splitlines() - lines = [line for line in lines if not line[:1] == '#'] - - return lines - - -def parse_config_file(file_obj): - """ - Reads in a Uncrustify config file - - - Parameters - ---------------------------------------------------------------------------- - :param file_obj: - the file object of an opened config file - - - :return: list< tuple< str, str > > - ---------------------------------------------------------------------------- - a list containing pairs of option names and option values - """ - # dict used to only save the last option setting if the same option occurs - # multiple times, without this: - # optionA0 can be removed because optionA1 = s0, and - # optionA1 can be removed because optionA0 = s0 - # -> optionA0, optionA1 are both removed - config_map = OrderedDict() - - # special keys may not have this limitation, as for example - # 'set x y' and 'set x z' do not overwrite each other - special_keys = {'macro-open', 'macro-else', 'macro-close', 'set', 'type', - 'file_ext', 'define'} - special_list = [] - - for line in file_obj: - # cut comments - pound_pos = line.find('#') - if pound_pos != -1: - line = line[:pound_pos] - - split_pos = line.find('=') - if split_pos == -1: - split_pos = line.find(' ') - if split_pos == -1: - continue - - key = line[:split_pos].strip() - value = line[split_pos + 1:].strip() - - if key in special_keys: - special_list.append((key, value)) - else: - config_map[key] = value - - config_list = list(config_map.items()) - config_list += special_list - - return config_list - - -def count_lines(file_path): - """ - returns the count of lines in a file by counting '\n' chars - - Parameters - ---------------------------------------------------------------------------- - :param file_path: str - file in which the lines will be counted - - - :return: int - ---------------------------------------------------------------------------- - number a lines - """ - in_count = 0 - with open(file_path, 'r') as f: - in_count = f.read().count('\n') + 1 - return in_count - - -def reduce(options_list): - """ - Reduces the given options to a minimum - - accesses global var(s): FLAGS, RESTULTSFLAG, ERROR_CODE - - Parameters - ---------------------------------------------------------------------------- - :param options_list: list< tuple< str, str > > - the list of options that are going to be reduced - - :return: int, list< tuple< str, str > > - status return code, reduced options - """ - config_list_len = len(options_list) - ret_flag = ERROR_CODE.NONE - - file_count = len(FLAGS.input_file_path) - lang_max_idx = -1 if FLAGS.lang is None else len(FLAGS.lang) - 1 - - pool = Pool(processes=FLAGS.jobs) - with make_temp_directory() as tmp_dir: - # region sanity run ---------------------------------------------------- - args = [] - for idx in range(file_count): - lang = None if idx > lang_max_idx else FLAGS.lang[idx] - - args.append((FLAGS.formatted_file_path[idx], - FLAGS.uncrustify_binary_path, FLAGS.config_file_path, - FLAGS.input_file_path[idx], lang)) - sr = pool.map(sanity_raw_run, args) - del args[:] - - if False in sr: - return ERROR_CODE.SANITY0, [] - del sr[:] - - # endregion - # region config generator loop ----------------------------------------- - args = [] - - for e_idx in range(config_list_len): - args.append((options_list, tmp_dir, e_idx)) - pool.map(write_config_file, args) - - del args[:] - - # endregion - # region main loop ----------------------------------------------------- - args = [] - jobs = config_list_len * file_count - - for idx in range(jobs): - file_idx = idx // config_list_len - option_idx = idx % config_list_len - - cfg_file_path = "%s%suncr-%d.cfg" \ - % (tmp_dir, os_path_sep, option_idx) - lang = None if idx > lang_max_idx else FLAGS.lang[file_idx] - - args.append((idx, FLAGS.formatted_file_path[file_idx], - FLAGS.uncrustify_binary_path, cfg_file_path, - FLAGS.input_file_path[file_idx], lang)) - - results = pool.map(process_uncrustify, args) - del args[:] - # endregion - # region clean results ------------------------------------------------- - option_flags = [RESTULTSFLAG.NONE] * config_list_len - - for r in results: - idx = r[0] - flag = r[1] - - option_idx = idx % config_list_len - - if option_flags[option_idx] == RESTULTSFLAG.KEEP: - continue - - option_flags[option_idx] = flag - del results[:] - # endregion - - options_r = [options_list[idx] for idx, x in enumerate(option_flags) - if x == RESTULTSFLAG.REMOVE] - options_list = [options_list[idx] for idx, x in enumerate(option_flags) - if x == RESTULTSFLAG.KEEP] - - del option_flags[:] - - # region sanity run ---------------------------------------------------- - # options can be removed one at a time generating appropriate results, - # oddly enough sometimes a config generated this way can fail when a - # combination of multiple options is missing - s_flag = True - if options_r: - s_flag = sanity_run_splitter( - FLAGS.uncrustify_binary_path, options_list, - FLAGS.input_file_path, FLAGS.formatted_file_path, FLAGS.lang, - tmp_dir, FLAGS.jobs) - - if not s_flag: - ret_flag = ERROR_CODE.SANITY1 - print("\n\nstumbled upon complex option dependencies in \n" - " %s\n" - "trying to add back minimal amount of removed options\n" - % FLAGS.config_file_path, file=stderr) - - ret_options = add_back( - FLAGS.uncrustify_binary_path, FLAGS.input_file_path, - FLAGS.formatted_file_path, FLAGS.lang, options_r, - options_list, tmp_dir) - - if ret_options: - options_list.extend(ret_options) - - s_flag = sanity_run_splitter( - FLAGS.uncrustify_binary_path, options_list, - FLAGS.input_file_path, FLAGS.formatted_file_path, - FLAGS.lang, tmp_dir, FLAGS.jobs) - - if s_flag: - print("Success!", file=stderr) - ret_flag = ERROR_CODE.NONE - # endregion - return ret_flag, options_list if ret_flag == ERROR_CODE.NONE else [] - - -def reduce_mode(): - """ - the mode that minimizes a config file as much as possible - - accesses global var(s): FLAGS, ERROR_CODE - """ - ret_flag = ERROR_CODE.NONE - option_list = {} - - # gen & parse non default config - lines = get_non_default_options(FLAGS.uncrustify_binary_path, - FLAGS.config_file_path) - option_list = parse_config_file(lines) - config_list_len = len(option_list) - - config_lines_init = count_lines(FLAGS.config_file_path) - config_lines_ndef = len(lines) - del lines[:] - - # early return if all options are already removed at this point - if config_list_len == 0: - if not FLAGS.empty_nochange \ - or (config_lines_init - config_lines_ndef) > 0: - if not FLAGS.quiet: - print("\n%s" % '# '.ljust(78, '-')) - - print(" ") - - if not FLAGS.quiet: - print("%s" % '# '.ljust(78, '-')) - print("# initial config lines: %d,\n" - "# default options and unneeded lines: %d,\n" - "# unneeded options: 0,\n" - "# kept options: 0" - % (config_lines_init, config_lines_init)) - print("ret_flag: 0", file=stderr) - return ERROR_CODE.NONE - - # gen reduced options - config_lines_redu = -1 - for i in range(FLAGS.passes): - old_config_lines_redu = config_lines_redu - - ret_flag, option_list = reduce(option_list) - config_lines_redu = len(option_list) - - if ret_flag != ERROR_CODE.NONE \ - or config_lines_redu == old_config_lines_redu: - break - - if ret_flag == ERROR_CODE.NONE: - # use the debug file trick again to get correctly sorted options - with make_raw_temp_file(suffix='.unc') as (fd, file_path): - with open_fd(fd, 'w') as f: - print_config(option_list, target_file_obj=f) - - lines = get_non_default_options(FLAGS.uncrustify_binary_path, - file_path) - option_list = parse_config_file(lines) - - # print output + stats - if not FLAGS.empty_nochange or config_lines_ndef != config_lines_redu: - if not FLAGS.quiet: - print("\n%s" % '# '.ljust(78, '-')) - - print_config(option_list) - - if not FLAGS.quiet: - print("\n%s" % '# '.ljust(78, '-')) - print("# initial config lines: %d,\n" - "# default options and unneeded lines: %d,\n" - "# unneeded options: %d,\n" - "# kept options: %d" - % (config_lines_init, - config_lines_init - config_lines_ndef, - config_lines_ndef - config_lines_redu, - config_lines_redu)) - - print("ret_flag: %d" % ret_flag, file=stderr) - return ret_flag - - -def no_default_mode(): - """ - the mode removes all unnecessary lines and options with default values - - accesses global var(s): FLAGS, ERROR_CODE - """ - - lines = get_non_default_options(FLAGS.uncrustify_binary_path, - FLAGS.config_file_path, ) - config_lines_ndef = len(lines) - config_lines_init = count_lines(FLAGS.config_file_path) - - if not FLAGS.empty_nochange or (config_lines_ndef != config_lines_init): - if not FLAGS.quiet: - print("%s" % '# '.ljust(78, '-')) - - options_str = '\n'.join(lines) - if not options_str: - print(" ") - else: - print(options_str, file=stdout) - - if not FLAGS.quiet: - print("%s" % '# '.ljust(78, '-')) - print("# initial config lines: %d,\n" - "# default options and unneeded lines: %d,\n" - % (config_lines_init, config_lines_init - config_lines_ndef)) - - return ERROR_CODE.NONE - - -def main(): - """ - calls the mode that was specified by the -m script argument, - defaults to reduce_mode if not provided or unknown mode - - accesses global var(s): MODES, FLAGS - - - :return: int - ---------------------------------------------------------------------------- - return code - """ - if FLAGS.mode == MODES[1]: - return no_default_mode() - - return reduce_mode() - - -def valid_file(arg_parser, *args): - """ - checks if on of the provided paths is a file - - - Parameters - ---------------------------------------------------------------------------- - :param arg_parser: - argument parser object that is called if no file is found - - :param args: list< str > - a list of file path that is going to be checked - - - :return: str - ---------------------------------------------------------------------------- - path to an existing file - """ - arg = None - found_flag = False - for arg in args: - if exists(arg): - found_flag = True - break - if not found_flag: - arg_parser.error("file(s) do not exist: %s" % args) - - return arg - - -if __name__ == "__main__": - """ - parses all script arguments and calls main() - - accesses global var(s): FLAGS, ERROR_CODE, MODES - """ - arg_parser = argparse.ArgumentParser() - - group_general = arg_parser.add_argument_group( - 'general options', 'Options used by both modes') - - group_general.add_argument( - '-q', '--quiet', - default=False, - action='store_true', - help='Whether or not messages, other than the actual config output, ' - 'should be printed to stdout.' - ) - group_general.add_argument( - '--empty-nochange', - default=False, - action='store_true', - help='Do not print anything to stdout if no options could be removed' - ) - group_general.add_argument( - '-m', '--mode', - type=str, - choices=MODES, - default=MODES[0], - help="The script operation mode. Defaults to '%s'" % MODES[0] - ) - group_general.add_argument( - '-b', '--uncrustify_binary_path', - metavar='<path>', - type=lambda x: valid_file( - arg_parser, x, - "../build/uncrustify.exe", - "../build/Debug/uncrustify", - "../build/Debug/uncrustify.exe", - "../build/Release/uncrustify", - "../build/Release/uncrustify.exe"), - default="../build/uncrustify", - help="The Uncrustify binary file path. Is searched in known locations " - "in the 'Uncrustify/build/' directory if no <path> is provided." - ) - group_general.add_argument( - '-c', '--config_file_path', - metavar='<path>', - type=lambda x: valid_file(arg_parser, x), - required=True, - help='Path to the config file.' - ) - - group_reduce = arg_parser.add_argument_group( - 'reduce mode', 'Options to reduce configuration file options') - - group_reduce.add_argument( - '-i', '--input_file_path', - metavar='<path>', - type=lambda x: valid_file(arg_parser, x), - nargs='+', - action='append', - help="Path to the unformatted source file. " - "Required if mode '%s' is used" % MODES[0] - ) - group_reduce.add_argument( - '-f', '--formatted_file_path', - metavar='<path>', - type=lambda x: valid_file(arg_parser, x), - nargs='+', - action='append', - help="Path to the formatted source file. " - "Required if mode '%s' is used" % MODES[0] - ) - group_reduce.add_argument( - '-l', '--lang', - metavar='<str>', - nargs='+', - required=False, - action='append', - help='Uncrustify processing language for each input file' - ) - group_reduce.add_argument( - '-j', '--jobs', - metavar='<nr>', - type=int, - default=cpu_count(), - help='Number of concurrent jobs.' - ) - group_reduce.add_argument( - '-p', '--passes', - metavar='<nr>', - type=int, - default=5, - help='Max. number of cleaning passes.' - ) - - group_no_default = arg_parser.add_argument_group( - 'no-default mode', 'Options to remove configuration file option with ' - 'default values: ~~_Currently only the general' - ' options are used for this mode_~~') - FLAGS, unparsed = arg_parser.parse_known_args() - - if FLAGS.lang is not None: - FLAGS.lang = [j for i in FLAGS.lang for j in i] - - if FLAGS.mode == MODES[0]: - if not FLAGS.input_file_path or not FLAGS.formatted_file_path: - arg_parser.error("Flags -f and -i are required in Mode '%s'!" - % MODES[0]) - sys_exit(ERROR_CODE.FLAGS) - - # flatten 2 dimensional args: -f p -f p -f p -f p0 p1 p2 -> [[],[], ...] - FLAGS.input_file_path = [j for i in FLAGS.input_file_path for j in i] - - FLAGS.formatted_file_path = [j for i in - FLAGS.formatted_file_path for j in i] - - if len(FLAGS.input_file_path) != len(FLAGS.formatted_file_path): - print("Unequal amount of input and formatted file paths.", - file=stderr) - sys_exit(ERROR_CODE.FLAGS) - - sys_exit(main()) |