def whetherHasSourceBetweenTwoLine(lines, startLineNo, startIndex, endLineNo, endIndex):
  '''检查指定的两个位置之间是否有代码{对应的}的行号和其所在行的位置
  Args:
    lines:所有行
    startLineNo:开始的行号
    startIndex:开始行中开始查找的位置
    endLineNo:结束的行号
    endIndex:结束行中开始查找的位置
  Returns:
    True:指定的两个位置之间有代码;False:指定的两个位置之间没有代码
  '''
  # 开始行,startIndex之后有代码
  if not common.IsBlankLine(lines[startLineNo][startIndex + 1:]):
    return True
  # 结束行,endIndex之前有代码
  if not common.IsBlankLine(lines[endLineNo][:endIndex]):
    return True
  i = startLineNo + 1
  while i < endLineNo:
    #null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # 有代码行
    return True
  return False
Exemple #2
0
def checkNewLine(filename, indentation, lines, startLineNo, endLineNo, ruleCheckKey, Error):
  errMessageHeader = 'Code Style Rule: If an expression is too long,'
  errorMessageIndentation = ' it should be wrapped, and the new line should indent 4 spaces.'
  errorMessageStartWord = ' it should be wrapped before a Logical AND (&&) or a Logical OR (||).'
  errorMessageBoth = ' it should be wrapped before a Logical AND (&&) or a Logical OR (||), and the new line should indent 4 spaces.'
  
  checkStartLineNo = startLineNo + 1
  maxLimit = endLineNo+ 1
  skipEndLno = -1
  previousLine = lines[startLineNo].strip()
  for i in xrange(checkStartLineNo, maxLimit):
    errorMessage = ''
    hasIndentationError = False
    hasStartWordError = False
    #if ( a > 1
    #   ) --如果最后一个右括号所在的行,右括号前没有代码,则不check
    if i == endLineNo and lines[i].strip().startswith(')') and lines[i].count(')') == 1:
      continue
    #空白行--skip
    if common.IsBlankLine(lines[i]):
      continue
    if i <= skipEndLno:
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      skipEndLno = common.getDefineMacroEndLineNo(lines, i)
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', lines[i]):
      skipEndLno = common.getDefineMacroEndLineNo(lines, i)
      continue
    #新行相对缩进4个空格check
    tempIndentation = 0
    m = strcmp.Search(r'^(\s*)\S', lines[i])
    if m:
      tempIndentation = len(m.group(1).replace('\t', '    '))
    #  缩进错误,编辑errormessage
    if indentation + 4 != tempIndentation:
      hasIndentationError = True
    #换行以二元操作符为起点check
    #  不是以二元操作符为起点,编辑errormessage
    if not checkIfStartWithDyadicOperator(lines[i], previousLine):
      hasStartWordError = True
    #如果有错误信息,报错
    if hasIndentationError and hasStartWordError:
      errorMessage = errMessageHeader + errorMessageBoth
    elif hasIndentationError:
      errorMessage = errMessageHeader + errorMessageIndentation
    elif hasStartWordError:
      errorMessage = errMessageHeader + errorMessageStartWord
    if errorMessage:
      Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
    #保存当前行,目的是下一行是以&开头时,判断&是一元操作符,还是二元操作符
    previousLine = lines[i].strip()
Exemple #3
0
def CheckCSC020006(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error):
  '''如果出现较长的表达式,也要进行换行。换行以二元逻辑操作符为起点,新行相对缩进4个空格。
  Args:
    filename:文件名
    file_extension:文件扩展名
    clean_lines:Holds 3 copies of all lines with different preprocessing applied to them
                 1) elided member contains lines without strings and comments,
                 2) lines member contains lines without comments, and
                 3) raw_lines member contains all the lines without processing.(行首以/*开头的多行注释被替换成空白)
    rawlines:all the lines without processing
    nesting_state: Holds states related to parsing braces.(cpplint中的对象,暂时未使用)
    startLineNo:for,while,if,switch所在的行
    ruleCheckKey:ruleid
    Error: error output method
  '''
  lines = clean_lines.elided
  i = 0
  while i < clean_lines.NumLines():
    #空白行--skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    #template<...> -- skip
    if strcmp.Search(r'^\s*template\s*<', lines[i]):
      i = getTemplateEndLno(lines, i)
      if i == -1:
        break
      else:
        i += 1
      continue
    m = strcmp.Search(r'(\bif\b|\bwhile\b)', lines[i])
    if m:
      indentation, startLineNo,endLineNo = getStatementStartEnd(lines, i, m.group(1))
      if endLineNo == -1 or endLineNo ==  clean_lines.NumLines() - 1:
        break
      if startLineNo == endLineNo:
        i = endLineNo + 1
        continue
      checkNewLine(filename,indentation, lines, startLineNo, endLineNo, ruleCheckKey, Error)
      i = endLineNo
    i += 1
def CheckCSC110006(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error, cpplines, fileErrorCount):
  lines = clean_lines.elided
  errMessage = "Code Style Rule: Usage of functions strcpy, sprintf, strcat is forbidden. Please use strncpy, snprintf, strncat instead."
  
  i = 0
  endLineNo = clean_lines.NumLines()
  while i < clean_lines.NumLines():
    #空白行--skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i += 1
      continue

    if (strcmp.Search(r'(\b^\.*strcpy\b\s*\()|(\b^\.*sprintf\b\s*\()|(\b^\.*strcat\b\s*\()', lines[i])):
      Error(filename, lines, i, ruleCheckKey, 3, errMessage)
      i += 1
      continue
  
    i += 1
def getFunctionCloseCurlyBraceInfo(lines, openCurlyBraceLno, openCurlyBraceIdx):
  '''返回{对应的}的行号和其所在行的位置
  Args:
    lines:所有行
    openParenthesisLno:{所在行的行号
    openParenthesisIdx:{在其所在行的位置
  Returns:
            返回{对应的}所在的line number和其所在行的位置;如果查不到},则返回-1, -1
  '''
  lengthOfLines =len(lines)
  i = openCurlyBraceLno
  openCurlyBraceQty = 0
  closeCurlyBraceQty = 0
  while i < lengthOfLines:
    #null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    if i == openCurlyBraceLno:
      checkStartIndex = openCurlyBraceIdx
    else:
      checkStartIndex = 0
    # #逐个字符累计左右大括号
    for j in xrange(checkStartIndex, len(lines[i])):
      if lines[i][j] == '{':
        openCurlyBraceQty += 1
      elif lines[i][j] == '}':
        closeCurlyBraceQty += 1
      else:
        continue
      # 左右大括号的个数相同时,返回右大括号的行号和位置
      if openCurlyBraceQty == closeCurlyBraceQty and openCurlyBraceQty > 0:
        return i, j
    i += 1
  # 如果查不到*/,则返回-1,说明文件有问题,不要再check该文件了
  return -1, -1
Exemple #6
0
def getEndInfoOfCondition(lines, startLineNo, keyWordIndex):
  '''函数功能:查找for,while,if,switch后面的()中)所在的行,及其在所在行的位置
  Args:
    lines:文件中各个行的内容组成的数组(已去完注释,字符串已被清空)
    startLineNo:for,while,if,switch所在的行
    keyWordIndex:for,while,if,switch在行中的index
  Returns:
             右圆括号的lineNo,其位于所在行的位置,如果找不到,则返回-1,-1
  '''
  linesLength = len(lines)
  i = startLineNo
  openParenthesisQty = 0
  closeParenthesisQty = 0
  while i < linesLength:
    #空白行--skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    checkStartIndex = 0
    if i == startLineNo:
      checkStartIndex = keyWordIndex
    #逐个字符累计左右圆括号
    for j in xrange(checkStartIndex, len(lines[i])):
      if lines[i][j] == '(':
        openParenthesisQty += 1
      elif lines[i][j] == ')':
        closeParenthesisQty += 1
      #左右圆括号个数相同,则返回最后一个右圆括号的lineNo,其位于所在行的位置
      if openParenthesisQty == closeParenthesisQty and openParenthesisQty > 0:
        return i, j
    i += 1
  return -1, -1
Exemple #7
0
def checkNewLine(filename, lines, startLineNo, endLineNo, ruleCheckKey, Error):
  errMessage = 'Code Style Rule: When a function declaration/definition is too long, it should be wrapped before the type of a parameter. For example, funcA(int a, int b) should wrap before "int b".'
  checkStartLineNo = startLineNo + 1
  maxLimit = endLineNo + 1
  skipEndLno = -1
  previousLine = lines[startLineNo].strip()
  for i in xrange(checkStartLineNo, maxLimit):
    errorMessage = ''
    #空白行--skip
    if common.IsBlankLine(lines[i]):
      continue
    if i <= skipEndLno:
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      skipEndLno = common.getDefineMacroEndLineNo(lines, i)
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', lines[i]):
      skipEndLno = common.getDefineMacroEndLineNo(lines, i)
      continue
    line = lines[i].strip()
    # int func(int a \n\t )不报错;
    if line.startswith(')'):
      previousLine = lines[i].strip()
      continue
    # int func(\n \tint a)不报错;
    if previousLine.endswith('('):
      previousLine = lines[i].strip()
      continue
    # int func(int \n\t&a)报错;int func(int \n\t*a)报错;
    if line.startswith('&') or line.startswith('*'):
      Error(filename, lines, i, ruleCheckKey, 3, errMessage)
    #int func(int  \n\ta,int b )报错
    elif not previousLine.endswith(','):
      Error(filename, lines, i, ruleCheckKey, 3, errMessage)
    #保存当前行,目的是下一行是以&开头时,判断&是一元操作符,还是二元操作符
    previousLine = lines[i].strip()
def CheckCSC030008(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error, cpplines, fileErrorCount):
  lines = clean_lines.elided
  
  isClassDeclare = False

  i = 1
  while i < len(lines) :
    
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
  
    if strcmp.Search(r'^\s*#', lines[i]):
      i += 1
      continue
  
    # template类型例子,
    # template <class T, ASN1::natural explicit_tag,  
    #     ASN1::tag_class_enum explicit_tag_class = ASN1::class_context_specific>
    if strcmp.Search(r'^\s*template\s*<', lines[i]):
      iRet = getTemplateEndLno(lines, i)
      if iRet != -1:
        i = iRet + 1
        continue
    
    # eg. class A {
    # 查找到class类名后,检查类作用域内是否有public / protected / private关键字
    # 排除namespace中的class声明 class NCWifiEvent; template <class T>
    if strcmp.Search(r'^\s*class\s+\w+', lines[i]) and not strcmp.Search(r'^\s*class\s+\w+\s*;', lines[i]) and not strcmp.Search(r'^\s*class\s+\w+\s*>', lines[i]) and lines[i].count('(') == 0:
      
      #判断是否是类定义
      isClassDeclare,startLineNo,endLineNo = common.isClassDeclareCheck(lines, i)
      
      #当class的类定义中,所有的代码都是在同一行时,没必要check
      if startLineNo == endLineNo:
        i = endLineNo + 1
        continue
      #check 类定义
      if isClassDeclare:
        checkClassBlock(filename, lines, startLineNo, endLineNo, ruleCheckKey, Error, cpplines, fileErrorCount)
        i = endLineNo + 1
        continue

    i += 1
