最近项目中出现由类成员未初始化而进行读写而造成的问题,于是想将项目中所有的为初始化的地方找出来,优化一下代码,维护了这么多年的程序已有百万余行且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++工程类成员初始化检测脚本的更多相关文章

  1. Java编程陷阱-类成员初始化

    原文地址:http://blog.csdn.net/veryitman/article/details/6450523 如果你忽略Java的细节,恐怕你的代码会充满bug,下面讨论关于类成员初始化问题 ...

  2. C#的类成员初始化顺序

    C#的类成员的定义和声明如下 using UnityEngine; using System.Collections; public class TestController : ECControll ...

  3. C++: 类成员初始化列表语法

      类的成员初始化列表的初始化的基本语法,类的构造函数还可以运用此语法为其变量初始化: class Class { private: int a; int b; char ch; public: Cl ...

  4. C#类成员初始化顺序

    这里直接给出C#类成员一般初始化顺序: 子类静态字段 子类静态构造 子类实例字段 父类静态字段 父类静态构造 父类实例字段 父类实例构造 子类实例构造 为什么说是"一般"初始化顺序 ...

  5. Java类成员初始化顺序

    类中包含7中成员:1.静态变量 static2.final静态常量 final static3.静态代码块 static{}  //多个代码块顺序执行 4.普通变量5.普通代码块 {}  //多个代码 ...

  6. java小心机(5)| 浅谈类成员初始化顺序

    类成员什么时候会被初始化呢?一般来说:"类的代码在初次使用时才被加载",加载过程包括了初始化. 比如说new A()调用构造函数时,类中全部成员都会被初始化. 但对于static域 ...

  7. C#类和类成员初始化顺序

    1.不带静态成员的普通类,首先通过构造函数初始化. 2.带静态属性的类,无论是普通类还是静态类,都会先初始化静态字段,再执行构造函数. 3.类初始化时,不会执行类中方法,无论是否是静态.若想执行方法, ...

  8. 109-PHP类成员初始化值

    <?php class mao{ //定义猫类 public $age=0; //定义多个属性并初始化 public $weight=50; public $color='white'; } $ ...

  9. C++类成员初始化列表的构造顺序

    看下面代码, 输出结果是多少呢? class A{ public: A(int k) : j(k), i(j) { } void show() { cout << this->i & ...

随机推荐

  1. 9.java.lang.ClassCastException

    java.lang.ClassCastException 数据类型转换异常 当试图将对某个对象强制执行向下转型,但该对象又不可转换又不可转换为其子类的实例时将引发该异常,如下列代码. Object o ...

  2. delphi程序设计之底层原理

    虽然用delphi也有7,8年了,但大部分时间还是用在系统的架构上,对delphi底层还是一知半解,今天在网上看到一篇文章写得很好,虽然是07年的,但仍有借鉴的价值. 现摘录如下: Delphi程序设 ...

  3. iPhone/iTouch免99美刀真机调试

    本文经本人验证,攻略来源于网上,由于多次转载原始出处不可靠,故无法对原作者进行链接引用,抱歉. 本文仅为记录流程,以备日后查询.本文版权所无,欢迎转载和拍砖. 测试环境: XCode 4.0.2 + ...

  4. MFC上下浮动与渐入渐出消息提示框实现

    类似QQ与360软件,消息提示有两种.上下浮动.渐入渐出. 1.上下浮动提示框实现 机制,定时器响应上下浮动消息. 主要API:MoveWindow. 源码如下UpDownTipDlg.h.UpDow ...

  5. 2016 Multi-University Training Contest 5&6 总结

    第五场和第六场多校都打得很糟糕. 能做到不以物喜不以己悲是假的,这对队伍的情绪也可以算上是比较大的打击. 很多时候我们发现了问题,但是依旧没有采取有效的方法去解决它,甚至也没有尝试去改变.这是一件相当 ...

  6. 如何在XML 加入特殊字符内容 如< >

    XML 文件本身包含了一些预定义的保留字符 如< 标记元素的开始符号等 如果要在属性或者元素的值里面包含类似的这些特殊字符 应该如何处理呢 ? 这时候要用到  <![CDATA[] 这个标 ...

  7. java自己主动生成验证码

    代码结构: web.xml <? xml version="1.0" encoding="UTF-8"?> <web-app version= ...

  8. android插件化-apkplugdemo源代码阅读指南-10

    阅读本节内容前可先了解 apkplug基础教程 本教程是基于apkplug V1.6.8 版本号编写  最新开发方式以官网为准 可下载最新的apkplugdemo源代码http://git.oschi ...

  9. 1.对于.NET的初步理解和介绍

    好久没写博客了,最近心情比较low,不知道为什么.很流行的一个问题叫做:如果你明天就挂了,那么你最后悔的事情将会是什么.我想了两个月,答案是不知道,无所谓.这样不好,那这个问题先放一边吧,我们开始这一 ...

  10. jquery新增,删除 ,修改,清空select中的option

    jQuery获取Select选择的Text和Value: 1. var checkText=jQuery("#select_id").find("option:selec ...