mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-11-04 01:08:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			310 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			310 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python
 | 
						|
 | 
						|
from __future__ import with_statement
 | 
						|
from string import Template
 | 
						|
import re, fnmatch, os
 | 
						|
 | 
						|
VERSION = "0.10.0"
 | 
						|
 | 
						|
TEST_FUNC_REGEX = r"^(void\s+(test_%s__(\w+))\(\s*void\s*\))\s*\{"
 | 
						|
 | 
						|
EVENT_CB_REGEX = re.compile(
 | 
						|
    r"^(void\s+clar_on_(\w+)\(\s*void\s*\))\s*\{",
 | 
						|
    re.MULTILINE)
 | 
						|
 | 
						|
SKIP_COMMENTS_REGEX = re.compile(
 | 
						|
    r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
 | 
						|
    re.DOTALL | re.MULTILINE)
 | 
						|
 | 
						|
CLAR_HEADER = """
 | 
						|
/*
 | 
						|
 * Clar v%s
 | 
						|
 *
 | 
						|
 * This is an autogenerated file. Do not modify.
 | 
						|
 * To add new unit tests or suites, regenerate the whole
 | 
						|
 * file with `./clar`
 | 
						|
 */
 | 
						|
""" % VERSION
 | 
						|
 | 
						|
CLAR_EVENTS = [
 | 
						|
    'init',
 | 
						|
    'shutdown',
 | 
						|
    'test',
 | 
						|
    'suite'
 | 
						|
]
 | 
						|
 | 
						|
def main():
 | 
						|
    from optparse import OptionParser
 | 
						|
 | 
						|
    parser = OptionParser()
 | 
						|
 | 
						|
    parser.add_option('-c', '--clar-path', dest='clar_path')
 | 
						|
    parser.add_option('-v', '--report-to', dest='print_mode', default='default')
 | 
						|
 | 
						|
    options, args = parser.parse_args()
 | 
						|
 | 
						|
    for folder in args or ['.']:
 | 
						|
        builder = ClarTestBuilder(folder,
 | 
						|
            clar_path = options.clar_path,
 | 
						|
            print_mode = options.print_mode)
 | 
						|
 | 
						|
        builder.render()
 | 
						|
 | 
						|
 | 
						|