def CheckCSC100005(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error, cpplines, fileErrorCount):
  lines = clean_lines.elided
  i = 0
  isClassDeclare = False
  while i < clean_lines.NumLines():
    #空白行--skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i += 1
      continue
    #template<...> -- skip
    if strcmp.Search(r'^\s*template\s*<', lines[i]):
      i = getTemplateEndLno(lines, i)
      if i == -1:
        break
      else:
        i += 1
      continue
    #行是以"几个空格+class"或者"class"开头时,check class
    if strcmp.Search(r'^(\s*)\bclass\b', lines[i]):
      #判断该段代码是否以class为返回值的函数
      if isFunctionDeclare('class', lines, i):
        i += 1
        continue
      #判断是否是类定义
      isClassDeclare,startLineNo,endLineNo = common.isClassDeclareCheck(lines, i)
      #当class的类定义中,所有的代码都是在同一行时,没必要check
      if startLineNo == endLineNo:
        i = endLineNo + 1
        continue
      #check 类定义
      if isClassDeclare:
        checkClassBlock(filename, lines, startLineNo, lines[startLineNo], endLineNo, ruleCheckKey, Error, cpplines, fileErrorCount)
      i = endLineNo
    i += 1
  
      
Exemple #10
0
def CheckCSC080005(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error):
  lines = clean_lines.elided
  errMessage = "Code Style Rule: Please put the opening curly brace of a for loop on the same line with the for keyword."
  
  i = 0
  while i < clean_lines.NumLines():
    
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
  
    if strcmp.Search(r'^\s*for\s*\(', lines[i]):
      lineNo = getParenthesisEndLineNo(lines, i)
      if lineNo != -1:
          i = lineNo
          if not lines[i].strip().endswith('{'):
            Error(filename, lines, i, ruleCheckKey, 3, errMessage)
            i = i + 1
            continue
    
    i += 1
def getNextNotNullLineNo(lines, startLno):
  '''从startLno向下查找第一个非空的行
  Args:
    lines:a copy of all lines without strings and comments
    startLno:目标行
  Returns:
           第一个非空的行的行号
  '''
  lengthOfLines = len(lines)
  i = startLno + 1
  while i < lengthOfLines:
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    elif strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    else:
      break
  if i < lengthOfLines:
    return i
  else:
    return lengthOfLines - 1
Exemple #12
0
def CheckCSC030027(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error):
  '''左大括号{之后如果有内容,请保留一个空格。[必须] 
  Args:
    filename:文件名
    file_extension:文件扩展名
    clean_lines:Holds 3 copies of all lines with different preprocessing applied to them
                 1) elided member contains lines without strings and comments,
                 2) lines member contains lines without comments, and
                 3) raw_lines member contains all the lines without processing.(行首以/*开头的多行注释被替换成空白)
    rawlines:all the lines without processing
    nesting_state: Holds states related to parsing braces.(cpplint中的对象,暂时未使用)
    startLineNo:for,while,if,switch所在的行
    ruleCheckKey:ruleid
    Error: error output method
  '''
  lines = clean_lines.elided
  errMessage = 'Code Style Rule: If there is contents after a left curly brace "{", please leave a space between them.'
  i = 0
  while i < clean_lines.NumLines():
    # null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i += 1
      continue
    m = strcmp.Search(r'\{[^\s\}\\]', lines[i])
    # 当 { 后面的字符不是空格,也不是},也不是换行符时,报错
    if m:
      Error(filename, lines, i, ruleCheckKey, 3, errMessage)
    i += 1
def CheckCSC030017(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error, cpplines, fileErrorCount):
  
  # 赋值判断
  #因为 * & 即是指针也是运算符,无法判断,所有不判断这两个
  arraySign1 = ["+","-","*","/","%","&", "|", "~", "^"]
  # 运算符 
  # eg. if (a && b), if (a || b)
  arraySign2 = ["&&", "||"]
  # 必须在等号后判断的,否则容易产生误判
  # error 数据有赋值为负数的情况,'-'删除
  arraySign3 = ["+","/","%", "|", "<<", ">>"]
  
  lines = clean_lines.elided
  errMessage = "Code Style Rule: There should a space both before and after a binary operator \"%s\". For example: A = B."
  i = 0
  FoldinglineFlag = False
  line = ''
  while i < clean_lines.NumLines():
    findFlg = True
    index = 0
    signTag = ''
    
    if lines[i].endswith("\\"):
      # 换行的第一行,清空缓存的line
      if not FoldinglineFlag:
        line = ''
        
      FoldinglineFlag = True
      line = line + lines[i][0:len(lines[i])]
      i += 1
      continue
    else :
      # 换行的最后一行
      if FoldinglineFlag:
        line = line + lines[i]
        line = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', line)
        line = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", line)
        line = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', line)
      else :
        line = lines[i]
        
      FoldinglineFlag = False
        
    line = lines[i].replace("->", ".")
        
    if common.IsBlankLine(line):
      i += 1
      continue
  
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
  
    if strcmp.Search(r'^\s*#', line):
      i += 1
      continue
    
    
    # 查找"operator",忽略操作符重载的函数名的判断
    if strcmp.Search(r'\boperator\b', line):
      i += 1
      continue
  
    # 查找"===",忽略
    if strcmp.Search(r'===', line):
      i += 1
      continue
  
    #只判断结束语句
    endPos = line.rfind(";")
    if endPos == -1:
      endPos = len(line)
    
    # 查找"="
    index2 = line.rfind("=", 0, endPos)
    if -1 != index2 and -1 == line.find('virtual ', 0, index2):
    
      # 忽略字符串中的 = 的判断
      # static std::string myTestData = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
      #strFlgIndex = line.find("\"", 0, endPos)
      #if strFlgIndex >= index2:
      #  i += 1
       # continue
    
      arraySign1FLg = False
      
      index3 = cpplines[i].rfind("=", 0, endPos)
      # 判断前一位是否为运算符
      if line[index2 - 1:index2] in arraySign1:
        findFlg = checkSignLeftRightBlank(line, index2 - 2, index2 + 1)
        signTag = line[index2 - 1:index2] + '='
        arraySign1FLg = True
        if not findFlg:
          replaceCorrectString(cpplines, i, index3 - 2, index3 + 1, signTag)
          fileErrorCount[0] =  fileErrorCount[0] + 1
      
      if not arraySign1FLg:
        if line[index2 - 1:index2] == "<" or line[index2 - 1:index2] == ">":
          # "<<=",">>=" 情况
          if line[index2 - 2:index2 - 1] == "<" or line[index2 - 2:index2 - 1] == ">":
            findFlg = checkSignLeftRightBlank(line, index2 - 3, index2 + 1)
            
            signTag = line[index2 - 2:index2] + '='
            if not findFlg:
              replaceCorrectString(cpplines, i, index3 - 3, index3 + 1, signTag)
              fileErrorCount[0] =  fileErrorCount[0] + 1
          else:
             # "<=",">=" 情况
            findFlg = checkSignLeftRightBlank(line, index2 - 2, index2 + 1)
            signTag = line[index2 - 2:index2] + '='
            
            if not findFlg:
              replaceCorrectString(cpplines, i, index3 - 2, index3 + 1, signTag)
              fileErrorCount[0] =  fileErrorCount[0] + 1
          
           # "!=" 情况
        elif line[index2 - 1:index2] == "!" :
          findFlg = checkSignLeftRightBlank(line, index2 - 2, index2 + 1)
          signTag = '!='
          if not findFlg:
            replaceCorrectString(cpplines, i, index3 - 2, index3 + 1, signTag)
            fileErrorCount[0] =  fileErrorCount[0] + 1
          # "==" 情况
        elif line[index2 - 1:index2] == "=" :
          findFlg = checkSignLeftRightBlank(line, index2 - 2, index2 + 1)
          signTag = '=='
          if not findFlg:
            replaceCorrectString(cpplines, i, index3 - 2, index3 + 1, signTag)
            fileErrorCount[0] =  fileErrorCount[0] + 1
        else:
          # "=" 情况
          findFlg = checkSignLeftRightBlank(line, index2 - 1, index2 + 1)
          signTag = '='
          if not findFlg:
            replaceCorrectString(cpplines, i, index3 - 1, index3 + 1, signTag)
            fileErrorCount[0] =  fileErrorCount[0] + 1
              
          for k in xrange(len(arraySign3)):
            index = line.find(arraySign3[k], index2, endPos)
            # "||" 在 '|'判断时产生误判
            if -1 != index and line[index: index +2 ] != '||':
              # next = *s++ 误判
              indexPlusPlus = line.find('++')
              if indexPlusPlus == index:
                continue
            
              findFlg = checkSignLeftRightBlank(line, index - 1, index + len(arraySign3[k]))
              signTag = arraySign3[k]
              if not findFlg:
                index = cpplines[i].find(arraySign3[k], index2, endPos)
                replaceCorrectString(cpplines, i, index - 1, index + len(arraySign3[k]), signTag)
                fileErrorCount[0] =  fileErrorCount[0] + 1
               
              break
          
    # 赋值判断
    for j in xrange(len(arraySign2)):
      index = line.find(arraySign2[j], 0, endPos)
      if -1 != index:
        findFlg = checkSignLeftRightBlank(line, index - 1, index + len(arraySign2[j]))
        signTag = arraySign2[j]
        
        if not findFlg:
          index = cpplines[i].find(arraySign2[j], 0, endPos)
          replaceCorrectString(cpplines, i, index - 1, index + len(arraySign2[j]), signTag)
          fileErrorCount[0] =  fileErrorCount[0] + 1
    
    #如果是类似 (XXX)*(XXX) 的形式,也需要报错。因为这种情况说明写法有问题,导致无法判断是乘号还是指针
    if strcmp.Search(r'\(\w+\)\*\(\w+\)', line):
      signTag = '*'
      findFlg = False
      if not findFlg:

        cpplines[i] = cpplines[i].replace(")*(", ") * (")
        fileErrorCount[0] =  fileErrorCount[0] + 1
    
    if not findFlg:
      Error(filename, lines, i, ruleCheckKey, 3, errMessage % signTag)
  
    i += 1
