• 【MicroPython】生成Q(string)符号表文件脚本 py\makeqstrdefs.py


    •  脚本使用格式

    python py/makeqstrdefs.py [command] [mode] [input-file] [output-directory] [output-file]

    command: pp, split, cat

    mode: qstr,  compress

    • 输入选项解析
    if __name__ == "__main__":
        if len(sys.argv) < 6:
            print("usage: %s command mode input_filename output_dir output_file" % sys.argv[0])
            sys.exit(2)
    
        class Args:
            pass
    
        args = Args()
        args.command = sys.argv[1]
    
        if args.command == "pp":
            # 创建字典 {k:v,}
            named_args = {
                s: []
                for s in [
                    "pp",
                    "output",
                    "cflags",
                    "cxxflags",
                    "sources",
                    "changed_sources",
                    "dependencies",
                ]
            }
    
            # 向字典k中追加v
            for arg in sys.argv[1:]:
                if arg in named_args:
                    current_tok = arg
                else:
                    named_args[current_tok].append(arg)
    
            if not named_args["pp"] or len(named_args["output"]) != 1:
                print("usage: %s %s ..." % (sys.argv[0], " ... ".join(named_args)))
                sys.exit(2)
    
            for k, v in named_args.items():
                # 构建类对象args
                setattr(args, k, v)
    
            preprocess()
            sys.exit(0)
    • 文件预处理
    def preprocess():
        # 选择源文件列表
        # 遍历列表args.changed_sources元素检查是否在列表args.dependencies中
        if any(src in args.dependencies for src in args.changed_sources):
            sources = args.sources
        elif any(args.changed_sources):
            sources = args.changed_sources
        else:
            sources = args.sources
        csources = []
        cxxsources = []
        # 归类收集文件
        for source in sources:
            if is_cxx_source(source):
                cxxsources.append(source)
            elif is_c_source(source):
                csources.append(source)
        try:
            os.makedirs(os.path.dirname(args.output[0]))
        except OSError:
            pass
    
        def pp(flags):
            def run(files):
                return subprocess.check_output(args.pp + flags + files)
    
            return run
    
        try:
            cpus = multiprocessing.cpu_count()
        except NotImplementedError:
            cpus = 1
        p = multiprocessing.dummy.Pool(cpus)
        with open(args.output[0], "wb") as out_file:
            for flags, sources in (
                (args.cflags, csources),
                (args.cxxflags, cxxsources),
            ):
                batch_size = (len(sources) + cpus - 1) // cpus
                chunks = [sources[i : i + batch_size] for i in range(0, len(sources), batch_size or 1)]
                for output in p.imap(pp(flags), chunks):
                    out_file.write(output)
    • 提取MP_QSTR_开头的字符串转换成Q(string)形式
    def write_out(fname, output):
        if output:
            for m, r in [("/", "__"), ("\\", "__"), (":", "@"), ("..", "@@")]:
                fname = fname.replace(m, r)
            with open(args.output_dir + "/" + fname + "." + args.mode, "w") as f:
                f.write("\n".join(output) + "\n")
    
    
    def process_file(f):
        re_line = re.compile(r"#[line]*\s\d+\s\"([^\"]+)\"")
        if args.mode == _MODE_QSTR:
            re_match = re.compile(r"MP_QSTR_[_a-zA-Z0-9]+")
        elif args.mode == _MODE_COMPRESS:
            re_match = re.compile(r'MP_COMPRESSED_ROM_TEXT\("([^"]*)"\)')
        output = []
        last_fname = None
        for line in f:
            if line.isspace():
                continue
            # match gcc-like output (# n "file") and msvc-like output (#line n "file")
            if line.startswith(("# ", "#line")):
                m = re_line.match(line)
                assert m is not None
                fname = m.group(1)
                if not is_c_source(fname) and not is_cxx_source(fname):
                    continue
                if fname != last_fname:
                    write_out(last_fname, output)
                    output = []
                    last_fname = fname
                continue
            # 新增非"#","#line"时使用给定的输出文件名
            else:
                last_fname = args.output_file
    
            for match in re_match.findall(line):
                if args.mode == _MODE_QSTR:
                    name = match.replace("MP_QSTR_", "")
                    output.append("Q(" + name + ")")
                elif args.mode == _MODE_COMPRESS:
                    output.append(match)
    
        if last_fname:
            write_out(last_fname, output)
        return ""

    $ python py/makeqstrdefs.py split "qstr" test.c skull boyer.c

     

    • 为了能供脚本py\makeqstrdata.py使用,需增加QCFG配置

    def cat_together():
        import glob
        import hashlib
    
        # 构建MD5算法的hashlib对象
        hasher = hashlib.md5()
        all_lines = []
        outf = open(args.output_dir + "/out", "wb")
        # glob查找文件
        for fname in glob.glob(args.output_dir + "/*." + args.mode):
            with open(fname, "rb") as f:
                lines = f.readlines()
                all_lines += lines
        # 排序
        all_lines.sort()
        # 换行转换原来字符串
        all_lines = b"\n".join(all_lines)
        outf.write(all_lines)
        outf.close()
        hasher.update(all_lines)
        # hash值十六进制输出
        new_hash = hasher.hexdigest()
        # print(new_hash)
        old_hash = None
        try:
            with open(args.output_file + ".hash") as f:
                old_hash = f.read()
        except IOError:
            pass
        mode_full = "QSTR"
        if args.mode == _MODE_COMPRESS:
            mode_full = "Compressed data"
        if old_hash != new_hash:
            print(mode_full, "updated")
            try:
                # rename below might fail if file exists
                os.remove(args.output_file)
            except:
                pass
            os.rename(args.output_dir + "/out", args.output_file)
            with open(args.output_file + ".hash", "w") as f:
                f.write(new_hash)
        else:
            print(mode_full, "not updated")

    $ python py/makeqstrdefs.py cat "qstr" test.c skull boyer.c

  • 相关阅读:
    武器排序HDU3293:sort
    sata硬盘id
    root sysroot chroot rootfs解析
    软件版本周期
    shell字符串的截取的问题
    游戏脚本
    udevadm使用
    vfat linux 大小写问题
    vmware 虚拟机性能优化
    日期被修改
  • 原文地址:https://www.cnblogs.com/skullboyer/p/16228130.html
Copyright © 2020-2023  润新知