查找C++中所有代码行数超过100的类成员函数

执行效果

python3 find_large_functions.py
./stage_test.cpp: StageTest::process has 106 lines.
./stage_test.cpp: StageTest::do_test_ has 172 lines.

实现方法

在检测到函数开始的“可能”标志后(比如返回类型和作用域运算符::),开始累积接下来的行直到遇到函数体开始的左大括号{为止,从而捕获完整的函数声明。

关键点:

  • 使用re.MULTILINE | re.DOTALL标志允许正则表达式跨越多行并正确匹配换行符。
  • func_pattern试图匹配整个函数声明,包括可能分布在多行的参数列表,直到声明结束处的左大括号{。
  • 在找到一个匹配后,代码将继续搜索匹配的右大括号},以确定函数体的实际长度,并计算行数。
import os
import redef find_large_functions_in_file(file_path, min_lines=100):with open(file_path, 'r', encoding='utf-8') as file:lines = file.read()# 模式匹配类成员函数(可能跨越多行)func_pattern = re.compile(r'\w[\w\s:]*\w+::\w+\s*\([^)]*\)\s*[{]',re.MULTILINE | re.DOTALL)functions = []for match in func_pattern.finditer(lines):func_sig = match.group()start_index = match.start()# 计算左右大括号以平衡,找出函数体的结束brace_count = 1i = match.end()while i < len(lines) and brace_count != 0:if lines[i] == '{':brace_count += 1elif lines[i] == '}':brace_count -= 1i += 1func_body = lines[start_index:i]line_count = func_body.count('\n')if line_count >= min_lines:# 提取简化的函数名func_name_match = re.search(r'(\w+)::(\w+)\s*\(', func_sig)if func_name_match:class_name = func_name_match.group(1)func_name = func_name_match.group(2)display_name = f"{class_name}::{func_name}"else:display_name = "Unknown Function"functions.append((display_name, line_count))return functionsdef find_large_functions(directory, line_threshold=100):for root, dirs, files in os.walk(directory):for file_name in files:if file_name.endswith('.cpp'):file_path = os.path.join(root, file_name)large_functions = find_large_functions_in_file(file_path, line_threshold)for func_name, line_count in large_functions:print(f"{file_path}: {func_name} has {line_count} lines.")if __name__ == "__main__":find_large_functions('.', 50)

改进实现

  • 读取整个文件内容:考虑到需要使用正则表达式跨多行匹配函数声明,我们维持了读取整个文件内容的方式,但这在处理巨大的源文件时可能不够高效。
  • 正则表达式改进:更好地匹配可能跨越多行的函数参数列表。
  • 异常处理: 当文件非常大或者编码问题导致无法打开时,应该添加适当的异常处理来增强代码的健壮性,这在示例中未展示。
  • 性能注意事项:对于特别大的项目或文件,完整地读取每个文件进内存可能导致性能瓶颈。对于超大文件,可能需要采用更高效的逐行分析策略,但这可能会复杂化正则表达式匹配跨越多行的情况。
import os
import redef find_large_functions_in_file(file_path, min_lines=100):# 编译正则表达式以匹配C++类成员函数声明(考虑跨多行)func_pattern = re.compile(r'\w[\w\s:]*\w+::\w+\s*\((?:[^)]|\n)*\)\s*{',re.MULTILINE | re.DOTALL)functions = []  # 存储符合条件的函数信息with open(file_path, 'r', encoding='utf-8') as file:content = file.read()for match in func_pattern.finditer(content):start_index = match.end()  # 函数体开始位置# 确定函数体结束的位置brace_level = 1  # 已匹配一个左花括号for i in range(start_index, len(content)):if content[i] == '{':brace_level += 1elif content[i] == '}':brace_level -= 1if brace_level == 0:  # 所有括号均已匹配end_index = i + 1breakelse:# 如果找不到匹配的右括号,则跳过此函数continue# 计算函数体行数line_count = content[start_index:end_index].count('\n')if line_count >= min_lines:# 提取和格式化函数名func_name_match = re.search(r'(\w+)::(\w+)\s*\(', match.group(0))class_name, func_name = func_name_match.groups() if func_name_match else ("Unknown", "Unknown")display_name = f"{class_name}::{func_name}"functions.append((display_name, line_count))return functionsdef find_large_functions(directory, line_threshold=100):for root, _, files in os.walk(directory):for file_name in files:if file_name.endswith('.cpp'):file_path = os.path.join(root, file_name)large_functions = find_large_functions_in_file(file_path, line_threshold)for func_name, line_count in large_functions:print(f"{file_path}: {func_name} has {line_count} lines.")if __name__ == "__main__":find_large_functions('.', 100)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/737617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue-router

router的使用&#xff08;52&#xff09; 5个基础步骤&#xff1a; 1.在终端执行yarn add vue-router3.6.5&#xff0c;安装router插件 yarn add vue-router3.6.5 2.在文件的main.js中引入router插件 import VueRouter from vue-router 3.在main.js中安装注册Vue.use(Vue…

力扣:链表篇章

1、链表 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据域一个是指针域&#xff08;存放指向下一个节点的指针&#xff09;&#xff0c;最后一个节点的指针域指向null&#xff08;空指针的意思&#xff09;。 2、链表的类…

Python高级二

一、异常 1、定义 异常是在程序执行过程中出现的错误或意外情况。当程序遇到异常时&#xff0c;它会中断当前的执行流程&#xff0c;并尝试找到相应的异常处理机制来解决问题。 2、常见异常类型 SyntaxError&#xff1a;语法错误&#xff0c;通常是代码书写不符合Python语法规则…

【前端】移动端布局

目录 1.移动端特点 分辨率 二倍图 2.百分比布局 3.flex布局 3.1flex布局模型 3.2主轴对齐方式 3.3 侧轴对齐方式 3.4flex属性 1.移动端特点 PC端网页和移动端网页的不同 PC端网页&#xff1a;屏幕大&#xff0c;网页固定版心 jd.com移动端网页&#xff1a;屏幕小 没…

实战案例——Kafka集群部署

1. 规划节点 IP主机名节点192.168.100.10zookeeper1集群节点192.168.100.20zookeeper2集群节点192.168.100.30zookeeper集群节点 2. 基础准备 使用ZooKeeper集群搭建的3个节点来构建Kafka集群&#xff0c;因为Kafka服务依赖于ZooKeeper服务&#xff0c; 所以不再多创建云主机…

vue前端获取本地IP地址

新建js文件 getIpAddress.js //获取本机的IP地址 function getNetworkIp() {let ip localhost;try {const network Os.networkInterfaces();//获取本机的网路for (const iter in network) {const faces network[iter];for (const interface of faces) {if (interface.fami…

接口自动化测试的三个阶段

根本目标 测试环境中&#xff0c;保证新增接口功能正确性&#xff0c;原有接口的回归&#xff08;保证原有接口不被修改“坏”&#xff09;&#xff1b; 生产环境中&#xff0c;保证接口层面服务可用&#xff0c;功能的正确性&#xff08;保证服务挂掉时&#xff0c;及时发现…

pytorch入门

相比起keras和tensorflow,个人感觉pytorch更好一些 相比起程序语言本身,个人感觉,记住解决问题的步骤和方法更重要 import torch ttorch.tensor(1) t.size() t1torch.rand((3,4)) torch.Tensor? torch.empty((3,3)) devicetorch.device(cuda if torch.cuda.is_available() els…

Python爬网页,不确定网页的编码,不需要用第三方库

Python爬网页&#xff0c;不确定网页的编码&#xff0c;不需要用第三方库&#xff0c;自己写个判断&#xff0c;乱拳打死老师傅 detect试了&#xff0c;不好用 apparent_encoding试了&#xff0c;不好用 encoding试了&#xff0c;不好用 headers里get试了&#xff0c;不好用…

户口本怎么翻译成英文

户口本翻译件一般用于出国旅游签证、商务签证、移民留学等业务时&#xff0c;申请人所需提交的文件之一。户口本翻译件需要正规有资质的翻译机构翻译并加盖翻译专用章,这样才能得到有关部门的认可。那么&#xff0c;英国签证户口本翻译&#xff0c;中译英怎么翻译比较好&#x…

鸿蒙Harmony应用开发—ArkTS声明式开发(模态转场设置:全屏模态转场)

通过bindContentCover属性为组件绑定全屏模态页面&#xff0c;在组件插入和删除时可通过设置转场参数ModalTransition显示过渡动效。 说明&#xff1a; 从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 不支持横竖屏切换。…

TCP三次握手,四次挥手状态转移过程

1.TCP状态转移过程 TCP连接的任意一端都是一个状态机,在TCP连接从建立到断开的整个过程中,连接两端的状态机将经历不同的状态变迁.理解TCP状态转移对于调试网络应用程序将有很大的帮助. 2.三次握手状态转换 3.四次挥手状态转换 4.TIME WAIT状态详解 为什么要有一个"TIME…

数据标注专业团队

数据标注服务 在跟一些淘宝、多多商家老板合作后&#xff0c;客户一般付款后&#xff0c;中介是有20%左右的提成&#xff0c;我们主要是希望可以实现数据标注无中介化&#xff0c;有需求可以直接联系数据标注团队直接负责人&#xff0c; 若有意愿请添加添加v&#xff1a;shu_ju…

9. 内核、文件系统加载工具

内核、文件系统加载工具 内核、文件系统加载工具是嵌入式开发必备的工具 1. 烧写BootLoader 1.1 通过超级终端方式 烧写 Bootloader 可以使用超级终端的“传送” |“发送文件”命令进入发送文件对话框&#xff0c;使用 Xmodem 协议和 Kermit 协议发送 Bootloader 的各个文件…

docker安装rocketMq

在搭建之前&#xff0c;我们需要做一些准备工作&#xff0c;这里我们需要使用 docker 搭建服务&#xff0c;所以需要提前安装 docker。 此外&#xff0c;由于 rocketmq 需要部署 broker 与 nameserver &#xff0c;考虑到分开部署比较麻烦&#xff0c;这里将会使用docker-comp…

网络模块使用Hilt注入

retrofit的异步回调方法已经做了线程切换&#xff0c;切换到了主线程 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"><uses-permission android:name"andr…

JS原型链面试题

题目1 function Person(name) {this.name name; }Person.prototype.sayHello function() {console.log(Hello, this.name); };var john new Person(John); john.sayHello();请问上述代码的输出结果是什么&#xff1f; 答案1 输出结果是&#xff1a;Hello, John 题目2 …

如何通过Python代码连接OceanBase Oracle租户

背景 目前&#xff0c;连接数据库的Oracle租户&#xff0c;只能通过Java和C的驱动程序&#xff0c;无法通过其他语言的驱动程序。为了满足社区中用户希望在Python代码中连接Oracle租户的需求&#xff0c;这里提供一种替代方案。通过结合使用JayDeBeApi和JDBC&#xff0c;我们可…

Docker使用及部署流程

文章目录 1. 准备Docker环境2. 准备应用的Docker镜像3. 在服务器上运行Docker容器方法一:Docker Hub方法二:从构建环境传输镜像4. 管理和维护使用Docker Compose(可选)主要区别步骤 1: 安装Docker ComposeLinuxWindowMac步骤 2: 创建docker-compose.yml文件步骤 3: 使用Doc…

牛客网KY266 反序数

题目 描述&#xff1a; 设N是一个四位数&#xff0c;它的9倍恰好是其反序数&#xff08;例如&#xff1a;1234的反序数是4321&#xff09;求N的值。 输入描述&#xff1a; 程序无任何输入数据。 输出描述&#xff1a; 输出题目要求的四位数&#xff0c;如果结果有多组&#xff…