# end of CheckCSC030017
Exemple #14
0
def CheckCSC140009(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error):
  '''函数声明的注释要求:函数的概要说明与详细说明之间必须空一行。[必须]
  (其他规则要求概要说明只能写在一行)
  Args:
    filename:文件名
    file_extension:文件扩展名
    clean_lines:Holds 3 copies of all lines with different preprocessing applied to them
                 1) elided member contains lines without strings and comments,
                 2) lines member contains lines without comments, and
                 3) raw_lines member contains all the lines without processing.(行首以/*开头的多行注释被替换成空白)
    rawlines:all the lines without processing
    nesting_state: Holds states related to parsing braces.(cpplint中的对象,暂时未使用)
    ruleCheckKey:ruleid
    Error: error output method
  '''
  particularTypeList = []
  lines = clean_lines.elided
  isStrutsEnumUnionDeclare = False
  strutsEnumUnionOpenLno = 0
  regExp = ''
  skipEndLno = -1
  i = 0
  templateStartLno = -1
  while i < clean_lines.NumLines():
    #null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i += 1
      continue
    # template declare ,goto next line
    m = strcmp.Search(r'^\s*template\s*<', lines[i])
    if m:
      if i == -1:
        break
      templateStartLno = i
      i = getTemplateEndLno(lines, i) + 1
    else:
      templateStartLno = -1
    # check typedef,将定于的类型别名存放到particularTypeList中
    # typedef特殊类型(结构体,联合,枚举)check
    m = strcmp.Search(r'(\btypedef\b\s+(\bstruct\b|\bunion\b|\benum\b))\s*(\w+)\s*{*', lines[i].replace('*',' ').replace('&',' '))
    if m:
      typeList,skipEndLno = getNickNameFromTypedefParticularType(m.group(1), lines, i)
      for typeListItem in typeList:
        if not (typeListItem in particularTypeList):
          if not regExp:
            regExp += r'\b' + typeListItem + r'\b'
          else:
            regExp += r'|\b' + typeListItem + r'\b'
          particularTypeList.append(typeListItem)
      i = skipEndLno + 1
      continue
    # typedef单独在某一行  或者 typedef基本类型 时
    elif strcmp.Search(r'\btypedef\b', lines[i]):
      # check typedef的目标是特殊类型还是基本类型
      isTypedefParticularType,skipEndLno,typeList =getNicknameIfTypedefAndPaticulartypeInTwoLine(lines, i)
      if isTypedefParticularType:
        # 特殊类型
        for typeListItem in typeList:
          if not (typeListItem in particularTypeList):
            if not regExp:
              regExp += r'\b' + typeListItem + r'\b'
            else:
              regExp += r'|\b' + typeListItem + r'\b'
            particularTypeList.append(typeListItem)
        i = skipEndLno + 1
        continue
      else:
        # 基本类型
        typeList,skipEndLno=getNicknameFromTypedefBaseType(lines, i)
        for typeListItem in typeList:
          if not (typeListItem in particularTypeList):
            if not regExp:
              regExp += r'\b' + typeListItem + r'\b'
            else:
              regExp += r'|\b' + typeListItem + r'\b'
            particularTypeList.append(typeListItem)
        i = skipEndLno + 1
        continue
    # 特殊类型 struct AA::aa; 或者 struct A;这种声明,直接把声明的类型存放到particularTypeList中
    m = strcmp.Search(r'(\bstruct\b|\bunion\b|\benum\b)\s+(\w+|\w+::\w+);', lines[i])
    if m:
      if not (m.group(2) in particularTypeList):
        if not regExp:
          regExp += r'\b' + m.group(2) + r'\b'
        else:
          regExp += r'|\b' + m.group(2) + r'\b'
        particularTypeList.append(m.group(2))
      i += 1
      continue
    # 特殊类型(结构体,联合,枚举)定义时,将其类型保存到particularTypeList中
    m = strcmp.Search(r'(\bstruct\b|\bunion\b|\benum\b)', lines[i])
    if m:
      isStrutsEnumUnionDeclare,declareType,skipEndLno,hasError = checkStructEnumUnionDeclare(m.group(1), lines, i)
      #特殊类型(结构体,联合,枚举)定义时
      if isStrutsEnumUnionDeclare:
        if hasError:
          break
        else:
          if not (declareType in particularTypeList):
            if not regExp:
              regExp += r'\b' + declareType + r'\b'
            else:
              regExp += r'|\b' + declareType + r'\b'
            particularTypeList.append(declareType)
          if declareType.find('::') > -1:
            declareTypeTemp = declareType[declareType.find('::'):].replace('::','').strip()
            if not (declareTypeTemp in particularTypeList):
              if not regExp:
                regExp += r'\b' + declareTypeTemp + r'\b'
              else:
                regExp += r'|\b' + declareTypeTemp + r'\b'
              particularTypeList.append(declareTypeTemp)
        #跳到特殊类型定义的下一行去
        i = skipEndLno + 1
        continue
    # check 是否含有基本类型的关键字
    checkFunctionStartIndex = -1
    checkTypeword = ''
    m = strcmp.Search(r'(\bvoid\b|\bbool\b|\bchar\b|\bwchar_t\b|\bshort\b|\bint\b|\blong\b|\bfloat\b|\bdouble\b)\s*\w*\s*', lines[i].replace('*',' '))
    if m:
      checkTypeword = m.group(1)
      checkFunctionStartIndex = m.start()
      if len(particularTypeList) > 0:
        # check 是否含有特殊类型的关键字
        m = strcmp.Search(r'(' + regExp + r')\s*\w*\s*', lines[i].replace('*',' '))
        #同时找到基本类型和特殊类型关键字时,哪个在前面,以哪个为基准check函数
        if m:
          particularIndex = m.start()
          if m.start() < checkFunctionStartIndex:
            checkFunctionStartIndex = m.start()
            checkTypeword = m.group(1)
    #没有找到基本类型
    else:
      if len(particularTypeList) == 0:
        i += 1
        continue
      # check 是否含有特殊类型
      m = strcmp.Search(r'(' + regExp + r')\s*\w*\s*', lines[i].replace('*',' '))
      if m:
        checkTypeword = m.group(1)
        checkFunctionStartIndex = m.start()
    # 如果找到下面的格式的代码,判断其是否是函数声明
    # int function(...)
    # struct AAA function (...)
    if checkFunctionStartIndex > -1:
      #判断是否是函数声明或定义,左右圆括号所在的行号,是否发生错误
      isFunctionDeclareOrDefinition,checkStartLineNo,checkEndLineNo,hasError = isFunction( checkTypeword, lines, i, checkFunctionStartIndex)
      if hasError:
        break
      # 是函数声明或定义
      if isFunctionDeclareOrDefinition:
        isFunctionDeclare, blockEndLineNo = isFunctionDeclaration( lines, checkEndLineNo)
        # 文件不正常, return
        if blockEndLineNo == -1:
          return
        # 函数定义
        if not isFunctionDeclare:
          i = blockEndLineNo + 1
          continue
        # 函数声明
        #check fuction declare前的注释
        if templateStartLno == -1:
          checkStartLineNo = i - 1
        else:
          checkStartLineNo = templateStartLno - 1
        checkComment(filename, lines, rawlines, checkStartLineNo, ruleCheckKey, Error)
        i = checkEndLineNo + 1
        continue
    i += 1
    
Exemple #15
0
def isFunctionDeclaration(lines, startLno):
  '''在已知是函数的情况下,判断是否是函数声明还是函数定义
  Args:
    lines:a copy of all lines without strings and comments
    startLno: function() )所在的行的行号
  Returns:
           boolean: True--函数声明; False--函数定义
           int: 函数声明时,function() )所在的行的行号;函数定义时,返回}所在行的行号
           当文件格式不正常,无法正常判断时,返回 False,-1
  '''
  closeParenthesisIndex = lines[startLno].find(')')
  # 找不到)的位置,文件不正常
  if closeParenthesisIndex == -1:
    return False, -1
  # )所在行,)之后不为空白,且)后不是;,说明这是函数声明
  if lines[startLno].endswith('\\'):
    tempLine = lines[startLno][lines[startLno].find(')') + 1:len(lines[startLno]) - 1].strip()
  else:
    tempLine = lines[startLno][lines[startLno].find(')') + 1:].strip()
  if tempLine and tempLine.startswith(';'):
    return True, startLno
  # )之后不为空白,但是不是;也不是{,文件不正常
  if tempLine and (not tempLine.startswith('{')):
    return False, -1

  i = startLno
  lengthOfLines = len(lines)
  openCurlyBraceLineNo = -1
  while i < lengthOfLines:
    #null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i += 1
      continue
    if i == startLno:
      pass
    # 如果有换行符,去掉换行符
    elif lines[i].endswith("\\"):
      tempLine = lines[i][:len(lines[i]) -1].strip()
    else:
      tempLine = lines[i].strip()
    # 如果改行只有换行符和空格而没有代码时
    if common.IsBlankLine(tempLine):
      i += 1
      continue
    # )之后不为空白,是{,说明是函数定义
    if tempLine.startswith('{'):
      openCurlyBraceLineNo = i
      break
    # )之后不为空白,是;,说明是函数声明
    elif tempLine.startswith(';'):
      return True, startLno
    # )之后不为空白,但是不是;也不是{,文件不正常
    else:
      return False, -1

  if openCurlyBraceLineNo == -1:
    return False, -1
  # 查找{对应的}所在行的行号
  i = openCurlyBraceLineNo
  openCurlyBraceQty = 0
  closeCurlyBraceQty = 0
  closeCurlyBracelineNo = -1
  while i < lengthOfLines:
    #null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i += 1
      continue
    openCurlyBraceQty = openCurlyBraceQty + lines[i].count('{')
    closeCurlyBraceQty = closeCurlyBraceQty + lines[i].count('}')
    if openCurlyBraceQty == closeCurlyBraceQty and openCurlyBraceQty > 0:
      closeCurlyBracelineNo = i
      break
    i += 1

  # 找不到)的位置,文件不正常
  if openCurlyBraceQty != closeCurlyBraceQty or openCurlyBraceQty == 0 or closeCurlyBraceQty == 0:
    return False, -1
  # 返回:函数定义,}所在行的行号
  return False, closeCurlyBracelineNo
