类似VS中添加类 A的方法 int abc();

会在对应的实现文件.cpp中自动生成,

int A::abc() {

}

初学python,尝试写了一个脚本,自动根据写好的.h文件完成这一工作,也支持模板类,不过没考虑太多模板可能会有bug。

也可能会有很多其他的bug,不过用了下,感觉还可以,有错误再改正:)

用法

比如有一个abc.h,对应的实现文件abc.cc

1.新建一个abc.cc文件

touch abc.cc

2.运行脚本

./prodef.py  abc.h abc.cc

因为我默认是.cc文件,也可

./prodef.py  abc.h

用google 开源的代码做了一个实验,

我们要处理的gtest-test-part.h如下

// Copyright 2008, Google Inc.

// All rights reserved.

#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_

#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_

#include <iosfwd>

#include <gtest/internal/gtest-internal.h>

#include <gtest/internal/gtest-string.h>

namespace testing {

// The possible outcomes of a test part (i.e. an assertion or an

// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).

enum TestPartResultType {

TPRT_SUCCESS,           // Succeeded.

TPRT_NONFATAL_FAILURE,  // Failed but the test can continue.

TPRT_FATAL_FAILURE      // Failed and the test should be terminated.

};

// A copyable object representing the result of a test part (i.e. an

// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).

//

// Don't inherit from TestPartResult as its destructor is not virtual.

class TestPartResult {

public:

// C'tor.  TestPartResult does NOT have a default constructor.

// Always use this constructor (with parameters) to create a

// TestPartResult object.

TestPartResult(TestPartResultType type,

const char* file_name,

int line_number,

const char* message)

: type_(type),

file_name_(file_name),

line_number_(line_number),

summary_(ExtractSummary(message)),

message_(message) {

}

// Gets the outcome of the test part.

TestPartResultType type() const { return type_; }

// Gets the name of the source file where the test part took place, or

// NULL if it's unknown.

const char* file_name() const { return file_name_.c_str(); }

// Gets the line in the source file where the test part took place,

// or -1 if it's unknown.

int line_number() const { return line_number_; }

// Gets the summary of the failure message.

const char* summary() const { return summary_.c_str(); }

// Gets the message associated with the test part.

const char* message() const { return message_.c_str(); }

// Returns true iff the test part passed.

bool passed() const { return type_ == TPRT_SUCCESS; }

// Returns true iff the test part failed.

bool failed() const { return type_ != TPRT_SUCCESS; }

// Returns true iff the test part non-fatally failed.

bool nonfatally_failed() const { return type_ == TPRT_NONFATAL_FAILURE; }

// Returns true iff the test part fatally failed.

bool fatally_failed() const { return type_ == TPRT_FATAL_FAILURE; }

private:

TestPartResultType type_;

// Gets the summary of the failure message by omitting the stack

// trace in it.

static internal::String ExtractSummary(const char* message);

// The name of the source file where the test part took place, or

// NULL if the source file is unknown.

internal::String file_name_;

// The line in the source file where the test part took place, or -1

// if the line number is unknown.

int line_number_;

internal::String summary_;  // The test failure summary.

internal::String message_;  // The test failure message.

};

// Prints a TestPartResult object.

std::ostream& operator<<(std::ostream& os, const TestPartResult& result);

// An array of TestPartResult objects.

//

// We define this class as we cannot use STL containers when compiling

// Google Test with MSVC 7.1 and exceptions disabled.

//

// Don't inherit from TestPartResultArray as its destructor is not

// virtual.

class TestPartResultArray {

public:

TestPartResultArray();

~TestPartResultArray();

// Appends the given TestPartResult to the array.

void Append(const TestPartResult& result);

// Returns the TestPartResult at the given index (0-based).

const TestPartResult& GetTestPartResult(int index) const;

// Returns the number of TestPartResult objects in the array.

int size() const;

private:

// Internally we use a list to simulate the array.  Yes, this means

// that random access is O(N) in time, but it's OK for its purpose.

internal::List<TestPartResult>* const list_;

GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);

};

// This interface knows how to report a test part result.

class TestPartResultReporterInterface {

public:

virtual ~TestPartResultReporterInterface() {}

virtual void ReportTestPartResult(const TestPartResult& result) = 0;

};

