Python C代码统计工具的代码实现

发布时间:2022-04-22 09:44:33 人气:242 作者:多测师

  首先,定义两个存储统计结果的列表:

  rawCountInfo = [0, 0, 0, 0, 0]

  detailCountInfo = []

  其中,rawCountInfo存储粗略的文件总行数信息,列表元素依次为文件行、代码行、注释行和空白行的总数,以及文件数目。detailCountInfo存储详细的统计信息,包括单个文件的行数信息和文件名,以及所有文件的行数总和。这是一个多维列表,存储内容示例如下:

  [['line.c', [33, 19, 15, 4]], ['test.c', [44, 34, 3, 7]]]

  以下将给出具体的实现代码。为避免大段粘贴代码,以函数为片段简要描述。

  def CalcLines(lineList):

  lineNo, totalLines = 0, len(lineList)

  codeLines, commentLines, emptyLines = 0, 0, 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]

  CalcLines()函数基于C语法判断文件行属性,按代码、注释或空行分别统计。参数lineList由readlines()读取文件得到,读到的每行末尾均含换行符。strip()可剔除字符串首尾的空白字符(包括换行符)。当通过print输出文件行内容时,可采用如下两种写法剔除多余的换行符:

PythonC代码统计工具的代码实现

  print '%s' %(line), #注意行末逗号

  print '%s' %(line.strip())

  行尾包含换行符的问题也存在于readline()和read()调用,包括for line in file的语法。对于read()调用,可在读取文件后split(' ')得到不带换行符的行列表。注意,调用readlines()和read()时,会读入整个文件,文件位置指示器将指向文件尾端。此后再调用时,必须先通过file.seek(0)方法返回文件开头,否则读取的内容为空。

  def CountFileLines(filePath, isRaw=True):

  fileExt = os.path.splitext(filePath)

  if fileExt[1] != '.c' and fileExt[1] != '.h': #识别C文件

  return

  try:

  fileObj = open(filePath, 'r')

  except IOError:

  print 'Cannot open file (%s) for reading!', filePath

  else:

  lineList = fileObj.readlines()

  fileObj.close()

  if isRaw:

  global rawCountInfo

  rawCountInfo[:-1] = [x+y for x,y in zip(rawCountInfo[:-1], CalcLines(lineList))]

  rawCountInfo[-1] += 1

  else:

  detailCountInfo.append([filePath, CalcLines(lineList)])

  CountFileLines()统计单个文件的行数信息,其参数isRaw指示统计报告是粗略还是详细的。对于详细报告,需要向detailCountInfo不断附加单个文件的统计结果;而对于详细报告,只需要保证rawCountInfo的元素值正确累加即可。

  def ReportCounterInfo(isRaw=True):

  #Python2.5版本引入条件表达式(if-else)实现三目运算符,低版本可采用and-or的短路特性

  #print 'FileLines CodeLines CommentLines EmptyLines %s' %('' if isRaw else 'FileName')

  print 'FileLines CodeLines CommentLines EmptyLines %s' %(not isRaw and 'FileName' or '')

  if isRaw:

  print '%-11d%-11d%-14d%-12d' %(rawCountInfo[0], rawCountInfo[1],

  rawCountInfo[2], rawCountInfo[3], rawCountInfo[4])

  return

  total = [0, 0, 0, 0]

  #对detailCountInfo按第一列元素(文件名)排序,以提高输出可读性

  #import operator; detailCountInfo.sort(key=operator.itemgetter(0))

  detailCountInfo.sort(key=lambda x:x[0]) #简洁灵活,但不如operator高效

  for item in 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[0], total[1], total[2], total[3], len(detailCountInfo))

  ReportCounterInfo()输出统计报告。注意,详细报告输出前,先按文件名排序。

  def CountDirLines(dirPath, isRawReport=True):

  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:

  CountFileLines(os.path.join(root, file), isRawReport)

  ReportCounterInfo(isRawReport)

  CountDirLines()统计当前目录及其子目录下所有文件的行数信息,并输出统计报告。注意,os.walk()不一定按字母顺序遍历文件。在作者的Windows XP主机上,os.walk()按文件名顺序遍历;而在Linux Redhat主机上,os.walk()以"乱序"遍历。

  最后,添加简单的命令行处理:

  if __name__ == '__main__':

  DIR_PATH = r'E:PyTestlctest'

  if len(sys.argv) == 1: #脚本名

  CountDirLines(DIR_PATH)

  sys.exit()

  if len(sys.argv) >= 2:

  if int(sys.argv[1]):

  CountDirLines(DIR_PATH, False)

  else:

  CountDirLines(DIR_PATH)

  sys.exit()

  以上内容为大家介绍了PythonC代码统计工具的代码实现,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注多测师。https://www.e70w.com/xwzx/


返回列表
在线客服
联系方式

热线电话

17727591462

上班时间

周一到周五

二维码
线