Exemple #16
0
def CheckCSC020003(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error):
  errorMessage = 'Code Style Rule: When a function declaration/definition is too long, it should be wrapped before the type of a parameter. For example, funcA(int a, int b) should wrap before "int b".'
  particularTypeList = []
  lines = clean_lines.elided
  isStrutsEnumUnionDeclare = False
  strutsEnumUnionOpenLno = 0
  regExp = ''
  skipEndLno = -1
  i = 0
  while i < clean_lines.NumLines():
    #null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # template declare line skip
    m = strcmp.Search(r'^\s*template\s*<', lines[i])
    if m:
      if i == -1:
        break
      i = getTemplateEndLno(lines, i) + 1
      continue
    # check typedef,将定于的类型别名存放到particularTypeList中
    # typedef特殊类型(结构体,联合,枚举)check
    m = strcmp.Search(r'(\btypedef\b\s+(\bstruct\b|\bunion\b|\benum\b))\s*(\w+)\s*{*', lines[i].replace('*',' ').replace('&',' '))
    if m:
      typeList,skipEndLno = getNickNameFromTypedefParticularType(m.group(1), lines, i)
      for typeListItem in typeList:
        if not (typeListItem in particularTypeList):
          if not regExp:
            regExp += r'\b' + typeListItem + r'\b'
          else:
            regExp += r'|\b' + typeListItem + r'\b'
          particularTypeList.append(typeListItem)
      i = skipEndLno + 1
      continue
    # typedef单独在某一行  或者 typedef基本类型 时
    elif strcmp.Search(r'\btypedef\b', lines[i]):
      # check typedef的目标是特殊类型还是基本类型
      isTypedefParticularType,skipEndLno,typeList =getNicknameIfTypedefAndPaticulartypeInTwoLine(lines, i)
      if isTypedefParticularType:
        # 特殊类型
        for typeListItem in typeList:
          if not (typeListItem in particularTypeList):
            if not regExp:
              regExp += r'\b' + typeListItem + r'\b'
            else:
              regExp += r'|\b' + typeListItem + r'\b'
            particularTypeList.append(typeListItem)
        i = skipEndLno + 1
        continue
      else:
        # 基本类型
        typeList,skipEndLno=getNicknameFromTypedefBaseType(lines, i)
        for typeListItem in typeList:
          if not (typeListItem in particularTypeList):
            if not regExp:
              regExp += r'\b' + typeListItem + r'\b'
            else:
              regExp += r'|\b' + typeListItem + r'\b'
            particularTypeList.append(typeListItem)
        i = skipEndLno + 1
        continue
    # 特殊类型 struct AA::aa; 或者 struct A;这种声明,直接把声明的类型存放到particularTypeList中
    m = strcmp.Search(r'(\bstruct\b|\bunion\b|\benum\b)\s+(\w+|\w+::\w+);', lines[i])
    if m:
      if not (m.group(2) in particularTypeList):
        if not regExp:
          regExp += r'\b' + m.group(2) + r'\b'
        else:
          regExp += r'|\b' + m.group(2) + r'\b'
        particularTypeList.append(m.group(2))
      i += 1
      continue
    # 特殊类型(结构体,联合,枚举)定义时,将其类型保存到particularTypeList中
    m = strcmp.Search(r'(\bstruct\b|\bunion\b|\benum\b)', lines[i])
    if m:
      isStrutsEnumUnionDeclare,declareType,skipEndLno,hasError = checkStructEnumUnionDeclare(m.group(1), lines, i)
      #特殊类型(结构体,联合,枚举)定义时
      if isStrutsEnumUnionDeclare:
        if hasError:
          break
        else:
          if not (declareType in particularTypeList):
            if not regExp:
              regExp += r'\b' + declareType + r'\b'
            else:
              regExp += r'|\b' + declareType + r'\b'
            particularTypeList.append(declareType)
          if declareType.find('::') > -1:
            declareTypeTemp = declareType[declareType.find('::'):].replace('::','').strip()
            if not (declareTypeTemp in particularTypeList):
              if not regExp:
                regExp += r'\b' + declareTypeTemp + r'\b'
              else:
                regExp += r'|\b' + declareTypeTemp + r'\b'
              particularTypeList.append(declareTypeTemp)
        #跳到特殊类型定义的下一行去
        i = skipEndLno + 1
        continue
    # check 是否含有基本类型的关键字
    baseIndex = -1
    particularIndex = -1
    checkTypeword = ''
    m = strcmp.Search(r'(\bvoid\b|\bbool\b|\bchar\b|\bwchar_t\b|\bshort\b|\bint\b|\blong\b|\bfloat\b|\bdouble\b)\s*\w*\s*', lines[i].replace('*',' '))
    if m:
      checkTypeword = m.group(1)
      baseIndex = lines[i].replace('*',' ').find(checkTypeword)
      if len(particularTypeList) > 0:
        # check 是否含有特殊类型的关键字
        m = strcmp.Search(r'(' + regExp + r')\s*\w*\s*', lines[i].replace('*',' '))
        #同时找到基本类型和特殊类型关键字时,哪个在前面,以哪个为基准check函数
        if m:
          particularIndex = lines[i].replace('*',' ').find(m.group(1))
          if particularIndex < baseIndex and particularIndex > -1:
            checkTypeword = m.group(1)
    #没有找到基本类型
    else:
      if len(particularTypeList) == 0:
        i += 1
        continue
      # check 是否含有特殊类型
      m = strcmp.Search(r'(' + regExp + r')\s*\w*\s*', lines[i].replace('*',' '))
      if m:
        checkTypeword = m.group(1)
        particularIndex = lines[i].replace('*',' ').find(checkTypeword)
    if baseIndex > -1 or particularIndex > -1:
      #判断是否是函数声明定义,左右圆括号所在的行号,是否发生错误
      isFunction,checkStartLineNo,checkEndLineNo,hasError = isFunctionDeclare(checkTypeword, lines, i)
      if hasError:
        break
      if isFunction:
        #func()左右圆括号所在的行号相同,说明该函数()中间没有换行
        if checkStartLineNo == checkEndLineNo:
          i = checkEndLineNo + 1
          continue
        #check换行
        checkNewLine(filename, lines, checkStartLineNo, checkEndLineNo, ruleCheckKey, Error)
        i = checkEndLineNo + 1
        continue
    i += 1
    
def CheckCSC030005(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error, cpplines, fileErrorCount):
  #列表clean_lines.elided的内容为['comment',codeLine1,codeLine2,...codeLineN,'comment']
  #codeLineN在clean_lines.elided的index为clean_lines.NumLines()-1
  lines = clean_lines.elided
  errorMessage = 'Code Style Rule: There should be a blank line after the definition of a struct/union/enum/class.'
  i = 0
  endLineNo = clean_lines.NumLines()
  while i < clean_lines.NumLines():
    #空白行--skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    #template<...> -- skip
    if strcmp.Search(r'^\s*template\s*<', lines[i]):
      i = getTemplateEndLno(lines, i)
      if i == -1:
        break
      else:
        i += 1
      continue
    #check class
    if strcmp.Search(r'\bclass\b', lines[i]):
      #判断该段代码是否以class为返回值的函数
      if isFunctionDeclare('class', lines, i):
        i += 1
        continue
      #判断是否是类定义
      isClassDeclare,startLineNo,endLineNo = common.isClassDeclareCheck(lines, i)
      if isClassDeclare:
        #如果class定义的最后一行同时是文件的最后一行(请参看lines = clean_lines.elided的注释)时,退出循环,不check了
        if endLineNo >= clean_lines.NumLines() - 2:
          break
        #  下一行只有} or };,skip
        if not common.IsBlankLine(lines[endLineNo + 1]) and lines[endLineNo + 1].strip().replace(' ','') in ['}', '};']:
          i = startLineNo + 1
          continue
        #如果class定义的最后一行的下一行不是空白行 ,报错
        if not common.IsBlankLine(rawlines[endLineNo + 1]):
          Error(filename, lines, endLineNo, ruleCheckKey, 3, errorMessage)
        i = startLineNo + 1
        continue
    #check struct,union,enum
    m = strcmp.Search(r'(\bstruct\b|\bunion\b|\benum\b)', lines[i])
    if m:
      #判断该段代码是否以struct/union/enum为返回值的函数
      if isFunctionDeclare(m.group(1), lines, i):
        i += 1
        continue
      #判断是否是结构体/联合/枚举定义
      isStructUnionEnumDeclare,endLineNo,canFindEndLine = checkStructEnumUnionDeclare(m.group(1), lines, i)
      if isStructUnionEnumDeclare:
        #如果代码不规范而导致无法找到结构体/联合/枚举定义的最后一行,退出循环
        if not canFindEndLine:
          break
        #如果结构体/联合/枚举定义的最后一行同时是文件的最后一行(请参看lines = clean_lines.elided的注释)时,退出循环,不check了
        if endLineNo >= clean_lines.NumLines() - 2:
          break
        #  下一行只有} or };,skip
        if not common.IsBlankLine(lines[endLineNo + 1]) and lines[endLineNo + 1].strip().replace(' ','') in ['}', '};']:
          i = endLineNo + 1
          continue
        #如果结构体/联合/枚举定义的最后一行的下一行不是空白行 且 下一行不是只有},报错
        if not common.IsBlankLine(rawlines[endLineNo + 1]) and rawlines[endLineNo + 1].strip().replace(' ','') not in ['}', '};']:
          Error(filename, lines, endLineNo, ruleCheckKey, 3, errorMessage)
        i = endLineNo + 1
        continue
    i += 1
  
      
Exemple #18
0
def CheckCSC020010(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error):
  '''函数功能:一行中最多有一条语句。
                                     特殊:for循环除外
  Args:
    filename:文件名
    file_extension:文件扩展名
    clean_lines:Holds 3 copies of all lines with different preprocessing applied to them
                 1) elided member contains lines without strings and comments,
                 2) lines member contains lines without comments, and
                 3) raw_lines member contains all the lines without processing.(行首以/*开头的多行注释被替换成空白)
    rawlines:all the lines without processing
    nesting_state: Holds states related to parsing braces.(cpplint中的对象,暂时未使用)
    startLineNo:for,while,if,switch所在的行
    ruleCheckKey:ruleid
    Error: error output method
  '''
  errorMessage = 'Code Style Rule: There should be only one statement per line.'
  lines = clean_lines.elided
  i = 0
  closeParenthesisLineNo = -1
  closeParenthesisIndex = -1
  while i < clean_lines.NumLines():
    #空白行--skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    findIndex = 0
    preCloseParenthesisIndex = -1
    preCloseParenthesisLineNo = -1
    if closeParenthesisLineNo == i:
      preCloseParenthesisLineNo = closeParenthesisLineNo
      preCloseParenthesisIndex = closeParenthesisIndex
      findIndex = closeParenthesisIndex
    #查找for
    mFor = strcmp.Search(r'\bfor\b', lines[i][findIndex:])
    if mFor:
      #当前行有之前for的)时
      # for (af;adsf;
      # ) { for (
      if preCloseParenthesisLineNo == i:
        Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
        hasSystemError,hasLastFor,closeParenthesisLineNo,closeParenthesisIndex=getEndInfoOfLastForConditionInALine(lines, i)
        if hasSystemError:
          return
        if closeParenthesisLineNo == -1:
          return
        if closeParenthesisLineNo == i:
          i += 1
          continue
        if closeParenthesisLineNo > i:
          i = closeParenthesisLineNo
          continue
      # 当前行没有之前for的)时
      # AAA(); for(i=0;i<1;i++) { 
      if strcmp.Search(r';\s*[^\s\}\)\\/]', lines[i][0:mFor.end()]):
        Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
        #查找本行最后最后一个for的)所在的位置
        hasSystemError,hasLastFor,closeParenthesisLineNo,closeParenthesisIndex=getEndInfoOfLastForConditionInALine(lines, i)
        if hasSystemError:
          return
        if closeParenthesisLineNo == -1:
          return
        if closeParenthesisLineNo == i:
          i += 1
          continue
        if closeParenthesisLineNo > i:
          i = closeParenthesisLineNo
          continue
      # 当前行没有之前for的)时
      #  for(i=0;i<1;i++) { ......
      closeParenthesisLineNo, closeParenthesisIndex = getEndInfoOfCondition(lines, i, findIndex + mFor.start())
      #找不到for的()中)所在的行号
      if closeParenthesisLineNo == -1:
        return
      # for的)在不在本行在后面时,不再check本行了,check)在的行
      #for(i=0;i<1;
      #i++) { ......
      if closeParenthesisLineNo > i:
        i = closeParenthesisLineNo
        continue
      #for的)在本行时
      elif closeParenthesisLineNo == i:
        secondFor = strcmp.Search(r'\bfor\b', lines[i][closeParenthesisIndex:])
        # 本行有两个以上的for时
        # for(i=0;i<1;){ for(i=0
        if secondFor:
          Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
          #查找本行最后最后一个for的)所在的位置
          hasSystemError,hasLastFor,closeParenthesisLineNo,closeParenthesisIndex=getEndInfoOfLastForConditionInALine(lines, i)
          if hasSystemError:
            return
          if closeParenthesisLineNo == -1:
            return
          if closeParenthesisLineNo == i:
            i += 1
            continue
          if closeParenthesisLineNo > i:
            i = closeParenthesisLineNo
            continue
        # 本行有1个for时
        else:
          #查看该行中是否出现这种情况: ;后面有语句
          #1.for () {aaa();bbb()
          #2.for () {aaa();
          mSemicolon = strcmp.Search(r';\s*[^\s\}\)\\/]|[^\s\{\}]\s*;', lines[i][closeParenthesisIndex:])
          if mSemicolon:
            if mSemicolon.start():
              Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
          i += 1
          continue
    #在for的condition表达式之外时
    else:
      # 当前行时下列情形的第二行时
      #   for(int i=0;i<10
      #   i++){ function();
      #   }
      if preCloseParenthesisLineNo == i:
        m = strcmp.Search(r'[^\s\{\}]\s*;', lines[i][preCloseParenthesisIndex + 1:])
        if m:
          #避免下面情形误判.因为既存处理,行末/**/换行时可能无法lines中可能残留注释  
          #   for(int i=0;i<10
          #   i++){  /*function();
          #   }
          if lines[i][preCloseParenthesisIndex + 1:m.start()].find('/*') == -1:
            Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
        i += 1
        continue
      #当前行中没有for的表达式
      #查看该行中是否出现这种情况: ;后面有语句
      mSemicolon = strcmp.Search(r';\s*[^\s\}\)\\/]', lines[i])
      if mSemicolon:
        #当前行没有之前for的)时
        #funtion(); AAA();
        if preCloseParenthesisLineNo < i:
          Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
        #当前行有之前for的)时
        # for (asdf;asdf;
        #     ){ funtion();funtion2();
        if preCloseParenthesisLineNo == i and mSemicolon.start() > preCloseParenthesisIndex:
          Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
        #当前行有之前for的)时
        # for (asdf;
        #     asdf;){ funtion();funtion2();
        elif preCloseParenthesisLineNo == i and mSemicolon.start() < preCloseParenthesisIndex:
          if strcmp.Search(r';\s*[^\s\}\)\\/]', lines[i][preCloseParenthesisIndex:]):
            Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
        
      i += 1
      continue
