def main(args=None):
    if sys.version_info < (3,):
        sys.exit('table-generator needs Python 3 to run.')
    signal.signal(signal.SIGINT, sigint_handler)

    arg_parser = create_argument_parser()
    options = arg_parser.parse_args((args or sys.argv)[1:])

    logging.basicConfig(format="%(levelname)s: %(message)s",
                        level=logging.WARNING if options.quiet else logging.INFO)

    global parallel
    import concurrent.futures
    cpu_count = 1
    try:
        cpu_count = os.cpu_count() or 1
    except __HOLE__:
        pass
    # Use up to cpu_count*2 workers because some tasks are I/O bound.
    parallel = concurrent.futures.ProcessPoolExecutor(max_workers=cpu_count*2)

    name = options.output_name
    outputPath = options.outputPath
    if outputPath == '-':
        # write to stdout
        outputFilePattern = '-'
        outputPath = '.'
    else:
        outputFilePattern = "{name}.{type}.{ext}"

    if options.xmltablefile:
        if options.tables:
            arg_parser.error("Invalid additional arguments '{}'.".format(" ".join(options.tables)))
        runSetResults = parse_table_definition_file(options.xmltablefile, options)
        if not name:
            name = basename_without_ending(options.xmltablefile)

        if not outputPath:
            outputPath = os.path.dirname(options.xmltablefile)

    else:
        if options.tables:
            inputFiles = options.tables
        else:
            searchDir = outputPath or DEFAULT_OUTPUT_PATH
            logging.info("Searching result files in '%s'...", searchDir)
            inputFiles = [os.path.join(searchDir, '*.results*.xml')]

        inputFiles = Util.extend_file_list(inputFiles) # expand wildcards
        runSetResults = parallel.map(load_result,
                                     inputFiles, itertools.repeat(options))

        if len(inputFiles) == 1:
            if not name:
                name = basename_without_ending(inputFiles[0])
            if not outputFilePattern == '-':
                outputFilePattern = "{name}.{ext}"
        else:
            if not name:
                name = NAME_START + "." + time.strftime("%Y-%m-%d_%H%M", time.localtime())

        if inputFiles and not outputPath:
            path = os.path.dirname(inputFiles[0])
            if not "://" in path and all(path == os.path.dirname(file) for file in inputFiles):
                outputPath = path
            else:
                outputPath = DEFAULT_OUTPUT_PATH

    if not outputPath:
        outputPath = '.'

    runSetResults = [r for r in runSetResults if r is not None]
    if not runSetResults:
        logging.error('No benchmark results found.')
        exit(1)

    logging.info('Merging results...')
    if options.common:
        find_common_tasks(runSetResults)
    else:
        # merge list of run sets, so that all run sets contain the same tasks
        merge_tasks(runSetResults)

    rows     = get_rows(runSetResults)
    if not rows:
        logging.warning('No results found, no tables produced.')
        exit()
    rowsDiff = filter_rows_with_differences(rows) if options.write_diff_table else []

    logging.info('Generating table...')
    if not os.path.isdir(outputPath) and not outputFilePattern == '-':
        os.makedirs(outputPath)
    futures = create_tables(name, runSetResults, rows, rowsDiff, outputPath, outputFilePattern, options)

    if options.dump_counts: # print some stats for Buildbot
        print("REGRESSIONS {}".format(get_regression_count(rows, options.ignoreFlappingTimeouts)))
        countsList = get_counts(rows)
        print("STATS")
        for counts in countsList:
            print(" ".join(str(e) for e in counts))

    for f in futures:
        f.result() # to get any exceptions that may have occurred
    logging.info('done')

    parallel.shutdown(wait=True)
dataset/ETHPy150Open sosy-lab/benchexec/benchexec/tablegenerator/__init__.py/main