namespace internal {

// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a

// statement generates new fatal failures. To do so it registers itself as the

// current test part result reporter. Besides checking if fatal failures were

// reported, it only delegates the reporting to the former result reporter.

// The original result reporter is restored in the destructor.

// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.

class HasNewFatalFailureHelper : public TestPartResultReporterInterface {

public:

HasNewFatalFailureHelper();

virtual ~HasNewFatalFailureHelper();

virtual void ReportTestPartResult(const TestPartResult& result);

bool has_new_fatal_failure() const { return has_new_fatal_failure_; }

private:

bool has_new_fatal_failure_;

TestPartResultReporterInterface* original_reporter_;

GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);

};

}  // namespace internal

}  // namespace testing

#endif  // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_

运行 ./prodef.py gtest-test-part.h

生成的 gtest-test-part.cc 函数框架如下

#include "gtest-test-part.h"

namespace testing {

// Gets the summary of the failure message by omitting the stack

// trace in it.

internal::String TestPartResult::ExtractSummary(const char* message) {

}

// Prints a TestPartResult object.

std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {

}

TestPartResultArray::TestPartResultArray() {

}

TestPartResultArray::~TestPartResultArray() {

}

// Appends the given TestPartResult to the array.

void TestPartResultArray::Append(const TestPartResult& result) {

}

// Returns the TestPartResult at the given index (0-based).

const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {

}

// Returns the number of TestPartResult objects in the array.

int TestPartResultArray::size() const {

}

void TestPartResultReporterInterface::ReportTestPartResult(const TestPartResult& result) {

}

namespace internal {

HasNewFatalFailureHelper::HasNewFatalFailureHelper() {

}

HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {

}

void HasNewFatalFailureHelper::ReportTestPartResult(const TestPartResult& result) {

}

}  // namespace internal

}  // namespace testing

下面是程序源码

#!/usr/local/bin/python3.0

#prodef.py
#automate generate the .cc file according to .h file
#generate all the functions need to be implemented 
#defining in .h file

#autor goldenlock@pku

#05.13.09