Exemple #19
0
def getStatementStartEnd(lines, startLineNo, typeword):
  #函数功能:查找if,while的左右括号所在的行号,以及if,while行的缩进情况
  #if,while所在行,凡是含有if,while字符串的单词,都相应的字符串都被替换
  substring = ''
  if typeword == 'if':
    substring = '12'
  elif typeword == 'while':
    substring = '12345'
  startLine = strcmp.Sub(r'\w' + typeword, '0' + substring, lines[startLineNo])
  startLine = strcmp.Sub(r'' + typeword + r'\w', substring + '0', startLine)
  #int a; /* if (*/ or int a; /* if( or  int a; /* adfa \n if */这三种情况skip,当成if的左右括号在一行,不check的情况
  typewordIndex = startLine.find(typeword)
  multiCommentStartIndex = startLine.find('/*')
  multiCommentEndIndex = startLine.find('*/')
  if multiCommentStartIndex > -1 and multiCommentEndIndex > -1 and \
  typewordIndex > multiCommentStartIndex and typewordIndex < multiCommentEndIndex:
    return 0,startLineNo,startLineNo
  elif multiCommentStartIndex == -1 and multiCommentEndIndex > -1 and typewordIndex < multiCommentEndIndex:
    return 0,startLineNo,startLineNo
  elif multiCommentEndIndex == -1 and multiCommentStartIndex > -1 and typewordIndex > multiCommentStartIndex:
    return 0,startLineNo,startLineNo
  #查找if,while所在行的缩进的空格数量,tab键作为4个空格
  indentation = 0
  m = strcmp.Search(r'^(\s*)\S', startLine)
  if m:
    indentation = len(m.group(1).replace('\t', '    '))
  #查找if(),while()中左右括号所在的行
  lengthOfLines = len(lines)
  openParenthesisQty = 0
  closeParenthesisQty = 0
  checkStartLineNo = -1
  checkEndLineNo = -1
  skipEndLno = -1
  line = ''
  for i in xrange(startLineNo, lengthOfLines):
    checkEndLineNo = i
    line = lines[i]
    if i == startLineNo:
      line = lines[i][startLine.find(typeword):]
    #空白行--skip
    if common.IsBlankLine(line):
      continue
    if i <= skipEndLno:
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', line):
      skipEndLno = common.getDefineMacroEndLineNo(lines, i)
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', lines[i]):
      skipEndLno = common.getDefineMacroEndLineNo(lines, i)
      continue
    openParenthesisQty = openParenthesisQty + line.count('(')
    closeParenthesisQty = closeParenthesisQty + line.count(')')
    if openParenthesisQty > 0 and checkStartLineNo == -1:
      checkStartLineNo = i
    if openParenthesisQty == closeParenthesisQty and openParenthesisQty > 0:
      break
  if openParenthesisQty != openParenthesisQty:
    return indentation, checkStartLineNo, -1
  return indentation, checkStartLineNo, checkEndLineNo
