VS C++工程类成员初始化检测脚本
最近项目中出现由类成员未初始化而进行读写而造成的问题,于是想将项目中所有的为初始化的地方找出来,优化一下代码,维护了这么多年的程序已有百万余行且VS2015还尚未支持检查类成员初始化的方法。,于是想写一个小工具帮助我们检查这些纰漏,于是向老大请示后开写,之前没有用过什么脚本写过工具,听说python挺火,于是我要上岸。
现学现用写了2天,写出来一个完全op的搓诞的玩意儿,太丑了,因为不能花太多时间在上面还有其他任务。不过能用来分析一个工程中所有的cpp与h文件效果还不错。
以下是代码,以此为戒
#hfilepath="D:\\Work\\ABSF\\ImportExport\\Import\\Import.vcxproj"
hfilepath="D:\\Work\\ABSF\\Model\\Model.vcxproj"
#hfilepath="D:\\Work\\ABSF\\Persistence\\Persistence.vcxproj"
#hfilepath="D:\\Work\\ABSF\\Language\\LDLPlusSyntaxParser\\LDLPlusSyntaxParser.vcxproj"
#hfilepath="D:\\Work\\ABSF\\Language\\LDLSyntaxParse\\LDLSyntaxParse.vcxproj"
class EMP:
def __init__(self):
self.name = "";
self.decl_defi={}
self.var_ini={}
name_EMP={}
global st
st= []
global insPtr
insPtr=0
privatestr="private:"
publicstr="public:"
protectedstr="protected:"
typedefstr="typedef"
templatestr="template"
friendstr="friend"
commentsstr="//"
DONTWANT=[]
DONTWANT.append(privatestr)
DONTWANT.append(publicstr)
DONTWANT.append(protectedstr)
DONTWANT.append(typedefstr)
DONTWANT.append(templatestr)
DONTWANT.append(friendstr)
DONTWANT.append("CLONE_METHOD")
#DONTWANT.append(commentsstr)
OTHEREXP=[]
OTHEREXP.append('if(')
OTHEREXP.append('while(')
OTHEREXP.append('switch(')
OTHEREXP.append('for(')
Require_Remove=[]
Require_Remove.append('virtual')
Require_Remove.append('friend')
Require_Remove.append('mutable')
Require_Remove.append('MODEL_API ')
Require_Remove.append('ATL_NO_VTABLE ')
Require_Remove.append('PERSISTENCE_API ')
defistr="#define"
classstr= "class "
sturctstr="struct "
enumstr="enum "
equalstr="="
colonstr=":"
semistr=";"
forbracestr="{"
bacbracestr="}"
forparenthstr="("
bacparenthstr=")"
bacbracestrAndSemistr=bacbracestr+semistr
AllFiles=[]
tmppos=-1
def getStack():
global st
global insPtr
if(insPtr!=0):
return st[insPtr-1]
else:
return ""
def pushStack(ele):
global st
global insPtr
st.insert(insPtr, ele)
insPtr+=1
def popStack():
global st
global insPtr
if (insPtr!=0):
insPtr-=1
st.pop(insPtr)
return insPtr
def clearStack():
global st
global insPtr
while popStack()!=0:
pass
def printTab():
global insPtr
for i in range(0,insPtr):
print("\t",end='')
print("\nBegin parse target project files...")
f0=open(hfilepath,'r')
for line in f0:
hpos=line.find('.h')
cpppos=line.find('.cpp')
if hpos>=0 or cpppos>=0:
hpos=line.find('=\"')
if hpos>=0:
cpppos=line.find('"',hpos+2,len(line))
if cpppos>=0:
line=line[hpos+2:cpppos]
#print(line)
NDDBS=0
startpos=0
while True:
if line.find('..\\',startpos,len(line))>=0:
NDDBS+=1
startpos+=len('..\\')
else:
break
if hfilepath.rfind("\\")==-1:
hfilepath+="\\"
tmppos=hfilepath.rfind("\\")
while NDDBS>0:
if hfilepath.rfind("\\",0,tmppos)==-1 or NDDBS==0:
break
else:
tmppos=hfilepath.rfind("\\",0,tmppos)
NDDBS-=1
if NDDBS==0:
#print(hfilepath[0:tmppos+1]+line[startpos:len(line)])
AllFiles.append(hfilepath[0:tmppos+1]+line[startpos:len(line)])
else:
print("!!!!!!!!\\not match")
print("\nBegin analyse all h files...")
for file in AllFiles:
#print(file)
if file.find('.h')>=0:
print("Analysing : "+file+" .....")
#hfilepath="D:\\Work\\ABSF\\Model\\"
#file=hfilepath
#file+="Element"
#file+="XMLImporter"
#file+="Object"
#file+="Model"
#file+="Insertable"
#file+="Configuration"
defineblock=0
codeblock=""
functionname=""
adhesionflag=0
tempstr=""
templongstr=""
#f1=open(file+'.h','r')
f1=open(file,'r')
for line in f1:
if line.find(commentsstr)>0:
line=line[0:line.find(commentsstr)]
for i in range(0,len(DONTWANT)):
if line.find(DONTWANT[i])>0:
i=-1
break
if i!=-1:#舍弃注释..public...选项
for i in range(0,len(Require_Remove)):
if line.find(Require_Remove[i])>=0:
#print(Require_Remove[i])
line=(line[0:line.find(Require_Remove[i])]+line[line.find(Require_Remove[i])+len(Require_Remove[i]):len(line)])
#print(line)
#print(adhesionflag,end='')
#print(" ",end='')
#print(line,end='')
classpos=-1
if line.find(sturctstr)>=0:
classpos=line.find(sturctstr)
if line.find(enumstr)>=0:
classpos=line.find(enumstr)
if line.find(classstr)>=0:
classpos=line.find(classstr)
if classpos>0:
for i in range(classpos-1,-1,-1):#排除 函数(struct情况)
if line[i].isalpha():
break
else:
i=0
#print(classpos)
#结构体枚举类
if line.find(defistr)>=0:#define忽略
if line.find('\\')>0:
defineblock=1
continue
if defineblock==1:
if line.find('\\')==-1:
defineblock=0
continue
if classpos>=0 and i==0:
if (commentsstr in line)==0 or((commentsstr in line)and line.find(commentsstr)>classpos):#是一个class申明或定义
tmppos=line.find(' ',classpos)
if tmppos>0:
tmppos+=1
for i in range(tmppos,len(line)):
if not(line[i]==' 'or line[i]=='\t'):
tmppos=i
break
for i in range(tmppos,len(line)):
if not (line[i].isalpha()or line[i].isdigit()or line[i]=='_') :
#print(line[i],end = '\n')
break
print("")
printTab()
if(len(line[tmppos:i])!=0):
print(line[tmppos:i]+' begin', end = '\n')
else:
print("enum")
pushStack(line[tmppos:i])
if semistr in line:#只是类申明不管
tempstr=getStack()
popStack()
printTab()
print(tempstr+' declaration end'+'\n', end = '\n')
elif (len(line[tmppos:i])!=0):
obj= EMP()#新建类对象
obj.name=line[tmppos:i]
if not(obj.name in name_EMP):
name_EMP[line[tmppos:i]]=obj
elif insPtr>0:
if adhesionflag==0:#代码块起始
codeblock=""
codeblock+=line
adhesionflag=1#标志此代码块成立
blocktype=0#代码块类型0无,1函数,2变量
bracecounter=0#代表没有括号出现
tmppos=line.find(forparenthstr)
#print(tmppos,end=' ')
if tmppos>0 and line.find('declspec')==-1:#有小括号但必须不包含__declspec有分号无大括号是函数调用或者if,swtich,while,for
blocktype=1
if line.find('()(')==tmppos:
tmppos+=2
for i in range(tmppos-1,-1,-1):
if not (line[i]==' 'or line[i]=='\t'):
break
tmppos-=1
for i in range(tmppos-1,-1,-1):
if not (line[i].isalpha()or line[i].isdigit()or line[i]=='~'or line[i]=='_'or line[i]=='&'or line[i]=='['or line[i]==']'or line[i]=='+'or line[i]=='-'or line[i]=='*'or line[i]=='='or line[i]=='<'or line[i]=='!'or line[i]=='('or line[i]==')'):
break
functionname=line[i+1:tmppos]
#print(functionname,end=' ')
#print(line.find(forbracestr))
if line.find(forbracestr)>0:
bracecounter=1
if line.find(bacbracestr)>0:#在一句话中有大括号一对,直接结束代码块,函数定义
bracecounter=0
adhesionflag=-2
else:
tmppos=line.rfind(bacparenthstr)
if line.rfind(semistr)>tmppos:#没有大括号但有在')'之后的分号,函数申明
adhesionflag=-1
if adhesionflag<0:#代码块结束
for i in range(0,len(OTHEREXP)):
if functionname.lower().find(OTHEREXP[i])>0:
i=-1
break
if i==-1:#非函数,为if while for switch
pass#不错浪费时间而已不做处理
else:#
tempstr=getStack()
tmppos=codeblock.find(functionname)
if functionname==tempstr:
if tmppos>=0:
parenthcounter=0
for i in range(tmppos,len(codeblock)):
if codeblock[i]==forparenthstr :
parenthcounter+=1
if codeblock[i]==bacparenthstr :
parenthcounter-=1
if parenthcounter==0:
printTab()
print(codeblock[tmppos:i+1])#构造函数申明部分
templongstr=codeblock[tmppos:i+1]
if adhesionflag==-1 and not (templongstr in name_EMP[tempstr].decl_defi):
name_EMP[tempstr].decl_defi[templongstr]="" #存入构造申明
printTab()
print("decla_stored",end="\n")
if adhesionflag==-2:
name_EMP[tempstr].decl_defi[templongstr]=codeblock#存入构造定义
printTab()
print("defi_stored",end="\n")
#print(len(name_EMP[tempstr].decl_defi[templongstr]))
#print(name_EMP[tempstr].decl_defi[templongstr])
break
adhesionflag=0
#### printTab()
####print("Func: ",end='')
####print(functionname,end='\n')
else:#非函数
blocktype=2
adhesionflag=0
tmppos=line.find(bacbracestr)#}
if tmppos>=0:
if tmppos<line.find(semistr):#}....;为类,结构体,枚举
tempstr=getStack()
popStack()
printTab()
print(tempstr+' end'+'\n', end = '')
if tempstr in name_EMP:#如果该类存在
if len(name_EMP[tempstr].decl_defi)==0:#构造个数
name_EMP[tempstr].decl_defi[tempstr+'()']=""#存入此构造tempstr+'()'+'\n'+'{}'
printTab()
print("construction Func num: ",end="")
print(len(name_EMP[tempstr].decl_defi))
continue
tmppos=line.find(semistr)#只找到';'
if tmppos>0:
if line.find("declspec")==-1:
if line.rfind(equalstr, 0, tmppos)>=0:
tmppos=line.rfind(equalstr, 0, tmppos)
for i in range(tmppos-1,-1,-1):
if not (line[i]==' 'or line[i].isdigit()or line[i]=='\t'or line[i]=='['or line[i]==']'or line[i]=='&'):
break
tmppos-=1
for i in range(tmppos-1,-1,-1):
if not (line[i].isalpha()or line[i].isdigit()or line[i]=='_'):
break
for x in range(i+1,len(line)):
if not (line[x].isalpha()or line[x].isdigit()or line[x]=='_'):
break
tempstr=getStack()
printTab()
print("Member: ",end='')
memname=line[i+1:x]
print(memname,end='')
if line.rfind(equalstr, x, len(line))>=0:
print(" .....Initialized",end='')#已初始化的变量
name_EMP[tempstr].var_ini[memname]=3
else:
name_EMP[tempstr].var_ini[memname]=0
print('')
else:#代码块增量
codeblock+=line
if blocktype==1:#函数相关
if bracecounter==0:#若没有出现过大括号便已有分号结尾
tmppos=line.rfind(bacparenthstr)
if line.rfind(semistr)>tmppos:#没有大括号但有在')'之后的分号,仅为函数申明
adhesionflag=-1
if adhesionflag==1:
if line.find(forbracestr)>0:
bracecounter+=1
if line.find(bacbracestr)>0:
bracecounter-=1
if bracecounter==0:#括号平衡,为函数定义
adhesionflag=-2
if adhesionflag<0:#代码块结束
for i in range(0,len(OTHEREXP)):
if functionname.lower().find(OTHEREXP[i])>0:
i=-1
break
if i==-1:#非函数,为if while for switch
pass#不错浪费时间而已不做处理
else:#
tempstr=getStack()#类名
tmppos=codeblock.find(functionname)
if functionname==tempstr:#构造
if tmppos>=0:
parenthcounter=0
for i in range(tmppos,len(codeblock)):
if codeblock[i]==forparenthstr:
parenthcounter+=1
if codeblock[i]==bacparenthstr:
parenthcounter-=1
if parenthcounter==0:
printTab()
print(codeblock[tmppos:i+1])#构造函数申明部分
templongstr=codeblock[tmppos:i+1]
if adhesionflag==-1 and not (templongstr in name_EMP[tempstr].decl_defi):
name_EMP[tempstr].decl_defi[templongstr]="" #存入构造申明
printTab()
print("decla_stored",end="\n")
if adhesionflag==-2:
name_EMP[tempstr].decl_defi[templongstr]=codeblock#存入构造定义
printTab()
print("defistored",end="\n")
#print(len(name_EMP[tempstr].decl_defi[templongstr]))
#print(name_EMP[tempstr].decl_defi[templongstr])
break
adhesionflag=0
#### printTab()
####print("Func: ",end='')
####print(functionname,end='\n')
f1.close
print("\n Begin analyse all cpp files...")
for file in AllFiles:
if file.find('.cpp')>=0:
print("Analysing : "+file+" .....")
#print("f2 begin")
#cppfilepath=""
classname=""
#f2=open(file+'.cpp','r')
f2=open(file,'r')
adhesionflag=0
tmppos=-1
tmppos1=-1
defineblock=0
for line in f2:
if line.find(commentsstr)>0:
line=line[0:line.find(commentsstr)]
for i in range(0,len(DONTWANT)):
if line.find(DONTWANT[i])>0:
i=-1
break
if i!=-1:#舍弃注释..public...选项
if line.find(defistr)>=0:#define忽略
if line.find('\\')>0:
defineblock=1
continue
if defineblock==1:
if line.find('\\')==-1:
defineblock=0
continue
if adhesionflag==1:#如果粘连部分
codeblock+=line
if bacbracestr in line:
adhesionflag=-1
if adhesionflag==0:
for classname in name_EMP:
tmppos1=line.find('(')
if tmppos1>=0:
tempstr=classname+'::'+classname
tmppos=line.rfind(tempstr,0,tmppos1)
if tmppos>=0 and tmppos1-tmppos>0 and tmppos1-tmppos<2+len(tempstr):#该行属于某类的构造开头
if adhesionflag==0:
adhesionflag=1#标志此为构造块
codeblock=""
codeblock+=line
if semistr in line:
if not (bacbracestr in line):
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!WHAT THE HELL IS THIS?")
print('target class: ')
adhesionflag=-1
break#终止其他查找
else:
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Inside other block")
if adhesionflag==-1:#为代码块终止
adhesionflag=0
construct=""
for construct in name_EMP[classname].decl_defi:
if len(name_EMP[classname].decl_defi[construct])==0:
name_EMP[classname].decl_defi[construct]=codeblock
#print(codeblock)
construct="added"
break
if construct!="added":#不能添加
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!construct FUNCTION FULL!!!!!!!")
#保存代码块到任意的构造中
#for tempstr in name_EMP[classname].decl_defi:
#tempstr=classname+'::'+tempstr
#if len(name_EMP[classname].decl_defi[tempstr])==0:#目标代码尚未定义的话
#tempstr=classname+'::'+tempstr
f2.close
print("\n=============================================================================\n"+hfilepath[hfilepath.rfind("\\")+1:hfilepath.rfind(".")]+" project's initialization status:\n")
for classname in name_EMP:
if len(name_EMP[classname].var_ini)!=0:#必须有成员
print(classname)
for var in name_EMP[classname].var_ini:
print("\t"+var+';'+" .....",end="")
if name_EMP[classname].var_ini[var]==0:
successed=3#假定是完全
for construct in name_EMP[classname].decl_defi:
tempstr=name_EMP[classname].decl_defi[construct]
for i in range(0,len(tempstr)-1):
if tempstr[i]==colonstr and tempstr[i+1]!=colonstr and tempstr[i-1]!=colonstr:
break;
if i!=len(tempstr)-2:#my lord , we found them
tmppos=tempstr.find(forbracestr,i,len(tempstr))
if tmppos>=0:
if tempstr.find(var,i,tmppos)>=0:
continue#绕过这次
successed=2#不在初始化列表中,假定在构造中
tmppos=tempstr.find(forbracestr,0,len(tempstr))
if tmppos>=0:
if tempstr.find(var,tmppos,len(tempstr))>=0:
continue
successed=1
break
if name_EMP[classname].var_ini[var]==0:
name_EMP[classname].var_ini[var]=successed
if name_EMP[classname].var_ini[var]==3:
print(".....OK")
elif name_EMP[classname].var_ini[var]==2:
print(".....OK in constructor but need to be initialized in initializer list")
elif name_EMP[classname].var_ini[var]==1:
print(".....Uninitialized!!!!!!!!")
else:
print("var_ini Error!!!!")
print(classname+" end\n")
print("=============================================================================\n\n")
VS C++工程类成员初始化检测脚本的更多相关文章
- Java编程陷阱-类成员初始化
原文地址:http://blog.csdn.net/veryitman/article/details/6450523 如果你忽略Java的细节,恐怕你的代码会充满bug,下面讨论关于类成员初始化问题 ...
- C#的类成员初始化顺序
C#的类成员的定义和声明如下 using UnityEngine; using System.Collections; public class TestController : ECControll ...
- C++: 类成员初始化列表语法
类的成员初始化列表的初始化的基本语法,类的构造函数还可以运用此语法为其变量初始化: class Class { private: int a; int b; char ch; public: Cl ...
- C#类成员初始化顺序
这里直接给出C#类成员一般初始化顺序: 子类静态字段 子类静态构造 子类实例字段 父类静态字段 父类静态构造 父类实例字段 父类实例构造 子类实例构造 为什么说是"一般"初始化顺序 ...
- Java类成员初始化顺序
类中包含7中成员:1.静态变量 static2.final静态常量 final static3.静态代码块 static{} //多个代码块顺序执行 4.普通变量5.普通代码块 {} //多个代码 ...
- java小心机(5)| 浅谈类成员初始化顺序
类成员什么时候会被初始化呢?一般来说:"类的代码在初次使用时才被加载",加载过程包括了初始化. 比如说new A()调用构造函数时,类中全部成员都会被初始化. 但对于static域 ...
- C#类和类成员初始化顺序
1.不带静态成员的普通类,首先通过构造函数初始化. 2.带静态属性的类,无论是普通类还是静态类,都会先初始化静态字段,再执行构造函数. 3.类初始化时,不会执行类中方法,无论是否是静态.若想执行方法, ...
- 109-PHP类成员初始化值
<?php class mao{ //定义猫类 public $age=0; //定义多个属性并初始化 public $weight=50; public $color='white'; } $ ...
- C++类成员初始化列表的构造顺序
看下面代码, 输出结果是多少呢? class A{ public: A(int k) : j(k), i(j) { } void show() { cout << this->i & ...
随机推荐
- J2SE知识点摘记(二十六)
为了用“集合框架”的额外部分把排序支持添加到 Java 2 SDK,版本 1.2,核心 Java 库作了许多更改.像 String 和 Integer 类如今实现 Comparable 接口以提供自然 ...
- otl库(以前不知道有这个库,并且还可以在Unix下使用)
OTL介绍:OTL 是 Oracle, Odbc and DB2-CLI Template Library 的缩写,是一个C++编译中操控关系数据库的模板库,它目前几乎支持所有的当前各种主流数据库,例 ...
- Qt for Linux:环境搭建(CentOS 6.5 32位)——完全从零安装
正文开始前,我们假设,用户可以操作终端 拥有root权限,以下所有操作也均由root完成 可以上网 安装了CentOS 6.5 32位 注:红色部分,每个人可能都不一样 话不多说,列出本章大致流程 1 ...
- rsyslog 定义模板
rsyslog默认会将特殊字符(\t)转换成#009 由全局配置$EscapeControlCharactersOnReceive 决定,如果自己需要根据\t处理输出时,需将该选项改为 off. $E ...
- rsyslog 配置
在Debian环境下: 1,配置文件在/etc/rsyslogd.conf下: 2,如果要增加配置,并且不想直接修改rsyslogd.conf文件,可以在/etc/rsyslog.d/目录下增加文件, ...
- Alisha’s Party(队列)
Alisha’s Party Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- 使用 Eclipse Memory Analyzer 进行堆转储文件分析
Eclipse Memory Analyzer(MAT)是著名的跨平台集成开发环境 Eclipse Galileo 版本的 33 个组成项目中之一,它是一个功能丰富的 JAVA 堆转储文件分析工具,可 ...
- Javascript 获取窗口的大小和位置
在Javascript中可以使用OuterWidth,OuterHeight 获取浏览器的大小.用 innerWidth,innerHeight 来获取窗口的大小(除去浏览器边框部分).对于IE6 及 ...
- SSIS: 把存储在数据库中的图片导出来
Data Flow Task Step 1 获取二进制图片数据 )='C:\labs\Images\' SELECT ThumbNailPhoto,@path+ThumbnailPhotoFileNa ...
- UISearchBar--改变内部输入框的背景颜色
思路是获取UISearchBar的子视图,判断他是否是输入框(注意不要先入为主地认为是UITextField),最后修改背景色.至于UISearchBar的子视图结构,在不同的iOS版本可能会不一样, ...