#since c++ is complex
#there may be bugs... 
#I assume you define class as below
#class A {
#};
#I assume you define function as below
#int abc();
#or
#int abc(int x,int y
# int z);
#Below is not allowed
#int
#abc (int x,int y,int z);
#I assume you always use c++ style comment //
def usage():
""" 
Run the program like this,notice need to touch a empty .cc or .cpp by yourself
we assume .cc by defualt
1.touch abc.cc                
2./prodef.py abc.h abc.cc
or ./prodef.py abc.h 
1.touch a.cpp
2./prodef.py a.h a.cpp
It will read abc.h and append the fuctions 
to be implemented to abc.cc
"""
func_list_exist = []
def AnalyzeOutputFile(file_handle):
print('Analze output file right now ,the reslt of existing functions is below\n')
file_handle.seek(0,0)
m = file_handle.readlines()
i = 0
while (i < len(m)):
line = m[i]
find1 = re.search('[(]',line)
find2 = re.search('[)]',line)
if (find1 and (not find2)):
i += 1
line += m[i] 
while (i < len(m) and (not re.search('[)]',line))):
i += 1
line += m[i]
match = re.search('^.*\)',line,re.MULTILINE|re.DOTALL)
if match:
print(match.group())
func_list_exist.append(match.group())
i += 1
print('Output file analze done!\n')
def ConvertDot_h2Dot_CC(input_file,output_file):
"""
kernal function given a .h file
convert to a .cc one with
all the functions properly listed
"""
print('The file you want to deal with is '+input_file + \
'\n It is converted to ' + output_file)
pattern = re.compile(r"""(^[\s]*)             #leading withe space,we will find and delete after
                ([a-zA-Z~_]            # void int likely the first caracter v or i...
.* 
[)]                   #we find )
#(?!\s*=\s*0)          #if we find = 0  which means pur virtual we will not match after
#(?=\s*=\s*0) 
(?!.*{)              # we do not want the case int abc() const { return 1;}
.*)
(;.*)                 #we want to find ; and after for we will replace these later
\n$
""",re.VERBOSE | re.MULTILINE | re.DOTALL)
pattern2 = re.compile(r'(virtual\s+|explicit\s+|friend\s+|static\s+)')   
leading_space_pattern = re.compile('(^[\s]*)[a-zA-Z~]')   
pattern_func_name = re.compile(r'([a-zA-Z0-9~_\-]+\s*|operator.*)[(]') 
pattern_comment = re.compile(r'^\s*//')
pattern_template = re.compile(r'(class|typename)\s+([a-zA-Z0-9_\-]+)')
p1 = re.compile(r'namespace.*{')      
p2 = re.compile(r'(class|struct)\s+([a-zA-Z0-9_\-]+).*{')
p3 = re.compile('{')
p4 = re.compile('}')
stack = []
stack_class = []
stack_template = []
f_out = open(output_file,'r+')    
AnalyzeOutputFile(f_out)                        
print('Below functions will be added\n')
f_out.write('#include "' + input_file + '"\n\n')
with open(input_file,'r') as f:
m = f.readlines()
i = 0
while i < len(m):
line = m[i]
if line == '\n' or re.search('^\s*//',line) :
i += 1
continue
f1 = p1.search(line)
if f1:                                
f_out.write(line+'\n')
stack.append('namespace_now')
i += 1
continue
f2 = p2.search(line)   
if f2:                 
if(re.search(r'\s*template',m[i-1])):  
stack_template.append(m[i-1])
else:
stack_template.append('')
stack.append('class_now')
class_name = f2.group(2)   
stack_class.append(class_name)
i += 1
continue
f3 = p3.search(line)
f4 = p4.search(line)
if f3:
stack.append('normal_now')
if f4:
top_status = stack.pop()
if top_status == 'namespace_now':
f_out.write(line+'\n')
elif top_status == 'class_now':
stack_class.pop()
stack_template.pop()
if f3 or f4:
i += 1
continue
if len(stack) >0 and stack[-1] == 'normal_now':  
i += 1
continue
find1 = re.search('[(]',line)
find2 = re.search('[)]',line)
if (find1 and (not find2)):
space = leading_space_pattern.search(line).group(1)
i += 1
line2 = m[i]
line2 = re.sub('^'+space,'',line2)     
line += line2
while (i < len(m) and (not re.search('[)]',line2))):
i += 1
line2 = m[i]
line2 = re.sub('^'+space,'',line2)
line += line2
(line,match) = pattern.subn(r'\2 {\n\n}\n\n',line)  
if match:
friend_match = re.search('friend ',line)
line = pattern2.sub('',line)            
define_match = re.search(r'^([a-zA-Z0-9~_/-]+)\s*[(]',line)
if define_match:
if len(stack_class) == 0 or (stack_class[-1] != define_match.group(1) and ('~'+stack_class[-1]) != define_match.group(1)):
i += 1
continue
func_name = ''
if len(stack_class) > 0 and not friend_match :                
template_line = ''
x = ''
if (stack_template[-1] != ''):
template_line = re.sub(r'\s*template','template',stack_template[-1])
x = re.sub(r'template\s*\<','<',template_line)
x = x.rstrip()             
x = re.sub(r'(class|typename)\s+','',x)
line = pattern_func_name.sub(stack_class[-1] + x + '::' + r'\1(',line)
line = re.sub(r'\s*=\s*0','',line)                 
func_name = re.search('^.*\)',line).group()
line = template_line + line;                       
else:
func_name = re.search('^.*\)',line,re.MULTILINE|re.DOTALL).group()
comment_line = ''                                   
for j in range(i-1,0,-1):
c_line = m[j]
if pattern_comment.search(c_line):
c_line = re.sub('\s*//','//',c_line)
comment_line = c_line + comment_line
else:
break
line = comment_line + line
if not(func_name in func_list_exist):
print(func_name)
f_out.write(line)
i += 1
print('Sucessfully converted,please see '+output_file)
def main(argv):                         
try:                                
opts, args = getopt.getopt(argv, "h", ["help"]) 
except getopt.GetoptError:           
print(usage.__doc__) 
sys.exit(2)
if len(opts) > 0:
for o, a in opts: 
if o in ("-h", "--help"): 
print(usage.__doc__) 
sys.exit()
elif len(args) > 0:
input_file = args[0]
if len(args) == 1:
output_file = re.sub('.h','.cc',input_file)
else:
output_file = args[1]
ConvertDot_h2Dot_CC(input_file,output_file)
else:
print(usage.__doc__)
sys.exit()
if __name__ == "__main__":
main(sys.argv[1:])