def CheckCSC020009(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error, cpplines, fileErrorCount):
  '''函数体定义需要遵循下面的规范:
     {和}分别单独占一行。
     [例外]如果是定义在class定义中的空实现,{和}分别单独在一行,或者需将{和}写在一起,并放置在函数后面。
     {和}分别单独占一行也是可以的。[必须]
     cpp文件中的空实现,{和}分别单独占一行。
  Args:
    filename:文件名
    file_extension:文件扩展名
    clean_lines:Holds 3 copies of all lines with different preprocessing applied to them
                 1) elided member contains lines without strings and comments,
                 2) lines member contains lines without comments, and
                 3) raw_lines member contains all the lines without processing.(行首以/*开头的多行注释被替换成空白)
    rawlines:all the lines without processing
    nesting_state: Holds states related to parsing braces.(cpplint中的对象,暂时未使用)
    ruleCheckKey:ruleid
    Error: error output method
  '''
  errorMessageHeader = 'Code Style Rule:'
  #{和}分别单独占一行。
  errorMessage = ' The left curly brace "{" and right curly brace "}" in a function definition should be both in a separate line.'
  # 右大括号右边不能带分号
  semicolonErrorMessage = ' There should be no semicolon after the right curly brace "}".'
  # function() {   } ---error
  hasSpaceInBraceErrorMessage = ' Please leave no space between the left and right curly braces. For example: void func() {}.'
  # class定义(struct定义)中,空实现,{和}写在一起,{和)放置在函数后面 or {和}分别单独占一行。
  exceptionClassDefinition = ' For an empty function in the class(or struct) definition block, it can be written in the following two formats: 1.Put the "{" and "}" in the same line with the function name 2.Put the "{" and "}" both in a separate line.'
  lines = clean_lines.elided
  i = 0
  currentLineHasError = False
  nextLineHasError = False
  openCurlyBraceIndex = -1
  closeCurlyBraceLineNo = -1
  closeCurlyBraceIndex = -1
  classStartLineNo = -1
  classStartIndex = -1
  classEndLineNo = -1
  classEndIndex = -1
  templateCloseAngleBraceLineNo = -1
  templateCloseAngleBraceIndex = -1
  while i < clean_lines.NumLines():
    #null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # template<class t, class t1>---- skkip
    m = strcmp.Search(r'\btemplate\b', lines[i])
    if m:
      templateCloseAngleBraceLineNo,templateCloseAngleBraceIndex = getTemplateEndLno(lines, i, m.start())
      #找不到template >所在的位置,则说明代码有问题,不再check
      if templateCloseAngleBraceLineNo == -1 or templateCloseAngleBraceIndex == -1:
        return
      i = templateCloseAngleBraceLineNo
    # 当前行是class的}所在的行,或者}后面的行时,重新找class定义
    if classEndLineNo <= i:
      # 当前行是template 的>所在的行,从class定义和templae的>后开始查找 class定义
      if templateCloseAngleBraceLineNo == i:
        classFindBeginIndex = templateCloseAngleBraceIndex
        # 当前行是class的};所在的行
        if classEndLineNo == i:
          if templateCloseAngleBraceIndex < classEndIndex:
            classFindBeginIndex = classEndIndex
      # 当前行不是template 的>所在的行 and 当前行是class的};所在的行,从class定义后开始查找 class定义
      elif classEndLineNo == i:
        classFindBeginIndex = classEndIndex
      # 当前行不是template 的>所在的行 and 当前行不是class的}所在的行
      else:
        classFindBeginIndex = 0
      # check是不是class定义
      m = strcmp.Search(r'\b(class|struct)\b', lines[i][classFindBeginIndex:])
      if m:
        isClassDefinition,classEndLineNo,classEndIndex = findClassStructDefinitionEndInfo(lines, i, m.start(), m.group(1))
        if isClassDefinition and (classEndLineNo == -1 or classEndIndex == -1):
          return
        # 是class定义
        if isClassDefinition:
          classStartLineNo = i
          classStartIndex = classFindBeginIndex + m.start()

    # 假如几个函数定义都写到一行了而且都不符合要求,这一行只报一个错误,不会重复报多个错误
    currentLineHasError = False
    if i == closeCurlyBraceLineNo and nextLineHasError:
      currentLineHasError = True
    nextLineHasError = False

    currentLine = lines[i]
    lengthCurrentLine = len(lines[i])
    # 查找{
    openCurlyBraceIndex = currentLine.find('{')
    if openCurlyBraceIndex == -1:
      i += 1
      continue
    # 如果{左侧满足operator += (...) 或者aaa(...)这种格式,说明这个是函数定义
    # operator +=(int a, int b) {}
    # AA::BB() {}
    # BB() {}
    while openCurlyBraceIndex > -1 and openCurlyBraceIndex < lengthCurrentLine:
      # 判断{是否是函数定义的第一个{
      isFunction, tempCloseParenthesislineNo, tempcloseParenthesisIndex, hasInitializationList = isFunctionDefinition(lines, i, openCurlyBraceIndex)
      # 是函数定义
      if isFunction:
        # 查找{对应的}的行号和其所在行的位置
        closeCurlyBraceLineNo, closeCurlyBraceIndex = getFunctionCloseCurlyBraceInfo(lines, i, openCurlyBraceIndex)
        # 查不到{对应的}的行号和其所在行的位置,说明文件不正常,不再check了
        if closeCurlyBraceLineNo == -1:
          return
        # check 函数是否在class 的{}内
        isInClassDefinition = isInBlock(closeCurlyBraceLineNo, closeCurlyBraceIndex, classStartLineNo, classStartIndex, classEndLineNo, classEndIndex)
        # }后面是逗号-- 不是函数定义
        if whetherCommarIsCloseAfterCloseCurlyBrace(lines, closeCurlyBraceLineNo, closeCurlyBraceIndex):
          # {}不在同一行
          if i < closeCurlyBraceLineNo:
            i = closeCurlyBraceLineNo
            break
          # {}在同一行
          # check 本行下一个{
          tempOpenCurlyBraceIndex = currentLine[closeCurlyBraceIndex + 1:].find('{')
          if tempOpenCurlyBraceIndex == -1:
            i += 1
            break
          openCurlyBraceIndex = closeCurlyBraceIndex + 1 + tempOpenCurlyBraceIndex
          continue
        # {}在同一行
        if closeCurlyBraceLineNo == i:
          if (not currentLineHasError) and strcmp.Search(r'^\s*;', lines[closeCurlyBraceLineNo][closeCurlyBraceIndex + 1:]):
            Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + semicolonErrorMessage)
          # {}之间没有内容 and 无初始化列表时
          if common.IsBlankLine(lines[i][openCurlyBraceIndex + 1:closeCurlyBraceIndex]) and (not hasInitializationList):
            # ) 与 {不在同一行
            if tempCloseParenthesislineNo != i and (not currentLineHasError):
              # class定义中
              if isInClassDefinition:
                # {和}写在一起,{和)放置在函数后面 or {和}分别单独占一行。
                Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + exceptionClassDefinition)
              else:
                # {和}分别单独占一行
                Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + errorMessage)
              currentLineHasError = True
            elif tempCloseParenthesislineNo == i and (not currentLineHasError):
              # class定义中时,
              if isInClassDefinition:
                # function() {} other code(for example:  get();)---error
                if strcmp.Search(r'^\s*[^\s\;]', lines[closeCurlyBraceLineNo][closeCurlyBraceIndex + 1:]):
                  Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + errorMessage)
                  currentLineHasError = True
                # function() {       } ---error
                if openCurlyBraceIndex + 1 < closeCurlyBraceIndex:
                  Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + hasSpaceInBraceErrorMessage)
                  currentLineHasError = True
              # class定义外
              else:
                Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + errorMessage)
                currentLineHasError = True
          # {}之间有内容  or have初始化列表时
          # 要求:{和}分别单独占一行
          else:
            if not currentLineHasError:
              currentLineHasError = True
              Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + errorMessage)
          tempOpenCurlyBraceIndex = currentLine[openCurlyBraceIndex + 1:].find('{')
          if tempOpenCurlyBraceIndex == -1:
            i += 1
            break
          openCurlyBraceIndex = openCurlyBraceIndex + 1 + tempOpenCurlyBraceIndex
        # {}不在同一行
        else:
          hasCode = whetherHasSourceBetweenTwoLine(lines, i, openCurlyBraceIndex, closeCurlyBraceLineNo, closeCurlyBraceIndex)
          # check {   -------------------->
          if not currentLineHasError:
            # 空实现(无代码 and 没有初始化列表)
            if (not hasCode) and (not hasInitializationList):
              # class定义中时
              if isInClassDefinition:
                # )与{在同一行
                if tempCloseParenthesislineNo == i:
                  # {和}写在一起,{和)放置在函数后面 or {和}分别单独占一行。
                  Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + exceptionClassDefinition)
                  currentLineHasError = True
              # class定义外时
              else:
                # )与{在同一行
                if tempCloseParenthesislineNo == i:
                  #{和}分别单独占一行。
                  Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + errorMessage)
                  currentLineHasError = True
            # 非空实现
            else:
              # {独占一行
              if common.IsBlankLine(lines[i][:openCurlyBraceIndex]) and common.IsBlankLine(lines[i][openCurlyBraceIndex + 1:]):
                pass
              # {非独占一行
              else:
                currentLineHasError = True
                Error(filename, lines, i, ruleCheckKey, 3, errorMessageHeader + errorMessage)
          # check {   <--------------------
          # check }   -------------------->
          # 非空实现(有代码  or 有初始化列表)
          if hasCode or hasInitializationList:
            # }独占一行
            # chcek }前是否有代码
            hasCodeBeforeCloseCurlyBrace = False
            if not common.IsBlankLine(lines[closeCurlyBraceLineNo][:closeCurlyBraceIndex]):
              hasCodeBeforeCloseCurlyBrace = True
            # chcek }后是否有分号
            hasSemicolonAfterCloseCurlyBrace = False
            mForSemicolon = strcmp.Search(r'^\s*;', lines[closeCurlyBraceLineNo][closeCurlyBraceIndex + 1:])
            if mForSemicolon:
              hasSemicolonAfterCloseCurlyBrace = True
            # chcek }后是否有代码
            # }后有分号时
            if hasSemicolonAfterCloseCurlyBrace:
              # chcek 分号后是否有代码
              if common.IsBlankLine(lines[closeCurlyBraceLineNo][closeCurlyBraceIndex + 1 + mForSemicolon.end():]):
                hasCodeAfterCloseCurlyBrace = False
              else:
                hasCodeAfterCloseCurlyBrace = True
            # }后没有分号时
            else:
              # chcek }后是否有代码
              if common.IsBlankLine(lines[closeCurlyBraceLineNo][closeCurlyBraceIndex + 1:]):
                hasCodeAfterCloseCurlyBrace = False
              else:
                hasCodeAfterCloseCurlyBrace = True
            # }后有分号 and }所在的行有代码
            if  (hasCodeBeforeCloseCurlyBrace or hasCodeAfterCloseCurlyBrace) and hasSemicolonAfterCloseCurlyBrace:
              nextLineHasError = True
              currentLineHasError = True
              Error(filename, lines, closeCurlyBraceLineNo, ruleCheckKey, 3, errorMessageHeader + errorMessage)
              Error(filename, lines, closeCurlyBraceLineNo, ruleCheckKey, 3, errorMessageHeader + semicolonErrorMessage)
            # }后有分号
            elif hasSemicolonAfterCloseCurlyBrace:
                nextLineHasError = True
                currentLineHasError = True
                Error(filename, lines, closeCurlyBraceLineNo, ruleCheckKey, 3, errorMessageHeader + semicolonErrorMessage)
            # }所在的行有代码
            elif hasCodeBeforeCloseCurlyBrace or hasCodeAfterCloseCurlyBrace:
              nextLineHasError = True
              currentLineHasError = True
              Error(filename, lines, closeCurlyBraceLineNo, ruleCheckKey, 3, errorMessageHeader + errorMessage)
          # 空实现
          else:
            # check }后是否有分号
            if strcmp.Search(r'^\s*;', lines[closeCurlyBraceLineNo][closeCurlyBraceIndex + 1:]):
              nextLineHasError = True
              currentLineHasError = True
              Error(filename, lines, closeCurlyBraceLineNo, ruleCheckKey, 3, errorMessageHeader + semicolonErrorMessage)
            # )与{不在同一行 and }后有代码
            elif strcmp.Search(r'^\s*\S', lines[closeCurlyBraceLineNo][closeCurlyBraceIndex + 1:]):
              if not isInClassDefinition:
                nextLineHasError = True
                currentLineHasError = True
                Error(filename, lines, closeCurlyBraceLineNo, ruleCheckKey, 3, errorMessageHeader + errorMessage)
              elif tempCloseParenthesislineNo != i:
                nextLineHasError = True
                currentLineHasError = True
                Error(filename, lines, closeCurlyBraceLineNo, ruleCheckKey, 3, errorMessageHeader + errorMessage)
          # check }   <--------------------
          i = closeCurlyBraceLineNo
          break
      # 不是函数定义
      else:
        tempOpenCurlyBraceIndex = currentLine[openCurlyBraceIndex + 1:].find('{')
        if tempOpenCurlyBraceIndex == -1:
          i += 1
          break
        openCurlyBraceIndex = openCurlyBraceIndex + 1 + tempOpenCurlyBraceIndex     
def findClassStructDefinitionEndInfo(lines, startLineNo, startIndex, keyWord):
  '''从startLno向下查找class的}所在的行号
  Args:
    lines:a copy of all lines without strings and comments
    startLno:leyword[class]所在的行号
    startIndex: leyword[class] index
    keyWord: 关键字
  Returns:
           是否是class/struct定义,class的};(or struct 的})所在的行号,index
    (systemError: return True, -1, -1)
  '''
  openCurlyBraceQty = 0
  closeCurlyBraceQty = 0
  lengthOfLines = len(lines)
  i = startLineNo
  semicolonIndex = -1
  otherCharIndex = -1
  closeCurlyBraceIndex = -1
  colonIndex = -1
  commaIndex = -1
  while i < lengthOfLines:
    endLine = i
    #null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    if i == startLineNo:
      line = lines[i][startIndex:]
    else:
      line = lines[i]
    if openCurlyBraceQty == closeCurlyBraceQty and openCurlyBraceQty > 0:
      # struct
      if keyWord == 'struct':
        return True, i, closeCurlyBraceIndex
      # class
      # class A {};--是函数定义
      if line.strip().startswith(';'):
        endIndex = line.find(';')
        if i == startLineNo:
          endIndex = endIndex + startIndex
        return True, i, endIndex
      # class {} AA-- }后没有;,说明文件有问题
      else:
        return True, -1, -1
    # 逐个字符对比,累计{,}的数量
    for j in xrange(0, len(line)):
      if line[j] == '{':
        openCurlyBraceQty += 1
      elif line[j] == '}':
        closeCurlyBraceIndex = j
        closeCurlyBraceQty += 1
      elif line[j] == ':':
        colonIndex = j
      elif line[j] == ',':
        commaIndex = j
      elif line[j] == ';':
        semicolonIndex = j
      elif line[j] in ['(',')', '=']:
        otherCharIndex = j
      #{,}个数相同
      if openCurlyBraceQty == closeCurlyBraceQty:
        # class A; --不是class定义
        # struct A a; --不是struct定义
        if openCurlyBraceQty == 0 and semicolonIndex != -1:
          return False, -1, -1
        #class a: public b, public c {-- 避免这种情况当成非类定义
        # function(class A a,struct A c);--不是class定义
        elif openCurlyBraceQty == 0 and colonIndex == -1 and commaIndex != -1:
          return False, -1, -1
        # stuct a a ={};--不是struct定义
        # function(struct A b,struct A c);--不是struct定义
        elif openCurlyBraceQty == 0 and otherCharIndex != -1:
          return False, -1, -1
        elif openCurlyBraceQty > 0:
          # struct
          if keyWord == 'struct':
            return True, i, closeCurlyBraceIndex
          # class
          # class A {};--是函数定义
          if line[j + 1 :].strip().startswith(';'):
            semicolonIndex = line[j:].find(';')
            if i == startLineNo:
              endIndex = startIndex + j + semicolonIndex
            else:
              endIndex = j + semicolonIndex
            return True, i, endIndex
          # class A {} \\ or class A {} -- check next line
          elif line[j + 1 :].strip() == '\\' or (not line[j + 1 :].strip()):
            break
          # class {} AA-- }后没有;,说明文件有问题
          else:
            return True, -1, -1
          break
    i += 1
  return False, -1, -1
