#encoding=utf-8
#import sys
import os
import re
import UI
class Cacu(object):
def __init__(self):
self.file_type = []
self.DIR_PATH = ''
def CalcLines(self, lineList):
lineNo = 0
totalLines = len(lineList)
codeLines = 0
commentLines = 0
emptyLines = 0
while lineNo < len(lineList):
if lineList[lineNo].isspace(): #空行
emptyLines += 1
lineNo += 1
continue
regMatch = re.match('^([^/]*)/(/|\*)+(.*)$', lineList[lineNo].strip())
if regMatch != None: #注释行
commentLines += 1
#代码&注释混合行
if regMatch.group(1) != '':
codeLines += 1
elif regMatch.group(2) == '*' and re.match('^.*\*/.+$', regMatch.group(3)) != None:
codeLines += 1
#行注释或单行块注释
if '/*' not in lineList[lineNo] or '*/' in lineList[lineNo]:
lineNo += 1; continue
#跨行块注释
lineNo += 1
while '*/' not in lineList[lineNo]:
if lineList[lineNo].isspace():
emptyLines += 1
else:
commentLines += 1
lineNo = lineNo + 1
continue
commentLines += 1 #'*/'所在行
else: #代码行
codeLines += 1
lineNo += 1; continue
return [totalLines, codeLines, commentLines, emptyLines,0]
#print ('%s' %(line),) #注意行末逗号
#print ('%s' %(line.strip()))
def CountFileLines(self, filePath):
fileExt = os.path.splitext(filePath)
#if fileExt[1] != '.v': #and fileExt[1] != '.h': #识别C文件
if fileExt[-1][1:] not in self.file_type:
return
try:
fileObj = open(filePath, 'r')
except IOError:
print ('Cannot open file (%s) for reading!', filePath)
else:
lineList = fileObj.readlines()
fileObj.close()
self.rawCountInfo[:-1] = [x+y for x,y in zip(self.rawCountInfo[:-1], self.CalcLines(lineList))]
self.rawCountInfo[-1] += 1
self.detailCountInfo.append([filePath, self.CalcLines(lineList)])
#print(self.rawCountInfo)
#print(self.detailCountInfo)
def ReportCounterInfo(self):
print ('FileLines CodeLines CommentLines EmptyLines %s' %('FileName' or ''))
#print ('%-11d%-11d%-14d%-12d<Total:%d Files>' %(self.rawCountInfo[0], self.rawCountInfo[1],self.rawCountInfo[2], self.rawCountInfo[3], self.rawCountInfo[4]))
total = [0, 0, 0, 0]
#对self.detailCountInfo按第一列元素(文件名)排序,以提高输出可读性
#import operator; self.detailCountInfo.sort(key=operator.itemgetter(0))
self.detailCountInfo.sort(key=lambda x:x[0]) #简洁灵活,但不如operator高效
for item in self.detailCountInfo:
#print ('%-11d%-11d%-14d%-12d%s' %(item[1][0], item[1][1], item[1][2], item[1][3], item[0]))
total[0] += item[1][0]; total[1] += item[1][1]
total[2] += item[1][2]; total[3] += item[1][3]
print ('%-11d%-11d%-14d%-12d<Total:%d Files>' %(total[0], total[1], total[2], total[3], len(self.detailCountInfo)))
def CountDirLines(self, dirPath):
self.rawCountInfo = [0, 0, 0, 0, 0]
self.detailCountInfo = []
if not os.path.exists(dirPath):
print (dirPath + ' is non-existent!')
return
if not os.path.isdir(dirPath):
print (dirPath + ' is not a directory!')
return
for root, dirs, files in os.walk(dirPath):
for file in files:
self.CountFileLines(os.path.join(root, file))
#self.ReportCounterInfo()
#return [self.detailCountInfo,self.rawCountInfo]
if __name__ == '__main__':
mUI = UI.UI()
mUI.launch()
mCacu = Cacu()
mCacu.DIR_PATH = mUI.file_path_var.get()
for item in mUI.file_types:
if mUI.file_type_var[item].get():
mCacu.file_type.append(item)
if len(sys.argv) == 1: #脚本名
mCacu.CountDirLines(mCacu.DIR_PATH)
print(mCacu.rawCountInfo)
print(mCacu.detailCountInfo)
sys.exit()
'''
if len(sys.argv) >= 2:
if int(sys.argv[1]):
mCacu.CountDirLines(dir_path, False)
#print(mCacu.rawCountInfo)
#print(mCacu.detailCountInfo)
else:
mCacu.CountDirLines(dir_path)
#print(mCacu.rawCountInfo)
#print(mCacu.detailCountInfo)
sys.exit()
'''
#encoding=utf-8
from tkinter import *
from tkinter.filedialog import askdirectory
import tkinter.messagebox as tm
from tkinter import ttk
import caculate as Ca
summary_str = ['总行数','代码行数','注释行数','空白行数','注释率']
class UI(object):
def __init__(self):
self.root = Tk()
self.root.title('AnnotationRateTool')
self.file_types = ['c', 'h', 'v']
self.root.resizable(width = False,height = False)
#######################选择文件路径#################################
def select_path_func(self):
self.file_path_var.set(askdirectory())
def select_path(self):
self.path_frame = Frame(self.root)
self.path_frame.pack(fill = X, padx = 10, pady = 5)
Button(self.path_frame, text = '选择路径', command = self.select_path_func).pack(side = LEFT, padx = 10)
self.file_path_var = StringVar()
Entry(self.path_frame, textvariable = self.file_path_var, width = 40).pack(side = LEFT, padx = 3, pady = 3)
#######################选择代码类型#################################
def initial(self):
mCa.file_type = []
nodes = self.file_excel.get_children("")
for node in nodes:
self.file_excel.delete(node)
self.summary_entry_var['注释率'].set('0')
def start_btn_clicked(self):
print('button clicked')
self.initial()
for item in mUi.file_types:
if mUi.file_type_var[item].get():
mCa.file_type.append(item)
print(mCa.file_type)
dir_path = self.file_path_var.get()
if(dir_path == '' or len(mCa.file_type) == 0):
tm.showwarning('',"文件路径或文件类型为空")
mCa.CountDirLines(dir_path)
i = 0
for info in mCa.detailCountInfo:
print(info)
i = i + 1
if(len(info) != 0 and (info[1][1] + info[1][2]) != 0):
self.file_excel.insert("",'end',values = (i,info[0],info[1][0],info[1][1],info[1][2],info[1][3],'{:.2f}%'.format(info[1][2]/(info[1][1] + info[1][2]) * 100)))
for i in range(0,len(summary_str) - 1):
self.summary_entry_var[summary_str[i]].set(mCa.rawCountInfo[i])
if(len(mCa.rawCountInfo)!= 0 and (mCa.rawCountInfo[1] + mCa.rawCountInfo[2]) != 0):
self.summary_entry_var['注释率'].set('{:.2f}%'.format(mCa.rawCountInfo[2]/(mCa.rawCountInfo[1] + mCa.rawCountInfo[2]) * 100))
print(mCa.rawCountInfo)
return
def select_file_type(self):
self.file_type_frame = Frame(self.root)
self.file_type_frame.pack(fill = X, padx = 20, pady = 5)
Label(self.file_type_frame, text = '选择文件类型',).pack(side = LEFT)
self.file_type_var = {}
self.file_type_cb = {}
for file_type in self.file_types:
self.file_type_var[file_type] = IntVar()
self.file_type_cb[file_type] = Checkbutton(self.file_type_frame, text = file_type, variable = self.file_type_var[file_type])
self.file_type_cb[file_type].pack(side = LEFT)
self.start_btn = Button(self.file_type_frame, text = '开始', command = self.start_btn_clicked)
self.start_btn.pack(side = LEFT, padx = 10)
#######################文件详细信息#################################
'''
def get_detail(self):
print('button clicked')
dir_path = mUi.file_path_var.get()
mCa.CountDirLines(dir_path)
def show_detail(self):
nodes = self.file_excel.get_children()
if node in nodes:
self.file_excel.delete(node)
for info in mCa.detailCountInfo:
print(info)
#self.file_excel.insert("",'end',)
return
'''
def file_detail(self):
#head_str = ['序号','文件名','总行数','代码行数','注释行数','空白行数','注释率']
self.show_detail_frame = Frame(self.root)
self.show_detail_frame.pack(fill = X, padx = 10, pady = 10)
mScrollbar = Scrollbar(self.show_detail_frame)
mScrollbar.pack(side = RIGHT, fill = Y)
self.file_excel = ttk.Treeview(self.show_detail_frame, show = 'headings', yscrollcommand = mScrollbar.set)
mScrollbar['command'] = self.file_excel.yview
self.file_excel["columns"] = ('序号','文件名','总行数','代码行数','注释行数','空白行数','注释率')
#self.file_excel.bind('<ButtonRelease-1>',self.get_detail)
#self.file_excel.bind('<3>',self.show_detail)
self.file_excel.column('序号',width=50,anchor='center')
self.file_excel.column('文件名',width=500,anchor='w')
self.file_excel.column('总行数',width=80,anchor='center')
self.file_excel.column('代码行数',width=80,anchor='center')
self.file_excel.column('注释行数',width=80,anchor='center')
self.file_excel.column('空白行数',width=80,anchor='center')
self.file_excel.column('注释率',width=80,anchor='center')
self.file_excel.heading('序号',text='序号')
self.file_excel.heading('文件名',text='文件名')
self.file_excel.heading('总行数',text='总行数')
self.file_excel.heading('代码行数',text='代码行数')
self.file_excel.heading('注释行数',text='注释行数')
self.file_excel.heading('空白行数',text='空白行数')
self.file_excel.heading('注释率',text='注释率')
#for item in head_str:
#self.file_excel.column(item, width = 100)
# self.file_excel.heading(item, text = item)
self.file_excel.pack()
#######################结果统计#################################
def show_summary(self):
self.summary_frame = Frame(self.root)
self.summary_frame.pack(fill = X, padx = 10, pady = 5)
self.summary_entry_var = {}
self.summary_entry = {}
for item in summary_str:
Label(self.summary_frame, text = item,).pack(side = LEFT)
self.summary_entry_var[item] = StringVar()
self.summary_entry[item] = Entry(self.summary_frame, textvariable = self.summary_entry_var[item], width = 10)
self.summary_entry[item].pack(side = LEFT, padx = 3, pady = 3)
def launch(self):
self.select_path()
self.select_file_type()
self.file_detail()
self.show_summary()
self.root.mainloop()
if __name__ == '__main__':
mCa = Ca.Cacu()
mUi = UI()
mUi.launch()