C++根据.h文件批量生成需要的函数框架相关推荐

  1. 如何通过TXT文件批量生成EAN14条码

    EAN14条形码是基于EAN-128码的编码规则,长度是14位,第14位为校验位,由前面13位计算得出.EAN14条形码通常会用来制作集装箱编号条码.批量制作条码时,我们一般会通过导入数据库的方式来实 ...

  2. 使用Excel文件批量生成Codabar码

    Codabar(库德巴码)是由Monarch Marking Systems在1972年研制的条形码.它是在"2 of 5"后早期阶段引入的条形码.广泛用于需要序列号的领域,如血库 ...

  3. 通过Excel文件批量生成Code 39扩展码

    code39码是条形码的一种,编码简单.能够对任意长度的数据进行编码.支持设备广泛,所以code39码是最常用的条形码之一.code39码在条码打印软件中有两种表现类型:标准code39码和支持字符更 ...

  4. 通过TXT文件批量生成UPC-A条码

    UPC码算是EAN条码的前身,因此两者有着类似的特性及编码方式.UPC码分为标准型UPC-A码及简易型UPC-E码,UPC-A条码左侧6个条码字符均由A子集的条码字符组成,右侧数据符及校验符均由C子集 ...

  5. TXT文件批量生成二维码

    大多数人在制作标签时,数据库文件都选择Excel文件,其实TXT文件在作为数据库时,也是可以制作各种可变数据标签的,比如批量生成二维码,条形码等.下面我们就使用TXT文件作为数据库批量生成二维码. 打 ...

  6. unity导出fbx模型_Unity批量合并Animation工具/根据已有的Animation文件批量生成带FBX动画工具...

    由于本人现有项目的项目素材大部分都需要继续沿用旧项目的模型与动画,但在接受旧模型动画的时候发现,模型动画由于外包已经丢失了3dmax的源文件,只剩下了一堆AnimationCilp(.anim)文件与 ...

  7. 用Python写一个批量生成账号的函数(用户控制数据长度、数据条数)

    # 1.写一个函数,批量生成一些注册使用的账号:产生的账号是以@163.com结尾,长度由用户输入,产生多少条也由用户输入,用户名不能重复,用户名必须由大写字母.小写字母.数字组成 import ra ...

  8. CodeSmith将模板文件批量生成文件的方法

    以前写codeSmith模板的时候,如果直接像asp一样混排编写的话,代码输出来codeSmith中,不知道怎么保存到文件,后来把所有要输出的模板文字都用stringBuiler串接起来然后IO到文件 ...

  9. Python读取Execl文件批量生成二维码

    #参考他人稍微修改 引入包 import qrcode import xlrd 代码 生成二维码 def create_qrcode(file_name, content): img = qrcode ...

最新文章

  1. python软件怎么用-用Python如何打出你的第一个程序
  2. 京东每日特价专栏仿写
  3. 综合布线中所需要的的带宽和数据速率
  4. hibernate之CRUD操作
  5. VC打包程序,并修改注册表(详细以后补充)
  6. 4008-基于邻接矩阵的新边的增加(C++,附思路)
  7. c++和java哪个难_为什么说C语言比Java难?
  8. lc滤波电路电感电容值选择_模拟电路中,电感的这些知识点你都清楚吗?
  9. linux下client命令,Linux系统smbclient命令的使用方法
  10. 一篇比较好的高数的学习规划分享
  11. 必须掌握,二叉树的前中后序遍历(迭代+递归)详细代码
  12. 硬币组合问题-非递归实现
  13. 自动驾驶最全基础知识、课程、论文、数据集、开源软件等资源整理分享
  14. Swift5实现ios后台播放语音,腾讯音视频通话后台播放来电铃声
  15. javaFX 学习之 超链接(HyperLink) 转载
  16. 从技术实现到安全运行,工程师版“元宇宙”离我们还有多远?
  17. DAO 中独特的通证经济
  18. OpenGL ES 实现瘦脸大眼效果
  19. 试用 网络存储器(ReadyNAS NV+)
  20. 网站下拉菜单,选择下拉后自动填充(图)

热门文章

  1. python输出99乘法表_如何用python输出99乘法表
  2. 第2章 DOS循环:for命令详解
  3. SCPPO(八):登录实现逻辑
  4. 快速图像增强的简便大法来了,英伟达开源新库代号“DALI”| CVPR 18
  5. 2018深度学习十大趋势:元学习成新SGD,多数硬件创企将失败
  6. JavaSE基础:泛型
  7. 让Python更加充分的使用Sqlite3
  8. 关于js弹出框的介绍:
  9. Nginx屏蔽个别User-Agent蜘蛛访问网站的方法
  10. C#中join 的lambada写法