def checkClassBlock(filename, lines, startLineNo, endLineNo, ruleCheckKey, Error, cpplines, fileErrorCount):
  
  errMessage = "Code Style Rule: There should be a blank line after every public/protected/private area."
  
  # public/protected/private区域表示
  bDeclareFlg = False
  bBlankFlg = False
  
  i = startLineNo + 1
  while i <= endLineNo:
    line = lines[i]
    
    if common.IsBlankLine(lines[i]):
      i += 1
      
      #有区间标志,记录空行
      if bDeclareFlg:
        bBlankFlg = True
        
      continue
  
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', line):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
  
    #预定义--skip
    if strcmp.Search(r'^\s*#', line):
      i += 1
      continue
  
    # template类型例子,
    # template <class T, ASN1::natural explicit_tag,  
    #     ASN1::tag_class_enum explicit_tag_class = ASN1::class_context_specific>
    if strcmp.Search(r'^\s*template\s*<', lines[i]):
      iRet = getTemplateEndLno(lines, i)
      if iRet != -1:
        i = iRet + 1
        continue
    
    m = strcmp.Search(r'^\s*(\bpublic\b|\bprivate\b|\bprotected\b)\s*:', line)
    if m:
        
      # 找到后修改标志
      if not bDeclareFlg:
        bDeclareFlg = True
      else :
        if not bBlankFlg:
          Error(filename, lines, i, ruleCheckKey, 3, errMessage)
          
          # 有空行,变量修改为false,继续查找
        else :
          bBlankFlg = False
          
    # 内嵌类    
    # eg. class A {
    # 查找到class类名后,检查类作用域内是否有public / protected / private关键字
    # 排除namespace中的class声明 class NCWifiEvent; template <class T>
    if strcmp.Search(r'^\s*class\s+\w+', lines[i]) and not strcmp.Search(r'^\s*class\s+\w+\s*;', lines[i]) and not strcmp.Search(r'^\s*class\s+\w+\s*>', lines[i]) and lines[i].count('(') == 0:
      #判断是否是类定义
      isClassDeclare,nestStartLineNo,nestEndLineNo = common.isClassDeclareCheck(lines, i)
      #当class的类定义中,所有的代码都是在同一行时,没必要check
      if nestStartLineNo == nestEndLineNo:
        i = nestEndLineNo + 1
        continue
      # check 内部类
      if isClassDeclare:
        checkClassBlock(filename, lines, nestStartLineNo, nestEndLineNo, ruleCheckKey, Error, cpplines, fileErrorCount)
      i = nestEndLineNo + 1
      continue
      
    i += 1
def CheckCSC030006(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error, cpplines, fileErrorCount):
    
  errMessage = "Code Style Rule: There should be a blank line after every function definition."
    
  lines = clean_lines.elided

#函数定义的例子
#void A (){
#Test1& operator = (const Test1& t1){ // 赋值运算符
#void VRS_210010::CheckGlobalInitInConstructor(){
#void VRS_210010::foo(string s, int i):name(s), id(i){} ;
#int bb<t,t1>::aa(){
#AA::A VRS_210010::CheckGlobalInitInConstructor(){

#1 operator关键字
#2 ::找
#3 普通

  i = 0
  while i < clean_lines.NumLines():
    line = lines[i]
      
    #null line skip
    if common.IsBlankLine(line):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', line):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', line):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
  
    # 查找{
    openCurlyBraceIndex = line.find('{')
    if openCurlyBraceIndex == -1:
      i += 1
      continue
  
    # 如果{左侧满足operator += (...) 或者aaa(...)这种格式,说明这个是函数定义
    # operator +=(int a, int b) {}
    # AA::BB() {}
    # BB() {}
    
    # 判断{是否是函数定义的第一个{
    isFunction, tempCloseParenthesislineNo, tempcloseParenthesisIndex = isFunctionDefinition(lines, i, openCurlyBraceIndex)
    # 是函数定义
    if isFunction:
      # 查找{对应的}的行号和其所在行的位置
      closeCurlyBraceLineNo, closeCurlyBraceIndex = getFunctionCloseCurlyBraceInfo(lines, i, openCurlyBraceIndex)
      # 查不到{对应的}的行号和其所在行的位置,说明文件不正常,不再check了
      if closeCurlyBraceLineNo == -1:
        return
    
      # {}在同一行
      if closeCurlyBraceLineNo == i:
        i += 1
        continue
      else :
        
        # 文件结束
        if -1 == lines[closeCurlyBraceLineNo + 1].find('EOF') and \
          closeCurlyBraceLineNo + 1 < clean_lines.NumLines() - 1 and \
          lines[closeCurlyBraceLineNo + 1].strip() != '};' and \
          lines[closeCurlyBraceLineNo + 1].strip() != '}'  :
            
          # 函数定义后必须有空行
          if not common.IsBlankLine(lines[closeCurlyBraceLineNo + 1]) :
            Error(filename, lines, closeCurlyBraceLineNo, ruleCheckKey, 3, errMessage)
            
          i = closeCurlyBraceLineNo + 2
          continue
    
    i += 1
def checkClassBlock(filename, lines, startLineNo, startLine, endLineNo, ruleCheckKey, Error, cpplines, fileErrorCount):
  #check 类定义
  currentAccess = 'default'
  acessList = []
  i = startLineNo
  errorMessage = 'Code Style Rule: In Class definitions, please put the access specifiers in the following order: first "public", second "protected", and finally "private".'
  skipEndLno = -1
  line = ''
  openCurlyBraceQty = 0
  closeCurlyBraceQty = 0
  tempOpenCurlyBraceQty = 0
  tempCloseCurlyBraceQty = 0
  while i <= endLineNo:
    line = lines[i]
    #空白行--skip
    if common.IsBlankLine(line):
      i += 1
      continue
    #宏定义--skip
    if strcmp.Search(r'^\s*#\s*define\s+', line):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    #预定义--skip
    if strcmp.Search(r'^\s*#', line):
      i += 1
      continue
    #template<...> -- skip
    if strcmp.Search(r'^\s*template\s*<', lines[i]):
      i = getTemplateEndLno(lines, i)
      if i == -1:
        break
      else:
        i += 1
      continue
    tempOpenCurlyBraceQty = openCurlyBraceQty
    tempCloseCurlyBraceQty = closeCurlyBraceQty
    openCurlyBraceQty = openCurlyBraceQty + line.count('{')
    closeCurlyBraceQty = closeCurlyBraceQty + line.count('}')
    if i == startLineNo:
      #startLineNo是class第一个左大括号所在的行
      line = startLine[startLine.find('{') + 1:]
    m = strcmp.Search(r'^\s*(\bpublic\b|\bprivate\b|\bprotected\b)\s*:', line)
    if m:
      line = line[line.find(':') + 1:]
      currentAccess = m.group(1)
      # check是否满足public,protected,private这样的顺序
      if currentAccess == 'public':
        if 'protected' in acessList or 'private' in acessList:
          Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
          break
      elif currentAccess == 'protected':
        if 'private' in acessList:
          Error(filename, lines, i, ruleCheckKey, 3, errorMessage)
          break
      acessList.append(currentAccess)
    # check当前行是否是内部类
    if strcmp.Search(r'^\s*\bclass\b', line.replace('{', '')):
      if isFunctionDeclare('class', lines, i):
        # class a function();
        # 当前行是返回值为class的函数--skip
        i += 1
        continue
      #判断是否是类定义
      isClassDeclare,nestStartLineNo,nestEndLineNo = common.isClassDeclareCheck(lines, i)
      #当class的类定义中,所有的代码都是在同一行时,没必要check
      if nestStartLineNo == nestEndLineNo:
        i = nestEndLineNo + 1
        continue
      # check 内部类
      if isClassDeclare:
        if i == nestStartLineNo:
          nestStartLine = line[line.find('class'):]
        else:
          nestStartLine = lines[nestStartLineNo]
        checkClassBlock(filename, lines, nestStartLineNo, nestStartLine, nestEndLineNo, ruleCheckKey, Error, cpplines, fileErrorCount)
      i = nestEndLineNo + 1
      continue
    i += 1
Exemple #25
0
def CheckCSC030017(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error):
  
  # 赋值判断
  #因为 * & 即是指针也是运算符,无法判断,所有不判断这两个
  arraySign1 = ["+","-","*","/","%","&", "|", "~", "^"]
  # 运算符 
  # eg. if (a && b), if (a || b)
  arraySign2 = ["&&", "||"]
  # 必须在等号后判断的,否则容易产生误判
  # error 数据有赋值为负数的情况,'-'删除
  arraySign3 = ["+","/","%", "|", "<<", ">>"]
  
  lines = clean_lines.elided
  errMessage = "Code Style Rule: There should a space both before and after a binary operator \"%s\". For example: A = B."
  i = 0
  while i < clean_lines.NumLines():
    findFlg = True
    index = 0
    signTag = ''
    
    line = lines[i].replace("->", ".")
        
    if common.IsBlankLine(line):
      i += 1
      continue
  
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
  
    if strcmp.Search(r'^\s*#', line):
      i += 1
      continue
    
    
    # 查找"operator",忽略操作符重载的函数名的判断
    if strcmp.Search(r'\boperator\b', line):
      i += 1
      continue
  
    # 查找"===",忽略
    if strcmp.Search(r'===', line):
      i += 1
      continue
  
    #只判断结束语句
    endPos = line.rfind(";")
    if endPos == -1:
      endPos = len(line)
    
    # 查找"="
    index2 = line.rfind("=", 0, endPos)
    if -1 != index2 and -1 == line.find('virtual ', 0, index2):
    
      arraySign1FLg = False
      # 判断前一位是否为运算符
      if line[index2 - 1:index2] in arraySign1:
        findFlg = checkSignLeftRightBlank(line, index2 - 2, index2 + 1)
        signTag = line[index2 - 1:index2] + '='
        arraySign1FLg = True
      
      if not arraySign1FLg:
        if line[index2 - 1:index2] == "<" or line[index2 - 1:index2] == ">":
          # "<<=",">>=" 情况
          if line[index2 - 2:index2 - 1] == "<" or line[index2 - 2:index2 - 1] == ">":
            findFlg = checkSignLeftRightBlank(line, index2 - 3, index2 + 1)
          else:
             # "<=",">=" 情况
            findFlg = checkSignLeftRightBlank(line, index2 - 2, index2 + 1)
          signTag = line[index2 - 2:index2] + '='
           # "!=" 情况
        elif line[index2 - 1:index2] == "!" :
          findFlg = checkSignLeftRightBlank(line, index2 - 2, index2 + 1)
          signTag = '!='
          # "==" 情况
        elif line[index2 - 1:index2] == "=" :
          findFlg = checkSignLeftRightBlank(line, index2 - 2, index2 + 1)
          signTag = '=='
        else:
          # "=" 情况
          findFlg = checkSignLeftRightBlank(line, index2 - 1, index2 + 1)
          signTag = '='
              
          for k in xrange(len(arraySign3)):
            index = line.find(arraySign3[k], index2, endPos)
            if -1 != index:
              # next = *s++ 误判
              indexPlusPlus = line.find('++')
              if indexPlusPlus == index:
                continue
            
              findFlg = checkSignLeftRightBlank(line, index - 1, index + len(arraySign3[k]))
              signTag = arraySign3[k]
              break
          
    # 赋值判断
    for j in xrange(len(arraySign2)):
      index = line.find(arraySign2[j], 0, endPos)
      if -1 != index:
        findFlg = checkSignLeftRightBlank(line, index - 1, index + len(arraySign2[j]))
        signTag = arraySign2[j]
    
    #如果是类似 (XXX)*(XXX) 的形式,也需要报错。因为这种情况说明写法有问题,导致无法判断是乘号还是指针
    if strcmp.Search(r'\(\w+\)\*\(\w+\)', line):
      signTag = '*'
      findFlg = False
    
    if not findFlg:
      Error(filename, lines, i, ruleCheckKey, 3, errMessage % signTag)
  
    i += 1
