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 & ...
随机推荐
- Oracle EBS-SQL (GL-5):从发票追溯到接收
SELECT destination_type_code, distribution_line_number, line_type, amount,vat_code, tax_code_id, tax ...
- Delphi中TWebBrowser中注入Js
最近帮朋友做一个软件,其中要自动化某网页中的操作,最简的操作是调用自己写的代码. 代码如下: procedure TForm1.Button2Click(Sender: TObject);var i ...
- mysql timestamp 值不合法问题
Create Table: CREATE TABLE `RecruitmentDesc` ( `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号(自增字段 ...
- git配置别名
配置别名 有没有经常敲错命令?比如git status?status这个单词真心不好记. 如果敲git st就表示git status那就简单多了,当然这种偷懒的办法我们是极力赞成的. 我们只需要 ...
- poj1969---找规律
题意:按照s型分别给数编号,给 #include <stdio.h> #include <stdlib.h> int main() { int n; while(scanf(& ...
- Android 自动编译、打包生成apk文件 3 - 使用SDK Ant方式
相关文章列表: < Android 自动编译.打包生成apk文件 1 - 命令行方式> < Android 自动编译.打包生成apk文件 2 - 使用原生Ant方式> &l ...
- SAN实现
Linux 上主要有三个 iSCSI Target(基于internet scsi协议的target) 实现: Linux SCSI Target – STGT / tgt Linux-IO Targ ...
- Fix Some bytes have been replaced with the Unicode substitution character while loading file XXX.cs with Chinese Simplified (GB2312) encoding
When we use <strong>visual studio</strong> open source file or any other file, we may en ...
- iOS开发蓝牙 蓝牙4.0的各种踩过的坑,希望你们少踩点
1.首先建立这个三个参数 @property (nonatomic,strong)CBCentralManager * manager; @property (nonatomic,strong)CBP ...
- math。h中的log函数的应用
以10为底的log函数: 形式为 double log10(double x) 以e为底的log函数(即 ln)double log (double x) 如何表达log 以a为底b的对数: 用换 ...