class ClarTestBuilder:
 | 
						|
    def __init__(self, path, clar_path = None, print_mode = 'default'):
 | 
						|
        self.declarations = []
 | 
						|
        self.suite_names = []
 | 
						|
        self.callback_data = {}
 | 
						|
        self.suite_data = {}
 | 
						|
        self.event_callbacks = []
 | 
						|
 | 
						|
        self.clar_path = os.path.abspath(clar_path) if clar_path else None
 | 
						|
 | 
						|
        self.path = os.path.abspath(path)
 | 
						|
        self.modules = [
 | 
						|
            "clar_sandbox.c",
 | 
						|
            "clar_fixtures.c",
 | 
						|
            "clar_fs.c"
 | 
						|
        ]
 | 
						|
 | 
						|
        self.modules.append("clar_print_%s.c" % print_mode)
 | 
						|
 | 
						|
        print("Loading test suites...")
 | 
						|
 | 
						|
        for root, dirs, files in os.walk(self.path):
 | 
						|
            module_root = root[len(self.path):]
 | 
						|
            module_root = [c for c in module_root.split(os.sep) if c]
 | 
						|
 | 
						|
            tests_in_module = fnmatch.filter(files, "*.c")
 | 
						|
 | 
						|
            for test_file in tests_in_module:
 | 
						|
                full_path = os.path.join(root, test_file)
 | 
						|
                test_name = "_".join(module_root + [test_file[:-2]])
 | 
						|
 | 
						|
                with open(full_path) as f:
 | 
						|
                    self._process_test_file(test_name, f.read())
 | 
						|
 | 
						|
        if not self.suite_data:
 | 
						|
            raise RuntimeError(
 | 
						|
                'No tests found under "%s"' % path)
 | 
						|
 | 
						|
    def render(self):
 | 
						|
        main_file = os.path.join(self.path, 'clar_main.c')
 | 
						|
        with open(main_file, "w") as out:
 | 
						|
            out.write(self._render_main())
 | 
						|
 | 
						|
        header_file = os.path.join(self.path, 'clar.h')
 | 
						|
        with open(header_file, "w") as out:
 | 
						|
            out.write(self._render_header())
 | 
						|
 | 
						|
        print ('Written Clar suite to "%s"' % self.path)
 | 
						|
 | 
						|
    #####################################################
 | 
						|
    # Internal methods
 | 
						|
    #####################################################
 | 
						|
 | 
						|
    def _render_cb(self, cb):
 | 
						|
        return '{"%s", &%s}' % (cb['short_name'], cb['symbol'])
 | 
						|
 | 
						|
    def _render_suite(self, suite):
 | 
						|
        template = Template(
 | 
						|
r"""
 | 
						|
    {
 | 
						|
        "${clean_name}",
 | 
						|
        ${initialize},
 | 
						|
        ${cleanup},
 | 
						|
        ${cb_ptr}, ${cb_count}
 | 
						|
    }
 | 
						|
""")
 | 
						|
 | 
						|
        callbacks = {}
 | 
						|
        for cb in ['initialize', 'cleanup']:
 | 
						|
            callbacks[cb] = (self._render_cb(suite[cb])
 | 
						|
                if suite[cb] else "{NULL, NULL}")
 | 
						|
 | 
						|
        return template.substitute(
 | 
						|
            clean_name = suite['name'].replace("_", "::"),
 | 
						|
            initialize = callbacks['initialize'],
 | 
						|
            cleanup = callbacks['cleanup'],
 | 
						|
            cb_ptr = "_clar_cb_%s" % suite['name'],
 | 
						|
            cb_count = suite['cb_count']
 | 
						|
        ).strip()
 | 
						|
 | 
						|
    def _render_callbacks(self, suite_name, callbacks):
 | 
						|
        template = Template(
 | 
						|
r"""
 | 
						|
static const struct clar_func _clar_cb_${suite_name}[] = {
 | 
						|
    ${callbacks}
 | 
						|
};
 | 
						|
""")
 | 
						|
        callbacks = [
 | 
						|
            self._render_cb(cb)
 | 
						|
            for cb in callbacks
 | 
						|
            if cb['short_name'] not in ('initialize', 'cleanup')
 | 
						|
        ]
 | 
						|
 | 
						|
        return template.substitute(
 | 
						|
            suite_name = suite_name,
 | 
						|
            callbacks = ",\n\t".join(callbacks)
 | 
						|
        ).strip()
 | 
						|
 | 
						|
    def _render_event_overrides(self):
 | 
						|
        overrides = []
 | 
						|
        for event in CLAR_EVENTS:
 | 
						|
            if event in self.event_callbacks:
 | 
						|
                continue
 | 
						|
 | 
						|
            overrides.append(
 | 
						|
                "#define clar_on_%s() /* nop */" % event
 | 
						|
            )
 | 
						|
 | 
						|
        return '\n'.join(overrides)
 | 
						|
 | 
						|
    def _render_header(self):
 | 
						|
        template = Template(self._load_file('clar.h'))
 | 
						|
 | 
						|
        declarations = "\n".join(
 | 
						|
            "extern %s;" % decl
 | 
						|
            for decl in sorted(self.declarations)
 | 
						|
        )
 | 
						|
 | 
						|
        return template.substitute(
 | 
						|
            extern_declarations = declarations,
 | 
						|
        )
 | 
						|
 | 
						|
    def _render_main(self):
 | 
						|
        template = Template(self._load_file('clar.c'))
 | 
						|
        suite_names = sorted(self.suite_names)
 | 
						|
 | 
						|
        suite_data = [
 | 
						|
            self._render_suite(self.suite_data[s])
 | 
						|
            for s in suite_names
 | 
						|
        ]
 | 
						|
 | 
						|
        callbacks = [
 | 
						|
            self._render_callbacks(s, self.callback_data[s])
 | 
						|
            for s in suite_names
 | 
						|
        ]
 | 
						|
 | 
						|
        callback_count = sum(
 | 
						|
            len(cbs) for cbs in self.callback_data.values()
 | 
						|
        )
 | 
						|
 | 
						|
        return template.substitute(
 | 
						|
            clar_modules = self._get_modules(),
 | 
						|
            clar_callbacks = "\n".join(callbacks),
 | 
						|
            clar_suites = ",\n\t".join(suite_data),
 | 
						|
            clar_suite_count = len(suite_data),
 | 
						|
            clar_callback_count = callback_count,
 | 
						|
            clar_event_overrides = self._render_event_overrides(),
 | 
						|
        )
 | 
						|
 | 
						|
    def _load_file(self, filename):
 | 
						|
        if self.clar_path:
 | 
						|
            filename = os.path.join(self.clar_path, filename)
 | 
						|
            with open(filename) as cfile:
 | 
						|
                return cfile.read()
 | 
						|
 | 
						|
        else:
 | 
						|
            import zlib, base64, sys
 | 
						|
            content = CLAR_FILES[filename]
 | 
						|
 | 
						|
            if sys.version_info >= (3, 0):
 | 
						|
                content = bytearray(content, 'utf_8')
 | 
						|
                content = base64.b64decode(content)
 | 
						|
                content = zlib.decompress(content)
 | 
						|
                return str(content)
 | 
						|
            else:
 | 
						|
                content = base64.b64decode(content)
 | 
						|
                return zlib.decompress(content)
 | 
						|
 | 
						|
    def _get_modules(self):
 | 
						|
        return "\n".join(self._load_file(f) for f in self.modules)
 | 
						|
 | 
						|
    def _skip_comments(self, text):
 | 
						|
        def _replacer(match):
 | 
						|
            s = match.group(0)
 | 
						|
            return "" if s.startswith('/') else s
 | 
						|
 | 
						|
        return re.sub(SKIP_COMMENTS_REGEX, _replacer, text)
 | 
						|
 | 
						|
    def _process_test_file(self, suite_name, contents):
 | 
						|
        contents = self._skip_comments(contents)
 | 
						|
 | 
						|
        self._process_events(contents)
 | 
						|
        self._process_declarations(suite_name, contents)
 | 
						|
 | 
						|
    def _process_events(self, contents):
 | 
						|
        for (decl, event) in EVENT_CB_REGEX.findall(contents):
 | 
						|
            if event not in CLAR_EVENTS:
 | 
						|
                continue
 | 
						|
 | 
						|
            self.declarations.append(decl)
 | 
						|
            self.event_callbacks.append(event)
 | 
						|
 | 
						|
    def _process_declarations(self, suite_name, contents):
 | 
						|
        callbacks = []
 | 
						|
        initialize = cleanup = None
 | 
						|
 | 
						|
        regex_string = TEST_FUNC_REGEX % suite_name
 | 
						|
        regex = re.compile(regex_string, re.MULTILINE)
 | 
						|
 | 
						|
        for (declaration, symbol, short_name) in regex.findall(contents):
 | 
						|
            data = {
 | 
						|
                "short_name" : short_name,
 | 
						|
                "declaration" : declaration,
 | 
						|
                "symbol" : symbol
 | 
						|
            }
 | 
						|
 | 
						|
            if short_name == 'initialize':
 | 
						|
                initialize = data
 | 
						|
            elif short_name == 'cleanup':
 | 
						|
                cleanup = data
 | 
						|
            else:
 | 
						|
                callbacks.append(data)
 | 
						|
 | 
						|
        if not callbacks:
 | 
						|
            return
 | 
						|
 | 
						|
        tests_in_suite = len(callbacks)
 | 
						|
 | 
						|
        suite = {
 | 
						|
            "name" : suite_name,
 | 
						|
            "initialize" : initialize,
 | 
						|
            "cleanup" : cleanup,
 | 
						|
            "cb_count" : tests_in_suite
 | 
						|
        }
 | 
						|
 | 
						|
        if initialize:
 | 
						|
            self.declarations.append(initialize['declaration'])
 | 
						|
 | 
						|
        if cleanup:
 | 
						|
            self.declarations.append(cleanup['declaration'])
 | 
						|
 | 
						|
        self.declarations += [
 | 
						|
            callback['declaration']
 | 
						|
            for callback in callbacks
 | 
						|
        ]
 | 
						|
 | 
						|
        callbacks.sort(key=lambda x: x['short_name'])
 | 
						|
        self.callback_data[suite_name] = callbacks
 | 
						|
        self.suite_data[suite_name] = suite
 | 
						|
        self.suite_names.append(suite_name)
 | 
						|
 | 
						|
        print("  %s (%d tests)" % (suite_name, tests_in_suite))
 | 
						|
 | 
						|
 | 
						|
 | 
						|
