diff options
| author | Mengsk <[email protected]> | 2022-11-07 12:47:41 +0100 |
|---|---|---|
| committer | Mengsk <[email protected]> | 2022-11-07 12:47:41 +0100 |
| commit | 9d3d8fd5b0788b811ad283d10d37dfd1b1005224 (patch) | |
| tree | f66b39fe968cc1a6e46e3074bbda9b907064bc15 /tools | |
| parent | 1eae139aa94130a63ecc4725852cb69c02566c82 (diff) | |
| parent | e434a1dc0584e841da1ae4ff525bbe81a0f5514b (diff) | |
Merge branch 'master' of https://github.com/hathach/tinyusb into bsp_412
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/build_board.py | 146 | ||||
| -rw-r--r-- | tools/build_esp32sx.py | 7 | ||||
| -rw-r--r-- | tools/build_family.py | 161 | ||||
| -rw-r--r-- | tools/build_utils.py | 122 | ||||
| -rw-r--r-- | tools/get_dependencies.py | 25 | ||||
| -rw-r--r-- | tools/iar_template.ipcf | 18 | ||||
| -rw-r--r-- | tools/mksunxi.py | 48 |
7 files changed, 293 insertions, 234 deletions
diff --git a/tools/build_board.py b/tools/build_board.py index 9397c754f..8d10ef820 100644 --- a/tools/build_board.py +++ b/tools/build_board.py @@ -1,125 +1,69 @@ import os -import glob import sys -import subprocess import time +import subprocess +from multiprocessing import Pool + +import build_utils SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" -success_count = 0 -fail_count = 0 -skip_count = 0 -exit_status = 0 - -total_time = time.monotonic() - -build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' build_separator = '-' * 106 + def filter_with_input(mylist): if len(sys.argv) > 1: input_args = list(set(mylist).intersection(sys.argv)) if len(input_args) > 0: mylist[:] = input_args -# If examples are not specified in arguments, build all -all_examples = [] -for entry in os.scandir("examples/device"): - if entry.is_dir(): - all_examples.append("device/" + entry.name) -for entry in os.scandir("examples/host"): - if entry.is_dir(): - all_examples.append("host/" + entry.name) -filter_with_input(all_examples) -all_examples.sort() - -# If boards are not specified in arguments, build all -all_boards = [] -for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.exists(entry.path + "/board.mk"): - all_boards.append(entry.name) -filter_with_input(all_boards) -all_boards.sort() - -def build_board(example, board): - global success_count, fail_count, skip_count, exit_status - start_time = time.monotonic() - flash_size = "-" - sram_size = "-" - - # Check if board is skipped - if skip_example(example, board): - success = SKIPPED - skip_count += 1 - print(build_format.format(example, board, success, '-', flash_size, sram_size)) - else: - subprocess.run("make -C examples/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - if build_result.returncode == 0: - success = SUCCEEDED - success_count += 1 - (flash_size, sram_size) = build_size(example, board) - else: - exit_status = build_result.returncode - success = FAILED - fail_count += 1 +if __name__ == '__main__': + # If examples are not specified in arguments, build all + all_examples = [] + for dir1 in os.scandir("examples"): + if dir1.is_dir(): + for entry in os.scandir(dir1.path): + if entry.is_dir(): + all_examples.append(dir1.name + '/' + entry.name) + filter_with_input(all_examples) + all_examples.sort() - build_duration = time.monotonic() - start_time - print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) + # If boards are not specified in arguments, build all + all_boards = [] + for entry in os.scandir("hw/bsp"): + if entry.is_dir() and os.path.exists(entry.path + "/board.mk"): + all_boards.append(entry.name) + filter_with_input(all_boards) + all_boards.sort() - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) + # Get dependencies + for b in all_boards: + subprocess.run("make -C examples/device/board_test BOARD={} get-deps".format(b), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) -def build_size(example, board): - #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) - elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) - size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - size_list = size_output.split('\n')[1].split('\t') - flash_size = int(size_list[0]) - sram_size = int(size_list[1]) + int(size_list[2]) - return (flash_size, sram_size) - -def skip_example(example, board): - ex_dir = 'examples/' + example - board_mk = 'hw/bsp/{}/board.mk'.format(board) - with open(board_mk) as mk: - mk_contents = mk.read() - - # Skip all OPT_MCU_NONE these are WIP port - if '-DCFG_TUSB_MCU=OPT_MCU_NONE' in mk_contents: - return 1 - - # Skip if CFG_TUSB_MCU in board.mk to match skip file - for skip_file in glob.iglob(ex_dir + '/.skip.MCU_*'): - mcu_cflag = '-DCFG_TUSB_MCU=OPT_' + os.path.basename(skip_file).split('.')[2] - if mcu_cflag in mk_contents: - return 1 - - # Build only list, if exists only these MCU are built - only_list = list(glob.iglob(ex_dir + '/.only.MCU_*')) - if len(only_list) > 0: - for only_file in only_list: - mcu_cflag = '-DCFG_TUSB_MCU=OPT_' + os.path.basename(only_file).split('.')[2] - if mcu_cflag in mk_contents: - return 0 - return 1 - - return 0 + print(build_separator) + print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + total_time = time.monotonic() -print(build_separator) -print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + # succeeded, failed, skipped + total_result = [0, 0, 0] + for example in all_examples: + print(build_separator) + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda b, e=example: [e, b], all_boards))) + result = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + result = list(map(sum, list(zip(*result)))) + + # add to total result + total_result = list(map(lambda x, y: x + y, total_result, result)) -for example in all_examples: + total_time = time.monotonic() - total_time + print(build_separator) + print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], + FAILED, total_result[2], SKIPPED, total_time)) print(build_separator) - for board in all_boards: - build_board(example, board) - -total_time = time.monotonic() - total_time -print(build_separator) -print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) -print(build_separator) -sys.exit(exit_status) + sys.exit(total_result[1]) diff --git a/tools/build_esp32sx.py b/tools/build_esp32sx.py index 91953f080..2947a0a6b 100644 --- a/tools/build_esp32sx.py +++ b/tools/build_esp32sx.py @@ -4,6 +4,8 @@ import sys import subprocess import time +import build_utils + SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" @@ -51,7 +53,7 @@ def build_board(example, board): sram_size = "-" # Check if board is skipped - if skip_example(example, board): + if build_utils.skip_example(example, board): success = SKIPPED skip_count += 1 print(build_format.format(example, board, success, '-', flash_size, sram_size)) @@ -83,9 +85,6 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) -def skip_example(example, board): - return 0 - print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) print(build_separator) diff --git a/tools/build_family.py b/tools/build_family.py index 4195c259b..c6c64d2b3 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -1,151 +1,74 @@ import os -import glob import sys -import subprocess import time +from multiprocessing import Pool + +import build_utils SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" -success_count = 0 -fail_count = 0 -skip_count = 0 -exit_status = 0 - -total_time = time.monotonic() - -build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' build_separator = '-' * 106 + def filter_with_input(mylist): if len(sys.argv) > 1: input_args = list(set(mylist).intersection(sys.argv)) if len(input_args) > 0: mylist[:] = input_args -# If examples are not specified in arguments, build all -all_examples = [] -for entry in os.scandir("examples/device"): - if entry.is_dir(): - all_examples.append("device/" + entry.name) -for entry in os.scandir("examples/host"): - if entry.is_dir(): - all_examples.append("host/" + entry.name) -filter_with_input(all_examples) -all_examples.sort() - -# If family are not specified in arguments, build all -all_families = [] -for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name != "esp32s2" and entry.name != "esp32s3": - all_families.append(entry.name) - -filter_with_input(all_families) -all_families.sort() def build_family(example, family): all_boards = [] for entry in os.scandir("hw/bsp/{}/boards".format(family)): - if entry.is_dir(): + if entry.is_dir() and entry.name != 'pico_sdk': all_boards.append(entry.name) filter_with_input(all_boards) all_boards.sort() - - for board in all_boards: - build_board(example, board) - -def build_board(example, board): - global success_count, fail_count, skip_count, exit_status - start_time = time.monotonic() - flash_size = "-" - sram_size = "-" - - # Check if board is skipped - if skip_example(example, board): - success = SKIPPED - skip_count += 1 - print(build_format.format(example, board, success, '-', flash_size, sram_size)) - else: - #subprocess.run("make -C examples/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - if build_result.returncode == 0: - success = SUCCEEDED - success_count += 1 - (flash_size, sram_size) = build_size(example, board) - subprocess.run("make -j -C examples/{} BOARD={} copy-artifact".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - else: - exit_status = build_result.returncode - success = FAILED - fail_count += 1 - - build_duration = time.monotonic() - start_time - print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda b, e=example: [e, b], all_boards))) + result = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + return list(map(sum, list(zip(*result)))) -def build_size(example, board): - #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) - elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) - size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") - size_list = size_output.split('\n')[1].split('\t') - flash_size = int(size_list[0]) - sram_size = int(size_list[1]) + int(size_list[2]) - return (flash_size, sram_size) -def skip_example(example, board): - ex_dir = 'examples/' + example - - # Check if example is skipped by family or board directory - skip_file = ".skip." + example.replace('/', '.'); - if os.path.isfile("hw/bsp/{}/{}".format(family, skip_file)) or os.path.isfile("hw/bsp/{}/boards/{}/{}".format(family, board, skip_file)): - return 1 +if __name__ == '__main__': + # If examples are not specified in arguments, build all + all_examples = [] + for dir1 in os.scandir("examples"): + if dir1.is_dir(): + for entry in os.scandir(dir1.path): + if entry.is_dir(): + all_examples.append(dir1.name + '/' + entry.name) + filter_with_input(all_examples) + all_examples.sort() - # Otherwise check if mcu is excluded by example directory + # If family are not specified in arguments, build all + all_families = [] + for entry in os.scandir("hw/bsp"): + if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name not in ("esp32s2", "esp32s3"): + all_families.append(entry.name) + filter_with_input(all_families) + all_families.sort() - # family CMake - family_mk = 'hw/bsp/{}/family.cmake'.format(family) - - # family.mk - if not os.path.exists(family_mk): - family_mk = 'hw/bsp/{}/family.mk'.format(family) - - with open(family_mk) as mk: - mk_contents = mk.read() - - # Skip all OPT_MCU_NONE these are WIP port - if 'CFG_TUSB_MCU=OPT_MCU_NONE' in mk_contents: - return 1 - - # Skip if CFG_TUSB_MCU in family.mk to match skip file - for skip_file in glob.iglob(ex_dir + '/.skip.MCU_*'): - mcu_cflag = 'CFG_TUSB_MCU=OPT_' + os.path.basename(skip_file).split('.')[2] - if mcu_cflag in mk_contents: - return 1 - - # Build only list, if exists only these MCU are built - only_list = list(glob.iglob(ex_dir + '/.only.MCU_*')) - if len(only_list) > 0: - for only_file in only_list: - mcu_cflag = 'CFG_TUSB_MCU=OPT_' + os.path.basename(only_file).split('.')[2] - if mcu_cflag in mk_contents: - return 0 - return 1 - return 0 + print(build_separator) + print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + total_time = time.monotonic() -print(build_separator) -print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + # succeeded, failed, skipped + total_result = [0, 0, 0] + for example in all_examples: + print(build_separator) + for family in all_families: + fret = build_family(example, family) + total_result = list(map(lambda x, y: x + y, total_result, fret)) -for example in all_examples: + total_time = time.monotonic() - total_time + print(build_separator) + print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1], + FAILED, total_result[2], SKIPPED, total_time)) print(build_separator) - for family in all_families: - build_family(example, family) - -total_time = time.monotonic() - total_time -print(build_separator) -print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, total_time)) -print(build_separator) -sys.exit(exit_status) + sys.exit(total_result[1]) diff --git a/tools/build_utils.py b/tools/build_utils.py new file mode 100644 index 000000000..f457c7986 --- /dev/null +++ b/tools/build_utils.py @@ -0,0 +1,122 @@ +import subprocess +import pathlib +import time + +build_format = '| {:29} | {:30} | {:18} | {:7} | {:6} | {:6} |' + +SUCCEEDED = "\033[32msucceeded\033[0m" +FAILED = "\033[31mfailed\033[0m" +SKIPPED = "\033[33mskipped\033[0m" + + +def skip_example(example, board): + ex_dir = pathlib.Path('examples/') / example + bsp = pathlib.Path("hw/bsp") + + if (bsp / board / "board.mk").exists(): + # board without family + board_dir = bsp / board + family = "" + mk_contents = "" + else: + # board within family + board_dir = list(bsp.glob("*/boards/" + board)) + if not board_dir: + # Skip unknown boards + return True + + board_dir = list(board_dir)[0] + + family_dir = board_dir.parent.parent + family = family_dir.name + + # family CMake + family_mk = family_dir / "family.cmake" + + # family.mk + if not family_mk.exists(): + family_mk = family_dir / "family.mk" + + mk_contents = family_mk.read_text() + + # Find the mcu, first in family mk then board mk + if "CFG_TUSB_MCU=OPT_MCU_" not in mk_contents: + board_mk = board_dir / "board.cmake" + if not board_mk.exists(): + board_mk = board_dir / "board.mk" + + mk_contents = board_mk.read_text() + + for token in mk_contents.split(): + if "CFG_TUSB_MCU=OPT_MCU_" in token: + # Strip " because cmake files has them. + token = token.strip("\"") + _, opt_mcu = token.split("=") + mcu = opt_mcu[len("OPT_MCU_"):] + + # Skip all OPT_MCU_NONE these are WIP port + if mcu == "NONE": + return True + + skip_file = ex_dir / "skip.txt" + only_file = ex_dir / "only.txt" + + if skip_file.exists() and only_file.exists(): + raise RuntimeError("Only have a skip or only file. Not both.") + elif skip_file.exists(): + skips = skip_file.read_text().split() + return ("mcu:" + mcu in skips or + "board:" + board in skips or + "family:" + family in skips) + elif only_file.exists(): + onlys = only_file.read_text().split() + return not ("mcu:" + mcu in onlys or + "board:" + board in onlys or + "family:" + family in onlys) + + return False + + +def build_example(example, board): + start_time = time.monotonic() + flash_size = "-" + sram_size = "-" + + # succeeded, failed, skipped + ret = [0, 0, 0] + + # Check if board is skipped + if skip_example(example, board): + status = SKIPPED + ret[2] = 1 + print(build_format.format(example, board, status, '-', flash_size, sram_size)) + else: + build_result = subprocess.run("make -j -C examples/{} BOARD={} all".format(example, board), shell=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + if build_result.returncode == 0: + status = SUCCEEDED + ret[0] = 1 + (flash_size, sram_size) = build_size(example, board) + subprocess.run("make -j -C examples/{} BOARD={} copy-artifact".format(example, board), shell=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + else: + status = FAILED + ret[1] = 1 + + build_duration = time.monotonic() - start_time + print(build_format.format(example, board, status, "{:.2f}s".format(build_duration), flash_size, sram_size)) + + if build_result.returncode != 0: + print(build_result.stdout.decode("utf-8")) + + return ret + + +def build_size(example, board): + elf_file = 'examples/{}/_build/{}/*.elf'.format(example, board) + size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + size_list = size_output.split('\n')[1].split('\t') + flash_size = int(size_list[0]) + sram_size = int(size_list[1]) + int(size_list[2]) + return (flash_size, sram_size) diff --git a/tools/get_dependencies.py b/tools/get_dependencies.py new file mode 100644 index 000000000..e7d3e0a76 --- /dev/null +++ b/tools/get_dependencies.py @@ -0,0 +1,25 @@ +import os +import sys +import subprocess + + +# dependency lookup (ABC sorted) +# deps = { +# 'LPC11UXX' : [ [] ] +# } + + +def get_family_dep(family): + for entry in os.scandir("hw/bsp/{}/boards".format(family)): + if entry.is_dir(): + result = subprocess.run("make -C examples/device/board_test BOARD={} get-deps".format(entry.name), + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + print(result.stdout.decode("utf-8")) + return result.returncode + +status = 0 +all_family = sys.argv[1:] +for f in all_family: + status += get_family_dep(f) + +sys.exit(status)
\ No newline at end of file diff --git a/tools/iar_template.ipcf b/tools/iar_template.ipcf index b8e50a1d2..ba54fe057 100644 --- a/tools/iar_template.ipcf +++ b/tools/iar_template.ipcf @@ -41,7 +41,8 @@ <path>$TUSB_DIR$/src/class/msc/msc_host.c</path> </group> <group name="src/class/net"> - <path>$TUSB_DIR$/src/class/net/net_device.c</path> + <path>$TUSB_DIR$/src/class/net/ecm_rndis_device.c</path> + <path>$TUSB_DIR$/src/class/net/ncm_device.c</path> </group> <group name="src/class/usbtmc"> <path>$TUSB_DIR$/src/class/usbtmc/usbtmc_device.c</path> @@ -58,6 +59,9 @@ <path>$TUSB_DIR$/src/host/usbh.c</path> <path>$TUSB_DIR$/src/host/usbh_control.c</path> </group> + <group name="src/portable/synopsys/dwc2"> + <path>$TUSB_DIR$/src/portable/synopsys/dwc2/dcd_dwc2.c</path> + </group> <group name="src/portable/dialog/da146xx"> <path>$TUSB_DIR$/src/portable/dialog/da146xx/dcd_da146xx.c</path> </group> @@ -67,6 +71,9 @@ <group name="src/portable/espressif/esp32sx"> <path>$TUSB_DIR$/src/portable/espressif/esp32sx/dcd_esp32sx.c</path> </group> + <group name="src/portable/mentor/musb"> + <path>$TUSB_DIR$/src/portable/mentor/musb/dcd_musb.c</path> + </group> <group name="src/portable/microchip/samd"> <path>$TUSB_DIR$/src/portable/microchip/samd/dcd_samd.c</path> </group> @@ -116,21 +123,12 @@ <group name="src/portable/renesas/usba"> <path>$TUSB_DIR$/src/portable/renesas/usba/dcd_usba.c</path> </group> - <group name="src/portable/silabs/efm32"> - <path>$TUSB_DIR$/src/portable/silabs/efm32/dcd_efm32.c</path> - </group> <group name="src/portable/sony/cxd56"> <path>$TUSB_DIR$/src/portable/sony/cxd56/dcd_cxd56.c</path> </group> <group name="src/portable/st/stm32_fsdev"> <path>$TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c</path> </group> - <group name="src/portable/st/synopsys"> - <path>$TUSB_DIR$/src/portable/st/synopsys/dcd_synopsys.c</path> - </group> - <group name="src/portable/template"> - <path>$TUSB_DIR$/src/portable/template/dcd_template.c</path> - </group> <group name="src/portable/ti/msp430x5xx"> <path>$TUSB_DIR$/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c</path> </group> diff --git a/tools/mksunxi.py b/tools/mksunxi.py new file mode 100644 index 000000000..04786f429 --- /dev/null +++ b/tools/mksunxi.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +import sys +import struct + +def align(num, alignment): + if num % alignment != 0: + num += (alignment - num % alignment) + return num + + +def process_file(input, output): + with open(input, 'rb') as fin: + content = bytearray(fin.read()) + + align_value = 512 + padded_length = align(len(content), align_value) + # pad file to actual length + content += b'\x00' * (padded_length - len(content)) + + struct_format = '<L8sLL' + (instruction, magic, checksum, length) = struct.unpack_from(struct_format, content) + + if magic != b'eGON.BT0': + print("Magic is invalid:", magic) + return 2 + + checksum = 0x5F0A6C39 + length = align(length, align_value) + + struct.pack_into(struct_format, content, 0, instruction, magic, checksum, length) + + checksum = 0 + for i in range(0, length, 4): + (n, ) = struct.unpack_from('<L', content, i) + checksum += n + checksum %= 4294967296 + + struct.pack_into(struct_format, content, 0, instruction, magic, checksum, length) + + with open(output, 'wb') as fout: + fout.write(content) + return 0 + +if __name__ == "__main__": + if len(sys.argv) != 3: + print("Usage: mksunxi.py input.bin output.bin") + exit(1) + exit(process_file(sys.argv[1], sys.argv[2]))
\ No newline at end of file |