# end of CheckCSC030017
def CheckCSC030029(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error, cpplines, fileErrorCount):
  '''如果做大括号{和右大括号}出现在一行,并且之间没有内容,请写在一起,不要留空格。[必须]
  Args:
    filename:文件名
    file_extension:文件扩展名
    clean_lines:Holds 3 copies of all lines with different preprocessing applied to them
                 1) elided member contains lines without strings and comments,
                 2) lines member contains lines without comments, and
                 3) raw_lines member contains all the lines without processing.(行首以/*开头的多行注释被替换成空白)
    rawlines:all the lines without processing
    nesting_state: Holds states related to parsing braces.(cpplint中的对象,暂时未使用)
    startLineNo:for,while,if,switch所在的行
    ruleCheckKey:ruleid
    Error: error output method
  '''
  lines = clean_lines.elided
  errMessage = 'Code Style Rule: If a left curly brace "{" is closely followed by a right curly brace "}", there should be no space between them.'
  i = 0
  while i < clean_lines.NumLines():
    # null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i += 1
      continue
    # if no {, skip
    if lines[i].find('{') == -1:
      i += 1
      continue
    # 查看是否存在{}中全是空格的情况
    m = strcmp.Search(r'\{\s+\}', lines[i])
    # 不存在{}中全是空格的情况,进入下次循环
    if not m:
      i += 1
      continue
    # 存在{}中全是空格的情况,需要检查rawlines[i],避免if(...) { /*1111111*/  }被误判
    # 检查rawlines[i] --Start
    # 该行如果没有注释标识符/* 且 {...}中...全是空格,则报错
    if rawlines[i].find('/*') == -1:
      Error(filename, lines, i, ruleCheckKey, 3, errMessage)
      j = cpplines[i].find("{") + 1
      strTemp = "{"
      while j < len(cpplines[i]):
        if cpplines[i][j] == " ":
          strTemp += " "
          j += 1
        elif cpplines[i][j] == "}":
          fileErrorCount[0] += 1
          cpplines[i] = cpplines[i].replace(strTemp, "{")
          break
        else:
          break
      i += 1
      continue
    # 因为lines中已经去掉多行注释了,为了避免if(...) { /*1111111*/  }被误判,需要检查rawlines
    m = strcmp.Search(r'\{\s+\}', rawlines[i])
    # 不存在{}中全是空格的情况,进入下次循环
    if not m:
      i += 1
      continue
    startIndex = m.start()
    endIndex = m.end()
    inSingleQuotesblock = False
    inDoubleQuotesblock = False
    while startIndex != -1:
      # 判断{  }是否在两个单引号中间
      singleQuotesQty = rawlines[i][0:startIndex].count("'")
      if singleQuotesQty % 2 == 1 and rawlines[i][startIndex:].count("'") > 0:
        inSingleQuotesblock = True
      if not inSingleQuotesblock:
        # 判断{  }是否在两个双引号中间
        doubleQuotesQty = rawlines[i][0:startIndex].count('"')
        if doubleQuotesQty % 2 == 1 and rawlines[i][startIndex:].count('"') > 0:
          inDoubleQuotesblock = True
      # {  }在两个单引号中间或者在两个双引号中间,需要查找下一个{  }
      if inSingleQuotesblock or inDoubleQuotesblock:
        pass
      # {  }不是字符串中的字符
      else:
        # 为了避免注释中的{   }情况被误判
        # if(...) {} else { /*111 {    }1111*/  }
        # if(...) {} else { /*1111111*/  } // {    }
        # if(...) {} else { /*1111111*/  } /*1111111*/ /* {    }
        singleCommentIndex = rawlines[i][0:startIndex].rfind('//')
        multiCommentOpenIndex = rawlines[i][0:startIndex].rfind('/*')
        multiCommentCloseIndex = rawlines[i][0:startIndex].rfind('*/')
        isComment = False
        if singleCommentIndex == -1 and multiCommentOpenIndex == -1:
          pass
        # if(...) {} else { /*1111111*/  } /*1111111*/ /* {    }
        elif multiCommentOpenIndex > -1 and multiCommentOpenIndex > multiCommentCloseIndex:
          isComment =True
        # if(...) {} else { /*1111111*/  } /*1111111*/ // {    }
        # if(...) {} else { /*1111111*/  } //  /*1111111*/ {    }
        # if(...) {} else { /*1111111*/  } // 2345345*/ {    }
        elif singleCommentIndex > -1:
          if (multiCommentCloseIndex > -1 and singleCommentIndex > multiCommentCloseIndex) or \
             (multiCommentOpenIndex > -1 and singleCommentIndex < multiCommentOpenIndex) or \
              multiCommentOpenIndex == -1:
            isComment =True
        # if(...) {} else { /*1111111
        #                     if(...) {  } */
        multiCommentOpenIndex = rawlines[i][startIndex:].find('/*')
        multiCommentCloseIndex = rawlines[i][startIndex:].find('*/')
        if not isComment and multiCommentCloseIndex > -1 and multiCommentCloseIndex < multiCommentOpenIndex:
          isComment = True
        # {}中全是空格且不是注释的情况,报错,不再check本行了,check下一行
        if not isComment:
          Error(filename, lines, i, ruleCheckKey, 3, errMessage)
          j = cpplines[i].find("{") + 1
          strTemp = "{"
          while j < len(cpplines[i]):
            if cpplines[i][j] == " ":
              strTemp += " "
              j += 1
            elif cpplines[i][j] == "}":
              fileErrorCount[0] += 1
              cpplines[i] = cpplines[i].replace(strTemp, "{")
              break
            else:
              break
          i += 1
          startIndex = -1
          continue
      # 查找下一个{  }
      m = strcmp.Search(r'\{\s+\}', rawlines[i][endIndex:])
      if m:
        inSingleQuotesblock = False
        inDoubleQuotesblock = False
        startIndex = endIndex + m.start()
        endIndex = endIndex + m.end()
        continue
      # 查找不到下一个{  },不再检查本行了,去检查下一行
      else:
        i += 1
        startIndex = -1
def CheckCSC030028(filename, file_extension, clean_lines, rawlines, nesting_state, ruleCheckKey, Error, cpplines, fileErrorCount):
  '''右大括号}之前如果有内容,请保留一个空格。[必须] 
  Args:
    filename:文件名
    file_extension:文件扩展名
    clean_lines:Holds 3 copies of all lines with different preprocessing applied to them
                 1) elided member contains lines without strings and comments,
                 2) lines member contains lines without comments, and
                 3) raw_lines member contains all the lines without processing.(行首以/*开头的多行注释被替换成空白)
    rawlines:all the lines without processing
    nesting_state: Holds states related to parsing braces.(cpplint中的对象,暂时未使用)
    startLineNo:for,while,if,switch所在的行
    ruleCheckKey:ruleid
    Error: error output method
  '''
  lines = clean_lines.elided
  errMessage = 'Code Style Rule: If there is contents before a right curly brace "}", please leave a space between them.'
  i = 0
  while i < clean_lines.NumLines():
    # null line skip
    if common.IsBlankLine(lines[i]):
      i += 1
      continue
    #define line skip
    if strcmp.Search(r'^\s*#\s*define\s+', lines[i]):
      i = common.getDefineMacroEndLineNo(lines, i) + 1
      continue
    # line start with # skip
    if strcmp.Search(r'^\s*#', lines[i]):
      i += 1
      continue
    m = strcmp.Search(r'[^\s\{]\}', lines[i])
    # 当 } 前面的字符不是空格,也不是{,则报错
    if m:
      Error(filename, lines, i, ruleCheckKey, 3, errMessage)
      fileErrorCount[0] += 1
      cpplines[i] = cpplines[i].replace("}", " }")
      i += 1
      continue
    # 查看}前是否紧跟着多行注释标识符的*/
    m = strcmp.Search(r'\*/\}', rawlines[i])
    # 找不到这种情况,进入下次循环
    if not m:
      i += 1
      continue
    startIndex = m.start()
    endIndex = m.end()
    # */} 是//后面的注释内容则check下一行,不再check本行了
    if rawlines[i][startIndex:].rfind('//') > -1:
      i += 1
      continue
    inSingleQuotesblock = False
    inDoubleQuotesblock = False
    while startIndex != -1:
      # 判断*/}是否在两个单引号中间
      singleQuotesQty = rawlines[i][0:startIndex].count("'")
      if singleQuotesQty % 2 == 1 and rawlines[i][startIndex:].count("'") > 0:
        inSingleQuotesblock = True
      if not inSingleQuotesblock:
        # 判断*/}是否在两个双引号中间
        doubleQuotesQty = rawlines[i][0:startIndex].count('"')
        if doubleQuotesQty % 2 == 1 and rawlines[i][startIndex:].count('"') > 0:
          inDoubleQuotesblock = True
      # */}在两个单引号中间或者在两个双引号中间,需要查找下一个{  }
      if inSingleQuotesblock or inDoubleQuotesblock:
        # 查找下一个*/}
        m = strcmp.Search(r'\*/\}', rawlines[i][endIndex:])
        if m:
          inSingleQuotesblock = False
          inDoubleQuotesblock = False
          startIndex = endIndex + m.start()
          endIndex = endIndex + m.end()
        # 查找不到下一个*/},不再检查本行了,去检查下一行
        else:
          i += 1
          startIndex = -1 
      # */}不是字符串中的字符
      else:
        # */} 不是//后面的注释内容,则报错;如果是//后面的注释内容,则check下一行,不再check本行了
        if rawlines[i][startIndex:].rfind('//') == -1:        
          Error(filename, lines, i, ruleCheckKey, 3, errMessage)
          fileErrorCount[0] += 1
          cpplines[i] = cpplines[i].replace("}", " }")
        i += 1
        startIndex = -1