CLAR_FILES = {
 | 
						|
"clar.c" : r"""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""",
 | 
						|
"clar_print_default.c" : r"""eJyFU01P4zAQPSe/YqgU1a5Cuadi98ap4rLaE6DIxA5YSu3InnQPK/479jgFB9FycuZ53vObj5QeBeoOjlZL6Abh2tFpg602Gln4AFQe285OBmuIsZ80qhPQWeMRulfhYJMujDgoz8v/ZcGiJP+k78qCpHu22lshlYRKJjXfQOUfzaqG+CJfvJCrZgp/UDhUMpAC+laWZ6rwrxNK+8/8XEkElHPWJeBcBQnKmB9YRt6Vn0YfTfJYkCunRuuwpVzPLlqnHPJtpsOp0x7d1GFKowTY0EF2T09CaCyHO6GHyamG+hokeO6q8k1TeWCV5/AQgko+wcM1hiOml0VBqte/qNAsjr2I4cpYkMp3To+o7YLS6yFnDNqE8U2HZ+W+6MzowhecFmHOS009+BfK0j2w+SJ7HK5u4f7vfs+D/DmdLJ0vp3N5f6yJTlm+5sl62Me0M1klCehD35X8uj+RsFsixMlWuuqC38SG37C+W0MD6+36B380Ifb9f0gmbjZgrB1hc7Pc3uTokrR4Dru6kA6DqGG73ZLwUbSDDlfCvYw7Cn38KVmMa0gzK479XJ5HGWZBeE0UnjjKSDaHb+U7mrWGAw==""",
 | 
						|
"clar_print_tap.c" : r"""eJyNVMFu2zAMPVtfwbgIYBu2gWK3BmuxnYthh+02wFBtORXmSIYkZxiG/vso2m6lJF12skk9ko+PlJh13MkWjlp20A7cNKORyjVSSZfhDzhhXdPqSbkSvG0n6cTqaLWyDtpnbqCYDxQ/CJuzPyzJfMr8LXy3ugLgiW/FEYU+S799+gpHYazUCm4//FBpvmMvjL1D2T5PrtO/1HXa3iGM0WZ2/A/d2BcE7xhLZA/ZJkqYvPZwAyO3VnTAhwG2HRHLbI7NlAFJbCwRgxVRYM/lgIEYxA9a7U+jg4IlxiVxtjXNbV1vu/Nq78tIaUlDNR3WEVtnptbNMAJAQZ9AOkR7Lda6AFVVzSMLfDhzy/cC7mBr35qo7udeDnYfw63A8Uv3+460OMtGowE4y0b+GOqbhwtQ74+RPYp+Cen9MXKQakV2IdL7G5TjSZh8XY/lqBO2NXJ0fqM3H+HL98fHcFkAAsApgeAoj5Wu6/ra5dCKVie8sLQP/hrOF2I2ifXsmNePJryW2lq/hNVCDIkvK/oAqdIO9M8UxUjx48/ChK8mlmMJ0SdyRozaLDtnsysd0Fizy29ORPMGiqJAkv5DCga4f5fgT0gnKoE7WXqBqcCRN4PEI272445MzIQB3i5hWd9+oWHxNZrwtUk/o0iAvxug/T2eAqiET5HPOYXqssV8YX8BFTvXlQ==""",
 | 
						|
"clar_sandbox.c" : r"""eJyNVV1P20AQfLZ/xRIkYpNATItaVSkPlaBVVEoiEgQSRJaxz+SEfY7uLmkD4r931+fEHwRahBST3Zudmb0xSgeahxDOAgl+mATSnwd6dnvsffk07du2MmUutM2VvwwSHvk6nedNTpgJpc3RffrCtZ9tazz5NvEnoDSetngMDkE4VO7CntIu7JyA59qWJZleSAHeum9n7A/Gp4NLPHCotJ9mEXObfcWzE4QhU6pAvfaHP104Idi+/VLjHHNR5ZszvV/EMZNdUPyJ+RoSJh4M9V0ei4jF4F8PLj5+sK0Cx6gsupdoUJgthIYTOO43egw+E0s0SqrbKfagIVZr8muEulpdoKf848x8Xo3PLkeXw++D87OWDdYLSgSrmMRJb5xJcDjieH3g8LUc34dOh7s5fGM2Nj8wjQ/OhgifojGWMRm/JFPplOZiwWhKXnm9Xmo1I1CmFOF85ay9w1J37RxBV5ZkWS82/tpWbx8GMegZo24uM5EytC3KmBJt9DNYQSBWesbFQxe0XIHOYKEY9HA+7PfsN0i1qN4qeDVpmWKNWYUYktpliWIG+gfTE5bORwTqnF4PL09dc6wLBq5x+XaZiHhsdE1mXIFaKc3SjaCEPzIUUNNC4sOFlLlwLlmoMyy+I+7wTWWH78la/3lwVA3AMuMR5JFeCBWI6D7749B3eUyJQCXv3pQC1L7z2qVqvBoYiWoiwhmqQJZIs2JIrHyZVsCaKUQ/eRL5BQWjdMOjcnup4OuAJ3lyWjkeWXOT/7QobZvIrl8a9YCXHEy8s7hKy8UAVd885JZtIRhOQ7/xoS6iqf4ZcPUikyku7YnldGnRo+F4cAOY1N+BjEAlgZoxlS+5EmXrVZRJRBni5j54sY+7fB+W1ShBu9feRG2ziAYGKTuAoym9cbHfDKrXO50SjO7R+tqVXdAhpt1yOducxTHYtMUyYpQ+Ykzmvvrndhr/GMx6DAJdu+px77PnbT1QCTieosE1nujpxdX5+atDhYFlquoXOEf4/wjB3t62O7/9/hGKyVWV6FYvavT+AhbcW38=""",
 | 
						|
"clar_fixtures.c" : r"""eJyFUV1LwzAUfW5+xZU9rLUVJ4ggZQ9DFAUfZEwQSglZmrBAl5Qkk6n43236tWbKfMvNOfecc+81llhBgSppLNAN0XCOuNjbnWa4InYTjpE1MSzxuD1Vki2L0BcKTKfn0EYgu57d3uRpjYhPhi1opSwumUwRCvo3zMFYXT9C5xA5stWSVh9hI5FAa+wUFG//osgJCA5tmQ1SF3CVw9kcppfTCAWBj8ZxDg3UN4/zZ7MaHBrHSBw7vpcJ4mGS5Ijtai9qnannNqk1q7myXU+KvhGaCF4wDnfPiyV+eHpbvS7v8cti9YjGq6Yl7lzCkxfo1L0j/lJOwOtrUrwrUcDBBRsii7Xan3bjBlNVL2WUzuMkgGlJdLuIP21oyYjcVf/a6G3ozXTQPRqmsZkwWQiOfgAVGffP""",
 | 
						|
"clar_fs.c" : r"""eJylVdtu20YQfSa/YkAD8TKWY8dJX6L0wXDEVqgsBhINN7UFhiGX1qIkl9hd+dLG/57ZCynJUWEkfZE0s7NnZufMGe2xsqAlpJfj6ZsT399DgzUUojhKo8npb3Mg+ud8PBlNE/hq/NP4LJ5G49n5aTKOp71zNJvFs4vx06DzPz6MZ6HvS5UplkO+zAS89EtWUd7KtM3UkuS8kcqdGE/o/+t71tYm/ArTi8lk6HuS/UNTBRVtbtRyAGzo+x4rgaQ2zMaFvucJqlaicdd8z15AHKkE/rbxIQI6+DqrKp4TF3YAJ2GH/AxwTeu8fTBRA0jtl0Xp0K+sucAsx9suzPPauX2v5AIIMxYweO9AhnBwwELAbvTFXLGFrmf/aF+X4/Uu2L++3scEjwjmitRnQ/+x7/0tZ0XXecIaBTUv6AC22i/5SuRPnQWVynAy/z3CSYg/zpPZxVkCJQLp4m2YvYqVbJHrEHU7bJgG+y7IZNBQf1HBz2nNxQN5oeEHoDnnJdlOHYa2aa18dRetmlxziI8ZOl8bCV5ruk3u3ptw9OlUnaeMquxGorOfd/OcKs2kpEKlBFuMibHUuKUCm8gbW1aoOTge4HFwyZqC30l4EgdlhmYR+J4tVVBK1q0wpnv0U4JkKmqygxTDQEdfFKcfRpNRMsKx6zgzM7oLL+c4oz9A80aSs/jjp40U6bpmA46t0vgVzZpVS7TLApg3lOwe55A6ivMqE04hwcsgtCB7tJK0KxdH0pdLWlUpXylii3IVZuLm9mphsPXg6gsrqeXECtwH+Kl7jF96sLj4m6z1i773cGw1VLYCb5dEqoIKodnzgvmDVLQGtLl4B5/t7c+Q40ZwFL66bgLNmUfvmSKHr0Onsg5eT4LFp/c0vyWm1uPFwBTdBd9lTGGwvjCAF7b+Ad4b9mq9HP05TubJaXIxJ/b8f3DZU2lNU9Ivi+G2VNcL1dopLh3dt17IuC0LpHVDwuvA9TLtT21LrHm1EXlo9ly/s/4rwC5C1z00g6MvrDnK22DovCYoOJz1jpPFpsaN6412udkJndTNwdtF/zdiFF6vpMJxlNKIfD12hjQj7MiwD4qD7jkovbfcSEvtlVlTfOH3uxX+rKg3NL3B0dvFrh6I+rselNtN6F68oxk/+2araVBLuv3SZ6RvZL5q3BVi9r52bTgeUfZNwUr/G9kaoSs=""",
 | 
						|
"clar.h" : r"""eJy9VU1P4zAQPZNfYZo9JJUFlCMLSAi1AqlCKyjavVmO4xBrEyfYztLVav874yRtmq922QOX1pnxzHvOe+O4IpIhjxAht8ubR7KaP63IHSGOC0EheS/uuEKypAg5utQmTERwEl87zq9MhIglVBFCtebKeM6RkAaxTIbCiExi5wjWGiIxVWgaiYTjaksCKJ0sVypTnVjINVMir3vZQh1nRRISGmTK+F8HOBD+WtCEaG+3Dx5/gKa9ADQe6ys8WzBUNNRl04ZobghLOJVF7pUxb1o/+tXz1MeoWmQ5fS14Q4FEulVq27oisvKVIi3uf6yeH+fk283qztnlYEvF2hSKe20VyhiRNG2h1GFNZRhk64+UbNjtKXE5WCJynNPp1EFTdFO+UlAVpZSpTKM3YWLE13kimDCotAJKudb0hcP+060xATUttCE5iEI8KFAYWZP4bR+WGR9dX6EzDGZe3C/nhNjV8v6hXE0WhWQlAUaTBEUUrBleoAlym54YzfwesN15GPhyFHe+zjkzPERRi4DJSg4HGNROPAh/PH5uwFfwXi2w0EhmBhlV8CHcjVa3MWc//0MnZus+Sagzv4/8yUoNUfgEoc78A0Mls38cp5rS0IQ9PC+Xw6PQKdp9572i+ujbirabq+3jpjt0jsZuDULfgj1SjVe6ZXvPUm7pVgyeZJEpZk0E3eA+PH2jSgr50mVfEhjwyZg7Vhxu2moYTibDl0WN9JGu36sSFBbK/hkLwtecFdZVF5MBz61+53A42nFe93SdL7OeYX3eprTNQdLHHqTxluGW4OTJlLxSoVNqWFwOg57BL8yRXZ6PXJjbT/cMi2Fg4UESgMUgsCsaELEfJPCCGQ7GQI6PIe1j+zcMFDRAwX6g3MtnOD/fmSQPIj66ukIehHcksiqm3MRZCPpZWtRKVYn05Q9fG64k2c38dTbf63eIKlZw"""
 | 
						|
}
 | 
						|
if __name__ == '__main__':
 | 
						|
    main()
 |