signature:
def CheckBracesSpacing ( filename , clean_lines , linenum , nesting_state , error ) :
    """Checks for horizontal spacing near commas .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 nesting _ state : A NestingState instance which maintains information about
 the current stack of nested blocks being parsed .
 error : The function to call with any errors found ."""

implementation:
line = clean_lines . elided [ linenum ]
# Except after an opening paren , or after another opening brace ( in case of
# an initializer list , for instance ) , you should have spaces before your
# braces when they are delimiting blocks , classes , namespaces etc .
# And since you should never have braces at the beginning of a line ,
# this is an easy test . Except that braces used for initialization don ' t
# follow the same rule ; we often don ' t want spaces before those .
match = Match ( r'^(.*[^ ({>]){' , line )
if match : # Try a bit harder to check for brace initialization . This
# happens in one of the following forms :
# Constructor ( ) : initializer _ list _ { } { . . . }
# Constructor { } . MemberFunction ( )
# Type variable { } ;
# FunctionCall ( type { } , . . . ) ;
# LastArgument ( . . . , type { } ) ;
# LOG ( INFO ) < < type { } < < " . . . " ;
# map _ of _ type [ { . . . } ] = . . . ;
# ternary = expr ? new type { } : nullptr ;
# OuterTemplate < InnerTemplateConstructor < Type > { } >
# We check for the character following the closing brace , and
# silence the warning if it ' s one of those listed above , i . e .
# To account for nested initializer list , we allow any number of
# closing braces up to " { ; , ) < " . We can ' t simply silence the
# warning on first sight of closing brace , because that would
# cause false negatives for things that are not initializer lists .
# Silence this : But not this :
# Outer { if ( . . . ) {
# Inner { . . . } if ( . . . ) { / / Missing space before {
# There is a false negative with this approach if people inserted
# spurious semicolons , e . g . " if ( cond ) { } ; " , but we will catch the
# spurious semicolon with a separate check .
    leading_text = match . group ( 1 )
    ( endline , endlinenum , endpos ) = CloseExpression ( clean_lines , linenum , len ( match . group ( 1 ) ) )
    trailing_text = ''
    if endpos > - 1 :
        trailing_text = endline [ endpos : ]
    for offset in xrange ( endlinenum + 1 , min ( endlinenum + 3 , clean_lines . NumLines ( ) - 1 ) ) :
        trailing_text += clean_lines . elided [ offset ]
    # We also suppress warnings for ` uint64 _ t { expression } ` etc . , as the style
    # guide recommends brace initialization for integral types to avoid
    # overflow / truncation .
    if ( not Match ( r'^[\s}]*[{.;,)<>\]:]' , trailing_text ) and not _IsType ( clean_lines , nesting_state , leading_text ) ) :
        error ( filename , linenum , 'whitespace/braces' , 5 , 'Missing space before {' )
# Make sure ' } else { ' has spaces .
if Search ( r'}else' , line ) :
    error ( filename , linenum , 'whitespace/braces' , 5 , 'Missing space before else' )
# You shouldn ' t have a space before a semicolon at the end of the line .
# There ' s a special case for " for " since the style guide allows space before
# the semicolon there .
if Search ( r':\s*;\s*$' , line ) :
    error ( filename , linenum , 'whitespace/semicolon' , 5 , 'Semicolon defining empty statement. Use {} instead.' )
elif Search ( r'^\s*;\s*$' , line ) :
    error ( filename , linenum , 'whitespace/semicolon' , 5 , 'Line contains only semicolon. If this should be an empty statement, ' 'use {} instead.' )
elif ( Search ( r'\s+;\s*$' , line ) and not Search ( r'\bfor\b' , line ) ) :
    error ( filename , linenum , 'whitespace/semicolon' , 5 , 'Extra space before last semicolon. If this should be an empty ' 'statement, use {} instead.' )


signature:
def IsDecltype ( clean_lines , linenum , column ) :
    """Check if the token ending on ( linenum , column ) is decltype ( ) .
 Args :
 clean _ lines : A CleansedLines instance containing the file .
 linenum : the number of the line to check .
 column : end column of the token to check .
 Returns :
 True if this token is decltype ( ) expression , False otherwise ."""

implementation:
( text , _ , start_col ) = ReverseCloseExpression ( clean_lines , linenum , column )
if start_col < 0 :
    return False
if Search ( r'\bdecltype\s*$' , text [ 0 : start_col ] ) :
    return True
return False


signature:
def CheckSectionSpacing ( filename , clean_lines , class_info , linenum , error ) :
    """Checks for additional blank line issues related to sections .
 Currently the only thing checked here is blank line before protected / private .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 class _ info : A _ ClassInfo objects .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
# Skip checks if the class is small , where small means 25 lines or less .
# 25 lines seems like a good cutoff since that ' s the usual height of
# terminals , and any class that can ' t fit in one screen can ' t really
# be considered " small " .
# Also skip checks if we are on the first line . This accounts for
# classes that look like
# class Foo { public : . . . } ;
# If we didn ' t find the end of the class , last _ line would be zero ,
# and the check will be skipped by the first condition .
if ( class_info . last_line - class_info . starting_linenum <= 24 or linenum <= class_info . starting_linenum ) :
    return
matched = Match ( r'\s*(public|protected|private):' , clean_lines . lines [ linenum ] )
if matched : # Issue warning if the line before public / protected / private was
# not a blank line , but don ' t do this if the previous line contains
# " class " or " struct " . This can happen two ways :
# - We are at the beginning of the class .
# - We are forward - declaring an inner class that is semantically
# private , but needed to be public for implementation reasons .
# Also ignores cases where the previous line ends with a backslash as can be
# common when defining classes in C macros .
    prev_line = clean_lines . lines [ linenum - 1 ]
    if ( not IsBlankLine ( prev_line ) and not Search ( r'\b(class|struct)\b' , prev_line ) and not Search ( r'\\$' , prev_line ) ) : # Try a bit harder to find the beginning of the class . This is to
    # account for multi - line base - specifier lists , e . g . :
    # class Derived
    # : public Base {
        end_class_head = class_info . starting_linenum
        for i in range ( class_info . starting_linenum , linenum ) :
            if Search ( r'\{\s*$' , clean_lines . lines [ i ] ) :
                end_class_head = i
                break
        if end_class_head < linenum - 1 :
            error ( filename , linenum , 'whitespace/blank_line' , 3 , '"%s:" should be preceded by a blank line' % matched . group ( 1 ) )


signature:
def GetPreviousNonBlankLine ( clean_lines , linenum ) :
    """Return the most recent non - blank line and its line number .
 Args :
 clean _ lines : A CleansedLines instance containing the file contents .
 linenum : The number of the line to check .
 Returns :
 A tuple with two elements . The first element is the contents of the last
 non - blank line before the current line , or the empty string if this is the
 first non - blank line . The second is the line number of that line , or - 1
 if this is the first non - blank line ."""

implementation:
prevlinenum = linenum - 1
while prevlinenum >= 0 :
    prevline = clean_lines . elided [ prevlinenum ]
    if not IsBlankLine ( prevline ) : # if not a blank line . . .
        return ( prevline , prevlinenum )
    prevlinenum -= 1
return ( '' , - 1 )


signature:
def CheckTrailingSemicolon ( filename , clean_lines , linenum , error ) :
    """Looks for redundant trailing semicolon .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
line = clean_lines . elided [ linenum ]
# Block bodies should not be followed by a semicolon . Due to C + + 11
# brace initialization , there are more places where semicolons are
# required than not , so we use a whitelist approach to check these
# rather than a blacklist . These are the places where " } ; " should
# be replaced by just " } " :
# 1 . Some flavor of block following closing parenthesis :
# for ( ; ; ) { } ;
# while ( . . . ) { } ;
# switch ( . . . ) { } ;
# Function ( . . . ) { } ;
# if ( . . . ) { } ;
# if ( . . . ) else if ( . . . ) { } ;
# 2 . else block :
# if ( . . . ) else { } ;
# 3 . const member function :
# Function ( . . . ) const { } ;
# 4 . Block following some statement :
# x = 42;
# 5 . Block at the beginning of a function :
# Function ( . . . ) {
# Note that naively checking for the preceding " { " will also match
# braces inside multi - dimensional arrays , but this is fine since
# that expression will not contain semicolons .
# 6 . Block following another block :
# while ( true ) { }
# 7 . End of namespaces :
# namespace { } ;
# These semicolons seems far more common than other kinds of
# redundant semicolons , possibly due to people converting classes
# to namespaces . For now we do not warn for this case .
# Try matching case 1 first .
match = Match ( r'^(.*\)\s*)\{' , line )
if match : # Matched closing parenthesis ( case 1 ) . Check the token before the
# matching opening parenthesis , and don ' t warn if it looks like a
# macro . This avoids these false positives :
# - macro that defines a base class
# - multi - line macro that defines a base class
# - macro that defines the whole class - head
# But we still issue warnings for macros that we know are safe to
# warn , specifically :
# - TEST , TEST _ F , TEST _ P , MATCHER , MATCHER _ P
# - TYPED _ TEST
# - INTERFACE _ DEF
# - EXCLUSIVE _ LOCKS _ REQUIRED , SHARED _ LOCKS _ REQUIRED , LOCKS _ EXCLUDED :
# We implement a whitelist of safe macros instead of a blacklist of
# unsafe macros , even though the latter appears less frequently in
# google code and would have been easier to implement . This is because
# the downside for getting the whitelist wrong means some extra
# semicolons , while the downside for getting the blacklist wrong
# would result in compile errors .
# In addition to macros , we also don ' t want to warn on
# - Compound literals
# - Lambdas
# - alignas specifier with anonymous structs
# - decltype
    closing_brace_pos = match . group ( 1 ) . rfind ( ')' )
    opening_parenthesis = ReverseCloseExpression ( clean_lines , linenum , closing_brace_pos )
    if opening_parenthesis [ 2 ] > - 1 :
        line_prefix = opening_parenthesis [ 0 ] [ 0 : opening_parenthesis [ 2 ] ]
        macro = Search ( r'\b([A-Z_][A-Z0-9_]*)\s*$' , line_prefix )
        func = Match ( r'^(.*\])\s*$' , line_prefix )
        if ( ( macro and macro . group ( 1 ) not in ( 'TEST' , 'TEST_F' , 'MATCHER' , 'MATCHER_P' , 'TYPED_TEST' , 'EXCLUSIVE_LOCKS_REQUIRED' , 'SHARED_LOCKS_REQUIRED' , 'LOCKS_EXCLUDED' , 'INTERFACE_DEF' ) ) or ( func and not Search ( r'\boperator\s*\[\s*\]' , func . group ( 1 ) ) ) or Search ( r'\b(?:struct|union)\s+alignas\s*$' , line_prefix ) or Search ( r'\bdecltype$' , line_prefix ) or Search ( r'\s+=\s*$' , line_prefix ) ) :
            match = None
    if ( match and opening_parenthesis [ 1 ] > 1 and Search ( r'\]\s*$' , clean_lines . elided [ opening_parenthesis [ 1 ] - 1 ] ) ) : # Multi - line lambda - expression
        match = None
else : # Try matching cases 2-3.
    match = Match ( r'^(.*(?:else|\)\s*const)\s*)\{' , line )
    if not match : # Try matching cases 4-6 . These are always matched on separate lines .
    # Note that we can ' t simply concatenate the previous line to the
    # current line and do a single match , otherwise we may output
    # duplicate warnings for the blank line case :
    # if ( cond ) {
    # / / blank line
        prevline = GetPreviousNonBlankLine ( clean_lines , linenum ) [ 0 ]
        if prevline and Search ( r'[;{}]\s*$' , prevline ) :
            match = Match ( r'^(\s*)\{' , line )
# Check matching closing brace
if match :
    ( endline , endlinenum , endpos ) = CloseExpression ( clean_lines , linenum , len ( match . group ( 1 ) ) )
    if endpos > - 1 and Match ( r'^\s*;' , endline [ endpos : ] ) : # Current { } pair is eligible for semicolon check , and we have found
    # the redundant semicolon , output warning here .
    # Note : because we are scanning forward for opening braces , and
    # outputting warnings for the matching closing brace , if there are
    # nested blocks with trailing semicolons , we will get the error
    # messages in reversed order .
    # We need to check the line forward for NOLINT
        raw_lines = clean_lines . raw_lines
        ParseNolintSuppressions ( filename , raw_lines [ endlinenum - 1 ] , endlinenum - 1 , error )
        ParseNolintSuppressions ( filename , raw_lines [ endlinenum ] , endlinenum , error )
        error ( filename , endlinenum , 'readability/braces' , 4 , "You don't need a ; after a }" )


signature:
def CheckEmptyBlockBody ( filename , clean_lines , linenum , error ) :
    """Look for empty loop / conditional body with only a single semicolon .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
# Search for loop keywords at the beginning of the line . Because only
# whitespaces are allowed before the keywords , this will also ignore most
# do - while - loops , since those lines should start with closing brace .
# We also check " if " blocks here , since an empty conditional block
# is likely an error .
line = clean_lines . elided [ linenum ]
matched = Match ( r'\s*(for|while|if)\s*\(' , line )
if matched : # Find the end of the conditional expression .
    ( end_line , end_linenum , end_pos ) = CloseExpression ( clean_lines , linenum , line . find ( '(' ) )
    # Output warning if what follows the condition expression is a semicolon .
    # No warning for all other cases , including whitespace or newline , since we
    # have a separate check for semicolons preceded by whitespace .
    if end_pos >= 0 and Match ( r';' , end_line [ end_pos : ] ) :
        if matched . group ( 1 ) == 'if' :
            error ( filename , end_linenum , 'whitespace/empty_conditional_body' , 5 , 'Empty conditional bodies should use {}' )
        else :
            error ( filename , end_linenum , 'whitespace/empty_loop_body' , 5 , 'Empty loop bodies should use {} or continue' )
    # Check for if statements that have completely empty bodies ( no comments )
    # and no else clauses .
    if end_pos >= 0 and matched . group ( 1 ) == 'if' : # Find the position of the opening { for the if statement .
    # Return without logging an error if it has no brackets .
        opening_linenum = end_linenum
        opening_line_fragment = end_line [ end_pos : ]
        # Loop until EOF or find anything that ' s not whitespace or opening { .
        while not Search ( r'^\s*\{' , opening_line_fragment ) :
            if Search ( r'^(?!\s*$)' , opening_line_fragment ) : # Conditional has no brackets .
                return
            opening_linenum += 1
            if opening_linenum == len ( clean_lines . elided ) : # Couldn ' t find conditional ' s opening { or any code before EOF .
                return
            opening_line_fragment = clean_lines . elided [ opening_linenum ]
        # Set opening _ line ( opening _ line _ fragment may not be entire opening line ) .
        opening_line = clean_lines . elided [ opening_linenum ]
        # Find the position of the closing } .
        opening_pos = opening_line_fragment . find ( '{' )
        if opening_linenum == end_linenum : # We need to make opening _ pos relative to the start of the entire line .
            opening_pos += end_pos
        ( closing_line , closing_linenum , closing_pos ) = CloseExpression ( clean_lines , opening_linenum , opening_pos )
        if closing_pos < 0 :
            return
        # Now construct the body of the conditional . This consists of the portion
        # of the opening line after the { , all lines until the closing line ,
        # and the portion of the closing line before the } .
        if ( clean_lines . raw_lines [ opening_linenum ] != CleanseComments ( clean_lines . raw_lines [ opening_linenum ] ) ) : # Opening line ends with a comment , so conditional isn ' t empty .
            return
        if closing_linenum > opening_linenum : # Opening line after the { . Ignore comments here since we checked above .
            bodylist = list ( opening_line [ opening_pos + 1 : ] )
            # All lines until closing line , excluding closing line , with comments .
            bodylist . extend ( clean_lines . raw_lines [ opening_linenum + 1 : closing_linenum ] )
            # Closing line before the } . Won ' t ( and can ' t ) have comments .
            bodylist . append ( clean_lines . elided [ closing_linenum ] [ : closing_pos - 1 ] )
            body = '\n' . join ( bodylist )
        else : # If statement has brackets and fits on a single line .
            body = opening_line [ opening_pos + 1 : closing_pos - 1 ]
        # Check if the body is empty
        if not _EMPTY_CONDITIONAL_BODY_PATTERN . search ( body ) :
            return
        # The body is empty . Now make sure there ' s not an else clause .
        current_linenum = closing_linenum
        current_line_fragment = closing_line [ closing_pos : ]
        # Loop until EOF or find anything that ' s not whitespace or else clause .
        while Search ( r'^\s*$|^(?=\s*else)' , current_line_fragment ) :
            if Search ( r'^(?=\s*else)' , current_line_fragment ) : # Found an else clause , so don ' t log an error .
                return
            current_linenum += 1
            if current_linenum == len ( clean_lines . elided ) :
                break
            current_line_fragment = clean_lines . elided [ current_linenum ]
        # The body is empty and there ' s no else clause until EOF or other code .
        error ( filename , end_linenum , 'whitespace/empty_if_body' , 4 , ( 'If statement had no body and no else clause' ) )


signature:
def FindCheckMacro ( line ) :
    """Find a replaceable CHECK - like macro .
 Args :
 line : line to search on .
 Returns :
 ( macro name , start position ) , or ( None , - 1 ) if no replaceable
 macro is found ."""

implementation:
for macro in _CHECK_MACROS :
    i = line . find ( macro )
    if i >= 0 : # Find opening parenthesis . Do a regular expression match here
    # to make sure that we are matching the expected CHECK macro , as
    # opposed to some other macro that happens to contain the CHECK
    # substring .
        matched = Match ( r'^(.*\b' + macro + r'\s*)\(' , line )
        if not matched :
            continue
        return ( macro , len ( matched . group ( 1 ) ) )
return ( None , - 1 )


signature:
def CheckCheck ( filename , clean_lines , linenum , error ) :
    """Checks the use of CHECK and EXPECT macros .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
# Decide the set of replacement macros that should be suggested
lines = clean_lines . elided
( check_macro , start_pos ) = FindCheckMacro ( lines [ linenum ] )
if not check_macro :
    return
# Find end of the boolean expression by matching parentheses
( last_line , end_line , end_pos ) = CloseExpression ( clean_lines , linenum , start_pos )
if end_pos < 0 :
    return
# If the check macro is followed by something other than a
# semicolon , assume users will log their own custom error messages
# and don ' t suggest any replacements .
if not Match ( r'\s*;' , last_line [ end_pos : ] ) :
    return
if linenum == end_line :
    expression = lines [ linenum ] [ start_pos + 1 : end_pos - 1 ]
else :
    expression = lines [ linenum ] [ start_pos + 1 : ]
    for i in xrange ( linenum + 1 , end_line ) :
        expression += lines [ i ]
    expression += last_line [ 0 : end_pos - 1 ]
# Parse expression so that we can take parentheses into account .
# This avoids false positives for inputs like " CHECK ( ( a < 4 ) = = b ) " ,
# which is not replaceable by CHECK _ LE .
lhs = ''
rhs = ''
operator = None
while expression :
    matched = Match ( r'^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||' r'==|!=|>=|>|<=|<|\()(.*)$' , expression )
    if matched :
        token = matched . group ( 1 )
        if token == '(' : # Parenthesized operand
            expression = matched . group ( 2 )
            ( end , _ ) = FindEndOfExpressionInLine ( expression , 0 , [ '(' ] )
            if end < 0 :
                return
                # Unmatched parenthesis
            lhs += '(' + expression [ 0 : end ]
            expression = expression [ end : ]
        elif token in ( '&&' , '||' ) : # Logical and / or operators . This means the expression
        # contains more than one term , for example :
        # CHECK ( 42 < a & & a < b ) ;
        # These are not replaceable with CHECK _ LE , so bail out early .
            return
        elif token in ( '<<' , '<<=' , '>>' , '>>=' , '->*' , '->' ) : # Non - relational operator
            lhs += token
            expression = matched . group ( 2 )
        else : # Relational operator
            operator = token
            rhs = matched . group ( 2 )
            break
    else : # Unparenthesized operand . Instead of appending to lhs one character
    # at a time , we do another regular expression match to consume several
    # characters at once if possible . Trivial benchmark shows that this
    # is more efficient when the operands are longer than a single
    # character , which is generally the case .
        matched = Match ( r'^([^-=!<>()&|]+)(.*)$' , expression )
        if not matched :
            matched = Match ( r'^(\s*\S)(.*)$' , expression )
            if not matched :
                break
        lhs += matched . group ( 1 )
        expression = matched . group ( 2 )
# Only apply checks if we got all parts of the boolean expression
if not ( lhs and operator and rhs ) :
    return
# Check that rhs do not contain logical operators . We already know
# that lhs is fine since the loop above parses out & & and | | .
if rhs . find ( '&&' ) > - 1 or rhs . find ( '||' ) > - 1 :
    return
# At least one of the operands must be a constant literal . This is
# to avoid suggesting replacements for unprintable things like
# CHECK ( variable ! = iterator )
# The following pattern matches decimal , hex integers , strings , and
# characters ( in that order ) .
lhs = lhs . strip ( )
rhs = rhs . strip ( )
match_constant = r'^([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')$'
if Match ( match_constant , lhs ) or Match ( match_constant , rhs ) : # Note : since we know both lhs and rhs , we can provide a more
# descriptive error message like :
# Consider using CHECK _ EQ ( x , 42 ) instead of CHECK ( x = = 42)
# Instead of :
# Consider using CHECK _ EQ instead of CHECK ( a = = b )
# We are still keeping the less descriptive message because if lhs
# or rhs gets long , the error message might become unreadable .
    error ( filename , linenum , 'readability/check' , 2 , 'Consider using %s instead of %s(a %s b)' % ( _CHECK_REPLACEMENT [ check_macro ] [ operator ] , check_macro , operator ) )


signature:
def CheckAltTokens ( filename , clean_lines , linenum , error ) :
    """Check alternative keywords being used in boolean expressions .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
line = clean_lines . elided [ linenum ]
# Avoid preprocessor lines
if Match ( r'^\s*#' , line ) :
    return
# Last ditch effort to avoid multi - line comments . This will not help
# if the comment started before the current line or ended after the
# current line , but it catches most of the false positives . At least ,
# it provides a way to workaround this warning for people who use
# multi - line comments in preprocessor macros .
# TODO ( unknown ) : remove this once cpplint has better support for
# multi - line comments .
if line . find ( '/*' ) >= 0 or line . find ( '*/' ) >= 0 :
    return
for match in _ALT_TOKEN_REPLACEMENT_PATTERN . finditer ( line ) :
    error ( filename , linenum , 'readability/alt_tokens' , 2 , 'Use operator %s instead of %s' % ( _ALT_TOKEN_REPLACEMENT [ match . group ( 1 ) ] , match . group ( 1 ) ) )


signature:
def GetLineWidth ( line ) :
    """Determines the width of the line in column positions .
 Args :
 line : A string , which may be a Unicode string .
 Returns :
 The width of the line in column positions , accounting for Unicode
 combining characters and wide characters ."""

implementation:
if isinstance ( line , unicode ) :
    width = 0
    for uc in unicodedata . normalize ( 'NFC' , line ) :
        if unicodedata . east_asian_width ( uc ) in ( 'W' , 'F' ) :
            width += 2
        elif not unicodedata . combining ( uc ) :
            width += 1
    return width
else :
    return len ( line )


signature:
def _DropCommonSuffixes ( filename ) :
    """Drops common suffixes like _ test . cc or - inl . h from filename .
 For example :
 > > > _ DropCommonSuffixes ( ' foo / foo - inl . h ' )
 ' foo / foo '
 > > > _ DropCommonSuffixes ( ' foo / bar / foo . cc ' )
 ' foo / bar / foo '
 > > > _ DropCommonSuffixes ( ' foo / foo _ internal . h ' )
 ' foo / foo '
 > > > _ DropCommonSuffixes ( ' foo / foo _ unusualinternal . h ' )
 ' foo / foo _ unusualinternal '
 Args :
 filename : The input filename .
 Returns :
 The filename with the common suffix removed ."""

implementation:
for suffix in itertools . chain ( ( '%s.%s' % ( test_suffix . lstrip ( '_' ) , ext ) for test_suffix , ext in itertools . product ( _test_suffixes , GetNonHeaderExtensions ( ) ) ) , ( '%s.%s' % ( suffix , ext ) for suffix , ext in itertools . product ( [ 'inl' , 'imp' , 'internal' ] , GetHeaderExtensions ( ) ) ) ) :
    if ( filename . endswith ( suffix ) and len ( filename ) > len ( suffix ) and filename [ - len ( suffix ) - 1 ] in ( '-' , '_' ) ) :
        return filename [ : - len ( suffix ) - 1 ]
return os . path . splitext ( filename ) [ 0 ]


signature:
def _ClassifyInclude ( fileinfo , include , is_system ) :
    """Figures out what kind of header ' include ' is .
 Args :
 fileinfo : The current file cpplint is running over . A FileInfo instance .
 include : The path to a # included file .
 is _ system : True if the # include used < > rather than " " .
 Returns :
 One of the _ XXX _ HEADER constants .
 For example :
 > > > _ ClassifyInclude ( FileInfo ( ' foo / foo . cc ' ) , ' stdio . h ' , True )
 _ C _ SYS _ HEADER
 > > > _ ClassifyInclude ( FileInfo ( ' foo / foo . cc ' ) , ' string ' , True )
 _ CPP _ SYS _ HEADER
 > > > _ ClassifyInclude ( FileInfo ( ' foo / foo . cc ' ) , ' foo / foo . h ' , False )
 _ LIKELY _ MY _ HEADER
 > > > _ ClassifyInclude ( FileInfo ( ' foo / foo _ unknown _ extension . cc ' ) ,
 . . . ' bar / foo _ other _ ext . h ' , False )
 _ POSSIBLE _ MY _ HEADER
 > > > _ ClassifyInclude ( FileInfo ( ' foo / foo . cc ' ) , ' foo / bar . h ' , False )
 _ OTHER _ HEADER"""

implementation:
# This is a list of all standard c + + header files , except
# those already checked for above .
is_cpp_h = include in _CPP_HEADERS
# Headers with C + + extensions shouldn ' t be considered C system headers
if is_system and os . path . splitext ( include ) [ 1 ] in [ '.hpp' , '.hxx' , '.h++' ] :
    is_system = False
if is_system :
    if is_cpp_h :
        return _CPP_SYS_HEADER
    else :
        return _C_SYS_HEADER
# If the target file and the include we ' re checking share a
# basename when we drop common extensions , and the include
# lives in . , then it ' s likely to be owned by the target file .
target_dir , target_base = ( os . path . split ( _DropCommonSuffixes ( fileinfo . RepositoryName ( ) ) ) )
include_dir , include_base = os . path . split ( _DropCommonSuffixes ( include ) )
target_dir_pub = os . path . normpath ( target_dir + '/../public' )
target_dir_pub = target_dir_pub . replace ( '\\' , '/' )
if target_base == include_base and ( include_dir == target_dir or include_dir == target_dir_pub ) :
    return _LIKELY_MY_HEADER
# If the target and include share some initial basename
# component , it ' s possible the target is implementing the
# include , so it ' s allowed to be first , but we ' ll never
# complain if it ' s not there .
target_first_component = _RE_FIRST_COMPONENT . match ( target_base )
include_first_component = _RE_FIRST_COMPONENT . match ( include_base )
if ( target_first_component and include_first_component and target_first_component . group ( 0 ) == include_first_component . group ( 0 ) ) :
    return _POSSIBLE_MY_HEADER
return _OTHER_HEADER


signature:
def CheckIncludeLine ( filename , clean_lines , linenum , include_state , error ) :
    """Check rules that are applicable to # include lines .
 Strings on # include lines are NOT removed from elided line , to make
 certain tasks easier . However , to prevent false positives , checks
 applicable to # include lines in CheckLanguage must be put here .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 include _ state : An _ IncludeState instance in which the headers are inserted .
 error : The function to call with any errors found ."""

implementation:
fileinfo = FileInfo ( filename )
line = clean_lines . lines [ linenum ]
# " include " should use the new style " foo / bar . h " instead of just " bar . h "
# Only do this check if the included header follows google naming
# conventions . If not , assume that it ' s a 3rd party API that
# requires special include conventions .
# We also make an exception for Lua headers , which follow google
# naming convention but not the include convention .
match = Match ( r'#include\s*"([^/]+\.h)"' , line )
if match and not _THIRD_PARTY_HEADERS_PATTERN . match ( match . group ( 1 ) ) :
    error ( filename , linenum , 'build/include_subdir' , 4 , 'Include the directory when naming .h files' )
# we shouldn ' t include a file more than once . actually , there are a
# handful of instances where doing so is okay , but in general it ' s
# not .
match = _RE_PATTERN_INCLUDE . search ( line )
if match :
    include = match . group ( 2 )
    is_system = ( match . group ( 1 ) == '<' )
    duplicate_line = include_state . FindHeader ( include )
    if duplicate_line >= 0 :
        error ( filename , linenum , 'build/include' , 4 , '"%s" already included at %s:%s' % ( include , filename , duplicate_line ) )
        return
    for extension in GetNonHeaderExtensions ( ) :
        if ( include . endswith ( '.' + extension ) and os . path . dirname ( fileinfo . RepositoryName ( ) ) != os . path . dirname ( include ) ) :
            error ( filename , linenum , 'build/include' , 4 , 'Do not include .' + extension + ' files from other packages' )
            return
    if not _THIRD_PARTY_HEADERS_PATTERN . match ( include ) :
        include_state . include_list [ - 1 ] . append ( ( include , linenum ) )
        # We want to ensure that headers appear in the right order :
        # 1 ) for foo . cc , foo . h ( preferred location )
        # 2 ) c system files
        # 3 ) cpp system files
        # 4 ) for foo . cc , foo . h ( deprecated location )
        # 5 ) other google headers
        # We classify each include statement as one of those 5 types
        # using a number of techniques . The include _ state object keeps
        # track of the highest type seen , and complains if we see a
        # lower type after that .
        error_message = include_state . CheckNextIncludeOrder ( _ClassifyInclude ( fileinfo , include , is_system ) )
        if error_message :
            error ( filename , linenum , 'build/include_order' , 4 , '%s. Should be: %s.h, c system, c++ system, other.' % ( error_message , fileinfo . BaseName ( ) ) )
        canonical_include = include_state . CanonicalizeAlphabeticalOrder ( include )
        if not include_state . IsInAlphabeticalOrder ( clean_lines , linenum , canonical_include ) :
            error ( filename , linenum , 'build/include_alpha' , 4 , 'Include "%s" not in alphabetical order' % include )
        include_state . SetLastHeader ( canonical_include )


signature:
def _GetTextInside ( text , start_pattern ) :
    r"""Retrieves all the text between matching open and close parentheses .
 Given a string of lines and a regular expression string , retrieve all the text
 following the expression and between opening punctuation symbols like
 ( , [ , or { , and the matching close - punctuation symbol . This properly nested
 occurrences of the punctuations , so for the text like
 printf ( a ( ) , b ( c ( ) ) ) ;
 a call to _ GetTextInside ( text , r ' printf \ ( ' ) will return ' a ( ) , b ( c ( ) ) ' .
 start _ pattern must match string having an open punctuation symbol at the end .
 Args :
 text : The lines to extract text . Its comments and strings must be elided .
 It can be single line and can span multiple lines .
 start _ pattern : The regexp string indicating where to start extracting
 the text .
 Returns :
 The extracted text .
 None if either the opening string or ending punctuation could not be found ."""

implementation:
# TODO ( unknown ) : Audit cpplint . py to see what places could be profitably
# rewritten to use _ GetTextInside ( and use inferior regexp matching today ) .
# Give opening punctuations to get the matching close - punctuations .
matching_punctuation = { '(' : ')' , '{' : '}' , '[' : ']' }
closing_punctuation = set ( itervalues ( matching_punctuation ) )
# Find the position to start extracting text .
match = re . search ( start_pattern , text , re . M )
if not match : # start _ pattern not found in text .
    return None
start_position = match . end ( 0 )
assert start_position > 0 , ( 'start_pattern must ends with an opening punctuation.' )
assert text [ start_position - 1 ] in matching_punctuation , ( 'start_pattern must ends with an opening punctuation.' )
# Stack of closing punctuations we expect to have in text after position .
punctuation_stack = [ matching_punctuation [ text [ start_position - 1 ] ] ]
position = start_position
while punctuation_stack and position < len ( text ) :
    if text [ position ] == punctuation_stack [ - 1 ] :
        punctuation_stack . pop ( )
    elif text [ position ] in closing_punctuation : # A closing punctuation without matching opening punctuations .
        return None
    elif text [ position ] in matching_punctuation :
        punctuation_stack . append ( matching_punctuation [ text [ position ] ] )
    position += 1
if punctuation_stack : # Opening punctuations left without matching close - punctuations .
    return None
# punctuations match .
return text [ start_position : position - 1 ]


signature:
def CheckLanguage ( filename , clean_lines , linenum , file_extension , include_state , nesting_state , error ) :
    """Checks rules from the ' C + + language rules ' section of cppguide . html .
 Some of these rules are hard to test ( function overloading , using
 uint32 inappropriately ) , but we do the best we can .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 file _ extension : The extension ( without the dot ) of the filename .
 include _ state : An _ IncludeState instance in which the headers are inserted .
 nesting _ state : A NestingState instance which maintains information about
 the current stack of nested blocks being parsed .
 error : The function to call with any errors found ."""

implementation:
# If the line is empty or consists of entirely a comment , no need to
# check it .
line = clean_lines . elided [ linenum ]
if not line :
    return
match = _RE_PATTERN_INCLUDE . search ( line )
if match :
    CheckIncludeLine ( filename , clean_lines , linenum , include_state , error )
    return
# Reset include state across preprocessor directives . This is meant
# to silence warnings for conditional includes .
match = Match ( r'^\s*#\s*(if|ifdef|ifndef|elif|else|endif)\b' , line )
if match :
    include_state . ResetSection ( match . group ( 1 ) )
# Perform other checks now that we are sure that this is not an include line
CheckCasts ( filename , clean_lines , linenum , error )
CheckGlobalStatic ( filename , clean_lines , linenum , error )
CheckPrintf ( filename , clean_lines , linenum , error )
if file_extension in GetHeaderExtensions ( ) : # TODO ( unknown ) : check that 1 - arg constructors are explicit .
# How to tell it ' s a constructor ?
# ( handled in CheckForNonStandardConstructs for now )
# TODO ( unknown ) : check that classes declare or disable copy / assign
# ( level 1 error )
    pass
# Check if people are using the verboten C basic types . The only exception
# we regularly allow is " unsigned short port " for port .
if Search ( r'\bshort port\b' , line ) :
    if not Search ( r'\bunsigned short port\b' , line ) :
        error ( filename , linenum , 'runtime/int' , 4 , 'Use "unsigned short" for ports, not "short"' )
else :
    match = Search ( r'\b(short|long(?! +double)|long long)\b' , line )
    if match :
        error ( filename , linenum , 'runtime/int' , 4 , 'Use int16/int64/etc, rather than the C type %s' % match . group ( 1 ) )
# Check if some verboten operator overloading is going on
# TODO ( unknown ) : catch out - of - line unary operator & :
# class X { } ;
# int operator & ( const X & x ) { return 42 ; } / / unary operator &
# The trick is it ' s hard to tell apart from binary operator & :
# class Y { int operator & ( const Y & x ) { return 23 ; } } ; / / binary operator &
if Search ( r'\boperator\s*&\s*\(\s*\)' , line ) :
    error ( filename , linenum , 'runtime/operator' , 4 , 'Unary operator& is dangerous.  Do not use it.' )
# Check for suspicious usage of " if " like
# } if ( a = = b ) {
if Search ( r'\}\s*if\s*\(' , line ) :
    error ( filename , linenum , 'readability/braces' , 4 , 'Did you mean "else if"? If not, start a new line for "if".' )
# Check for potential format string bugs like printf ( foo ) .
# We constrain the pattern not to pick things like DocidForPrintf ( foo ) .
# Not perfect but it can catch printf ( foo . c _ str ( ) ) and printf ( foo - > c _ str ( ) )
# TODO ( unknown ) : Catch the following case . Need to change the calling
# convention of the whole function to process multiple line to handle it .
# printf (
# boy _ this _ is _ a _ really _ long _ variable _ that _ cannot _ fit _ on _ the _ prev _ line ) ;
printf_args = _GetTextInside ( line , r'(?i)\b(string)?printf\s*\(' )
if printf_args :
    match = Match ( r'([\w.\->()]+)$' , printf_args )
    if match and match . group ( 1 ) != '__VA_ARGS__' :
        function_name = re . search ( r'\b((?:string)?printf)\s*\(' , line , re . I ) . group ( 1 )
        error ( filename , linenum , 'runtime/printf' , 4 , 'Potential format string bug. Do %s("%%s", %s) instead.' % ( function_name , match . group ( 1 ) ) )
# Check for potential memset bugs like memset ( buf , sizeof ( buf ) , 0 ) .
match = Search ( r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)' , line )
if match and not Match ( r"^''|-?[0-9]+|0x[0-9A-Fa-f]$" , match . group ( 2 ) ) :
    error ( filename , linenum , 'runtime/memset' , 4 , 'Did you mean "memset(%s, 0, %s)"?' % ( match . group ( 1 ) , match . group ( 2 ) ) )
if Search ( r'\busing namespace\b' , line ) :
    if Search ( r'\bliterals\b' , line ) :
        error ( filename , linenum , 'build/namespaces_literals' , 5 , 'Do not use namespace using-directives.  ' 'Use using-declarations instead.' )
    else :
        error ( filename , linenum , 'build/namespaces' , 5 , 'Do not use namespace using-directives.  ' 'Use using-declarations instead.' )
# Detect variable - length arrays .
match = Match ( r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];' , line )
if ( match and match . group ( 2 ) != 'return' and match . group ( 2 ) != 'delete' and match . group ( 3 ) . find ( ']' ) == - 1 ) : # Split the size using space and arithmetic operators as delimiters .
# If any of the resulting tokens are not compile time constants then
# report the error .
    tokens = re . split ( r'\s|\+|\-|\*|\/|<<|>>]' , match . group ( 3 ) )
    is_const = True
    skip_next = False
    for tok in tokens :
        if skip_next :
            skip_next = False
            continue
        if Search ( r'sizeof\(.+\)' , tok ) :
            continue
        if Search ( r'arraysize\(\w+\)' , tok ) :
            continue
        tok = tok . lstrip ( '(' )
        tok = tok . rstrip ( ')' )
        if not tok :
            continue
        if Match ( r'\d+' , tok ) :
            continue
        if Match ( r'0[xX][0-9a-fA-F]+' , tok ) :
            continue
        if Match ( r'k[A-Z0-9]\w*' , tok ) :
            continue
        if Match ( r'(.+::)?k[A-Z0-9]\w*' , tok ) :
            continue
        if Match ( r'(.+::)?[A-Z][A-Z0-9_]*' , tok ) :
            continue
        # A catch all for tricky sizeof cases , including ' sizeof expression ' ,
        # ' sizeof ( * type ) ' , ' sizeof ( const type ) ' , ' sizeof ( struct StructName ) '
        # requires skipping the next token because we split on ' ' and ' * ' .
        if tok . startswith ( 'sizeof' ) :
            skip_next = True
            continue
        is_const = False
        break
    if not is_const :
        error ( filename , linenum , 'runtime/arrays' , 1 , 'Do not use variable-length arrays.  Use an appropriately named ' "('k' followed by CamelCase) compile-time constant for the size." )
# Check for use of unnamed namespaces in header files . Registration
# macros are typically OK , so we allow use of " namespace { " on lines
# that end with backslashes .
if ( file_extension in GetHeaderExtensions ( ) and Search ( r'\bnamespace\s*{' , line ) and line [ - 1 ] != '\\' ) :
    error ( filename , linenum , 'build/namespaces' , 4 , 'Do not use unnamed namespaces in header files.  See ' 'https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' ' for more information.' )


signature:
def CheckGlobalStatic ( filename , clean_lines , linenum , error ) :
    """Check for unsafe global or static objects .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
line = clean_lines . elided [ linenum ]
# Match two lines at a time to support multiline declarations
if linenum + 1 < clean_lines . NumLines ( ) and not Search ( r'[;({]' , line ) :
    line += clean_lines . elided [ linenum + 1 ] . strip ( )
# Check for people declaring static / global STL strings at the top level .
# This is dangerous because the C + + language does not guarantee that
# globals with constructors are initialized before the first access , and
# also because globals can be destroyed when some threads are still running .
# TODO ( unknown ) : Generalize this to also find static unique _ ptr instances .
# TODO ( unknown ) : File bugs for clang - tidy to find these .
match = Match ( r'((?:|static +)(?:|const +))(?::*std::)?string( +const)? +' r'([a-zA-Z0-9_:]+)\b(.*)' , line )
# Remove false positives :
# - String pointers ( as opposed to values ) .
# string * pointer
# const string * pointer
# string const * pointer
# string * const pointer
# - Functions and template specializations .
# string Function < Type > ( . . .
# string Class < Type > : : Method ( . . .
# - Operators . These are matched separately because operator names
# cross non - word boundaries , and trying to match both operators
# and functions at the same time would decrease accuracy of
# matching identifiers .
# string Class : : operator * ( )
if ( match and not Search ( r'\bstring\b(\s+const)?\s*[\*\&]\s*(const\s+)?\w' , line ) and not Search ( r'\boperator\W' , line ) and not Match ( r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)' , match . group ( 4 ) ) ) :
    if Search ( r'\bconst\b' , line ) :
        error ( filename , linenum , 'runtime/string' , 4 , 'For a static/global string constant, use a C style string ' 'instead: "%schar%s %s[]".' % ( match . group ( 1 ) , match . group ( 2 ) or '' , match . group ( 3 ) ) )
    else :
        error ( filename , linenum , 'runtime/string' , 4 , 'Static/global string variables are not permitted.' )
if ( Search ( r'\b([A-Za-z0-9_]*_)\(\1\)' , line ) or Search ( r'\b([A-Za-z0-9_]*_)\(CHECK_NOTNULL\(\1\)\)' , line ) ) :
    error ( filename , linenum , 'runtime/init' , 4 , 'You seem to be initializing a member variable with itself.' )


signature:
def CheckPrintf ( filename , clean_lines , linenum , error ) :
    """Check for printf related issues .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
line = clean_lines . elided [ linenum ]
# When snprintf is used , the second argument shouldn ' t be a literal .
match = Search ( r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,' , line )
if match and match . group ( 2 ) != '0' : # If 2nd arg is zero , snprintf is used to calculate size .
    error ( filename , linenum , 'runtime/printf' , 3 , 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' 'to snprintf.' % ( match . group ( 1 ) , match . group ( 2 ) ) )
# Check if some verboten C functions are being used .
if Search ( r'\bsprintf\s*\(' , line ) :
    error ( filename , linenum , 'runtime/printf' , 5 , 'Never use sprintf. Use snprintf instead.' )
match = Search ( r'\b(strcpy|strcat)\s*\(' , line )
if match :
    error ( filename , linenum , 'runtime/printf' , 4 , 'Almost always, snprintf is better than %s' % match . group ( 1 ) )


signature:
def IsDerivedFunction ( clean_lines , linenum ) :
    """Check if current line contains an inherited function .
 Args :
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 Returns :
 True if current line contains a function with " override "
 virt - specifier ."""

implementation:
# Scan back a few lines for start of current function
for i in xrange ( linenum , max ( - 1 , linenum - 10 ) , - 1 ) :
    match = Match ( r'^([^()]*\w+)\(' , clean_lines . elided [ i ] )
    if match : # Look for " override " after the matching closing parenthesis
        line , _ , closing_paren = CloseExpression ( clean_lines , i , len ( match . group ( 1 ) ) )
        return ( closing_paren >= 0 and Search ( r'\boverride\b' , line [ closing_paren : ] ) )
return False


signature:
def IsOutOfLineMethodDefinition ( clean_lines , linenum ) :
    """Check if current line contains an out - of - line method definition .
 Args :
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 Returns :
 True if current line contains an out - of - line method definition ."""

implementation:
# Scan back a few lines for start of current function
for i in xrange ( linenum , max ( - 1 , linenum - 10 ) , - 1 ) :
    if Match ( r'^([^()]*\w+)\(' , clean_lines . elided [ i ] ) :
        return Match ( r'^[^()]*\w+::\w+\(' , clean_lines . elided [ i ] ) is not None
return False


signature:
def IsInitializerList ( clean_lines , linenum ) :
    """Check if current line is inside constructor initializer list .
 Args :
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 Returns :
 True if current line appears to be inside constructor initializer
 list , False otherwise ."""

implementation:
for i in xrange ( linenum , 1 , - 1 ) :
    line = clean_lines . elided [ i ]
    if i == linenum :
        remove_function_body = Match ( r'^(.*)\{\s*$' , line )
        if remove_function_body :
            line = remove_function_body . group ( 1 )
    if Search ( r'\s:\s*\w+[({]' , line ) : # A lone colon tend to indicate the start of a constructor
    # initializer list . It could also be a ternary operator , which
    # also tend to appear in constructor initializer lists as
    # opposed to parameter lists .
        return True
    if Search ( r'\}\s*,\s*$' , line ) : # A closing brace followed by a comma is probably the end of a
    # brace - initialized member in constructor initializer list .
        return True
    if Search ( r'[{};]\s*$' , line ) : # Found one of the following :
    # - A closing brace or semicolon , probably the end of the previous
    # function .
    # - An opening brace , probably the start of current class or namespace .
    # Current line is probably not inside an initializer list since
    # we saw one of those things without seeing the starting colon .
        return False
# Got to the beginning of the file without seeing the start of
# constructor initializer list .
return False


signature:
def CheckForNonConstReference ( filename , clean_lines , linenum , nesting_state , error ) :
    """Check for non - const references .
 Separate from CheckLanguage since it scans backwards from current
 line , instead of scanning forward .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 nesting _ state : A NestingState instance which maintains information about
 the current stack of nested blocks being parsed .
 error : The function to call with any errors found ."""

implementation:
# Do nothing if there is no ' & ' on current line .
line = clean_lines . elided [ linenum ]
if '&' not in line :
    return
# If a function is inherited , current function doesn ' t have much of
# a choice , so any non - const references should not be blamed on
# derived function .
if IsDerivedFunction ( clean_lines , linenum ) :
    return
# Don ' t warn on out - of - line method definitions , as we would warn on the
# in - line declaration , if it isn ' t marked with ' override ' .
if IsOutOfLineMethodDefinition ( clean_lines , linenum ) :
    return
# Long type names may be broken across multiple lines , usually in one
# of these forms :
# LongType
# : : LongTypeContinued & identifier
# LongType : :
# LongTypeContinued & identifier
# LongType <
# . . . > : : LongTypeContinued & identifier
# If we detected a type split across two lines , join the previous
# line to current line so that we can match const references
# accordingly .
# Note that this only scans back one line , since scanning back
# arbitrary number of lines would be expensive . If you have a type
# that spans more than 2 lines , please use a typedef .
if linenum > 1 :
    previous = None
    if Match ( r'\s*::(?:[\w<>]|::)+\s*&\s*\S' , line ) : # previous _ line \ n + : : current _ line
        previous = Search ( r'\b((?:const\s*)?(?:[\w<>]|::)+[\w<>])\s*$' , clean_lines . elided [ linenum - 1 ] )
    elif Match ( r'\s*[a-zA-Z_]([\w<>]|::)+\s*&\s*\S' , line ) : # previous _ line : : \ n + current _ line
        previous = Search ( r'\b((?:const\s*)?(?:[\w<>]|::)+::)\s*$' , clean_lines . elided [ linenum - 1 ] )
    if previous :
        line = previous . group ( 1 ) + line . lstrip ( )
    else : # Check for templated parameter that is split across multiple lines
        endpos = line . rfind ( '>' )
        if endpos > - 1 :
            ( _ , startline , startpos ) = ReverseCloseExpression ( clean_lines , linenum , endpos )
            if startpos > - 1 and startline < linenum : # Found the matching < on an earlier line , collect all
            # pieces up to current line .
                line = ''
                for i in xrange ( startline , linenum + 1 ) :
                    line += clean_lines . elided [ i ] . strip ( )
# Check for non - const references in function parameters . A single ' & ' may
# found in the following places :
# inside expression : binary & for bitwise AND
# inside expression : unary & for taking the address of something
# inside declarators : reference parameter
# We will exclude the first two cases by checking that we are not inside a
# function body , including one that was just introduced by a trailing ' { ' .
# TODO ( unknown ) : Doesn ' t account for ' catch ( Exception & e ) ' [ rare ] .
if ( nesting_state . previous_stack_top and not ( isinstance ( nesting_state . previous_stack_top , _ClassInfo ) or isinstance ( nesting_state . previous_stack_top , _NamespaceInfo ) ) ) : # Not at toplevel , not within a class , and not within a namespace
    return
# Avoid initializer lists . We only need to scan back from the
# current line for something that starts with ' : ' .
# We don ' t need to check the current line , since the ' & ' would
# appear inside the second set of parentheses on the current line as
# opposed to the first set .
if linenum > 0 :
    for i in xrange ( linenum - 1 , max ( 0 , linenum - 10 ) , - 1 ) :
        previous_line = clean_lines . elided [ i ]
        if not Search ( r'[),]\s*$' , previous_line ) :
            break
        if Match ( r'^\s*:\s+\S' , previous_line ) :
            return
# Avoid preprocessors
if Search ( r'\\\s*$' , line ) :
    return
# Avoid constructor initializer lists
if IsInitializerList ( clean_lines , linenum ) :
    return
# We allow non - const references in a few standard places , like functions
# called " swap ( ) " or iostream operators like " < < " or " > > " . Do not check
# those function parameters .
# We also accept & in static _ assert , which looks like a function but
# it ' s actually a declaration expression .
whitelisted_functions = ( r'(?:[sS]wap(?:<\w:+>)?|' r'operator\s*[<>][<>]|' r'static_assert|COMPILE_ASSERT' r')\s*\(' )
if Search ( whitelisted_functions , line ) :
    return
elif not Search ( r'\S+\([^)]*$' , line ) : # Don ' t see a whitelisted function on this line . Actually we
# didn ' t see any function name on this line , so this is likely a
# multi - line parameter list . Try a bit harder to catch this case .
    for i in xrange ( 2 ) :
        if ( linenum > i and Search ( whitelisted_functions , clean_lines . elided [ linenum - i - 1 ] ) ) :
            return
decls = ReplaceAll ( r'{[^}]*}' , ' ' , line )
# exclude function body
for parameter in re . findall ( _RE_PATTERN_REF_PARAM , decls ) :
    if ( not Match ( _RE_PATTERN_CONST_REF_PARAM , parameter ) and not Match ( _RE_PATTERN_REF_STREAM_PARAM , parameter ) ) :
        error ( filename , linenum , 'runtime/references' , 2 , 'Is this a non-const reference? ' 'If so, make const or use a pointer: ' + ReplaceAll ( ' *<' , '<' , parameter ) )


signature:
def CheckCasts ( filename , clean_lines , linenum , error ) :
    """Various cast related checks .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
line = clean_lines . elided [ linenum ]
# Check to see if they ' re using an conversion function cast .
# I just try to capture the most common basic types , though there are more .
# Parameterless conversion functions , such as bool ( ) , are allowed as they are
# probably a member operator declaration or default constructor .
match = Search ( r'(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b' r'(int|float|double|bool|char|int32|uint32|int64|uint64)' r'(\([^)].*)' , line )
expecting_function = ExpectingFunctionArgs ( clean_lines , linenum )
if match and not expecting_function :
    matched_type = match . group ( 2 )
    # matched _ new _ or _ template is used to silence two false positives :
    # - New operators
    # - Template arguments with function types
    # For template arguments , we match on types immediately following
    # an opening bracket without any spaces . This is a fast way to
    # silence the common case where the function type is the first
    # template argument . False negative with less - than comparison is
    # avoided because those operators are usually followed by a space .
    # function < double ( double ) > / / bracket + no space = false positive
    # value < double ( 42 ) / / bracket + space = true positive
    matched_new_or_template = match . group ( 1 )
    # Avoid arrays by looking for brackets that come after the closing
    # parenthesis .
    if Match ( r'\([^()]+\)\s*\[' , match . group ( 3 ) ) :
        return
    # Other things to ignore :
    # - Function pointers
    # - Casts to pointer types
    # - Placement new
    # - Alias declarations
    matched_funcptr = match . group ( 3 )
    if ( matched_new_or_template is None and not ( matched_funcptr and ( Match ( r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(' , matched_funcptr ) or matched_funcptr . startswith ( '(*)' ) ) ) and not Match ( r'\s*using\s+\S+\s*=\s*' + matched_type , line ) and not Search ( r'new\(\S+\)\s*' + matched_type , line ) ) :
        error ( filename , linenum , 'readability/casting' , 4 , 'Using deprecated casting style.  ' 'Use static_cast<%s>(...) instead' % matched_type )
if not expecting_function :
    CheckCStyleCast ( filename , clean_lines , linenum , 'static_cast' , r'\((int|float|double|bool|char|u?int(16|32|64))\)' , error )
# This doesn ' t catch all cases . Consider ( const char * const ) " hello " .
# ( char * ) " foo " should always be a const _ cast ( reinterpret _ cast won ' t
# compile ) .
if CheckCStyleCast ( filename , clean_lines , linenum , 'const_cast' , r'\((char\s?\*+\s?)\)\s*"' , error ) :
    pass
else : # Check pointer casts for other than string constants
    CheckCStyleCast ( filename , clean_lines , linenum , 'reinterpret_cast' , r'\((\w+\s?\*+\s?)\)' , error )
# In addition , we look for people taking the address of a cast . This
# is dangerous - - casts can assign to temporaries , so the pointer doesn ' t
# point where you think .
# Some non - identifier character is required before the ' & ' for the
# expression to be recognized as a cast . These are casts :
# expression = & static _ cast < int * > ( temporary ( ) ) ;
# function ( & ( int * ) ( temporary ( ) ) ) ;
# This is not a cast :
# reference _ type & ( int * function _ param ) ;
match = Search ( r'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|' r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)' , line )
if match : # Try a better error message when the & is bound to something
# dereferenced by the casted pointer , as opposed to the casted
# pointer itself .
    parenthesis_error = False
    match = Match ( r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<' , line )
    if match :
        _ , y1 , x1 = CloseExpression ( clean_lines , linenum , len ( match . group ( 1 ) ) )
        if x1 >= 0 and clean_lines . elided [ y1 ] [ x1 ] == '(' :
            _ , y2 , x2 = CloseExpression ( clean_lines , y1 , x1 )
            if x2 >= 0 :
                extended_line = clean_lines . elided [ y2 ] [ x2 : ]
                if y2 < clean_lines . NumLines ( ) - 1 :
                    extended_line += clean_lines . elided [ y2 + 1 ]
                if Match ( r'\s*(?:->|\[)' , extended_line ) :
                    parenthesis_error = True
    if parenthesis_error :
        error ( filename , linenum , 'readability/casting' , 4 , ( 'Are you taking an address of something dereferenced ' 'from a cast?  Wrapping the dereferenced expression in ' 'parentheses will make the binding more obvious' ) )
    else :
        error ( filename , linenum , 'runtime/casting' , 4 , ( 'Are you taking an address of a cast?  ' 'This is dangerous: could be a temp var.  ' 'Take the address before doing the cast, rather than after' ) )


signature:
def CheckCStyleCast ( filename , clean_lines , linenum , cast_type , pattern , error ) :
    """Checks for a C - style cast by looking for the pattern .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 cast _ type : The string for the C + + cast to recommend . This is either
 reinterpret _ cast , static _ cast , or const _ cast , depending .
 pattern : The regular expression used to find C - style casts .
 error : The function to call with any errors found .
 Returns :
 True if an error was emitted .
 False otherwise ."""

implementation:
line = clean_lines . elided [ linenum ]
match = Search ( pattern , line )
if not match :
    return False
# Exclude lines with keywords that tend to look like casts
context = line [ 0 : match . start ( 1 ) - 1 ]
if Match ( r'.*\b(?:sizeof|alignof|alignas|[_A-Z][_A-Z0-9]*)\s*$' , context ) :
    return False
# Try expanding current context to see if we one level of
# parentheses inside a macro .
if linenum > 0 :
    for i in xrange ( linenum - 1 , max ( 0 , linenum - 5 ) , - 1 ) :
        context = clean_lines . elided [ i ] + context
if Match ( r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$' , context ) :
    return False
# operator + + ( int ) and operator - - ( int )
if context . endswith ( ' operator++' ) or context . endswith ( ' operator--' ) :
    return False
# A single unnamed argument for a function tends to look like old style cast .
# If we see those , don ' t issue warnings for deprecated casts .
remainder = line [ match . end ( 0 ) : ]
if Match ( r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)' , remainder ) :
    return False
# At this point , all that should be left is actual casts .
error ( filename , linenum , 'readability/casting' , 4 , 'Using C-style cast.  Use %s<%s>(...) instead' % ( cast_type , match . group ( 1 ) ) )
return True


signature:
def ExpectingFunctionArgs ( clean_lines , linenum ) :
    """Checks whether where function type arguments are expected .
 Args :
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 Returns :
 True if the line at ' linenum ' is inside something that expects arguments
 of function types ."""

implementation:
line = clean_lines . elided [ linenum ]
return ( Match ( r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(' , line ) or ( linenum >= 2 and ( Match ( r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$' , clean_lines . elided [ linenum - 1 ] ) or Match ( r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$' , clean_lines . elided [ linenum - 2 ] ) or Search ( r'\bstd::m?function\s*\<\s*$' , clean_lines . elided [ linenum - 1 ] ) ) ) )


signature:
def FilesBelongToSameModule ( filename_cc , filename_h ) :
    """Check if these two filenames belong to the same module .
 The concept of a ' module ' here is a as follows :
 foo . h , foo - inl . h , foo . cc , foo _ test . cc and foo _ unittest . cc belong to the
 same ' module ' if they are in the same directory .
 some / path / public / xyzzy and some / path / internal / xyzzy are also considered
 to belong to the same module here .
 If the filename _ cc contains a longer path than the filename _ h , for example ,
 ' / absolute / path / to / base / sysinfo . cc ' , and this file would include
 ' base / sysinfo . h ' , this function also produces the prefix needed to open the
 header . This is used by the caller of this function to more robustly open the
 header file . We don ' t have access to the real include paths in this context ,
 so we need this guesswork here .
 Known bugs : tools / base / bar . cc and base / bar . h belong to the same module
 according to this implementation . Because of this , this function gives
 some false positives . This should be sufficiently rare in practice .
 Args :
 filename _ cc : is the path for the source ( e . g . . cc ) file
 filename _ h : is the path for the header path
 Returns :
 Tuple with a bool and a string :
 bool : True if filename _ cc and filename _ h belong to the same module .
 string : the additional prefix needed to open the header file ."""

implementation:
fileinfo_cc = FileInfo ( filename_cc )
if not fileinfo_cc . Extension ( ) . lstrip ( '.' ) in GetNonHeaderExtensions ( ) :
    return ( False , '' )
fileinfo_h = FileInfo ( filename_h )
if not fileinfo_h . Extension ( ) . lstrip ( '.' ) in GetHeaderExtensions ( ) :
    return ( False , '' )
filename_cc = filename_cc [ : - ( len ( fileinfo_cc . Extension ( ) ) ) ]
matched_test_suffix = Search ( _TEST_FILE_SUFFIX , fileinfo_cc . BaseName ( ) )
if matched_test_suffix :
    filename_cc = filename_cc [ : - len ( matched_test_suffix . group ( 1 ) ) ]
filename_cc = filename_cc . replace ( '/public/' , '/' )
filename_cc = filename_cc . replace ( '/internal/' , '/' )
filename_h = filename_h [ : - ( len ( fileinfo_h . Extension ( ) ) ) ]
if filename_h . endswith ( '-inl' ) :
    filename_h = filename_h [ : - len ( '-inl' ) ]
filename_h = filename_h . replace ( '/public/' , '/' )
filename_h = filename_h . replace ( '/internal/' , '/' )
files_belong_to_same_module = filename_cc . endswith ( filename_h )
common_path = ''
if files_belong_to_same_module :
    common_path = filename_cc [ : - len ( filename_h ) ]
return files_belong_to_same_module , common_path


signature:
def UpdateIncludeState ( filename , include_dict , io = codecs ) :
    """Fill up the include _ dict with new includes found from the file .
 Args :
 filename : the name of the header to read .
 include _ dict : a dictionary in which the headers are inserted .
 io : The io factory to use to read the file . Provided for testability .
 Returns :
 True if a header was successfully added . False otherwise ."""

implementation:
headerfile = None
try :
    headerfile = io . open ( filename , 'r' , 'utf8' , 'replace' )
except IOError :
    return False
linenum = 0
for line in headerfile :
    linenum += 1
    clean_line = CleanseComments ( line )
    match = _RE_PATTERN_INCLUDE . search ( clean_line )
    if match :
        include = match . group ( 2 )
        include_dict . setdefault ( include , linenum )
return True


signature:
def CheckMakePairUsesDeduction ( filename , clean_lines , linenum , error ) :
    """Check that make _ pair ' s template arguments are deduced .
 G + + 4.6 in C + + 11 mode fails badly if make _ pair ' s template arguments are
 specified explicitly , and such use isn ' t intended in any case .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
line = clean_lines . elided [ linenum ]
match = _RE_PATTERN_EXPLICIT_MAKEPAIR . search ( line )
if match :
    error ( filename , linenum , 'build/explicit_make_pair' , 4 , # 4 = high confidence
    'For C++11-compatibility, omit template arguments from make_pair' ' OR use pair directly OR if appropriate, construct a pair directly' )


signature:
def CheckRedundantVirtual ( filename , clean_lines , linenum , error ) :
    """Check if line contains a redundant " virtual " function - specifier .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
# Look for " virtual " on current line .
line = clean_lines . elided [ linenum ]
virtual = Match ( r'^(.*)(\bvirtual\b)(.*)$' , line )
if not virtual :
    return
# Ignore " virtual " keywords that are near access - specifiers . These
# are only used in class base - specifier and do not apply to member
# functions .
if ( Search ( r'\b(public|protected|private)\s+$' , virtual . group ( 1 ) ) or Match ( r'^\s+(public|protected|private)\b' , virtual . group ( 3 ) ) ) :
    return
# Ignore the " virtual " keyword from virtual base classes . Usually
# there is a column on the same line in these cases ( virtual base
# classes are rare in google3 because multiple inheritance is rare ) .
if Match ( r'^.*[^:]:[^:].*$' , line ) :
    return
# Look for the next opening parenthesis . This is the start of the
# parameter list ( possibly on the next line shortly after virtual ) .
# TODO ( unknown ) : doesn ' t work if there are virtual functions with
# decltype ( ) or other things that use parentheses , but csearch suggests
# that this is rare .
end_col = - 1
end_line = - 1
start_col = len ( virtual . group ( 2 ) )
for start_line in xrange ( linenum , min ( linenum + 3 , clean_lines . NumLines ( ) ) ) :
    line = clean_lines . elided [ start_line ] [ start_col : ]
    parameter_list = Match ( r'^([^(]*)\(' , line )
    if parameter_list : # Match parentheses to find the end of the parameter list
        ( _ , end_line , end_col ) = CloseExpression ( clean_lines , start_line , start_col + len ( parameter_list . group ( 1 ) ) )
        break
    start_col = 0
if end_col < 0 :
    return
# Couldn ' t find end of parameter list , give up
# Look for " override " or " final " after the parameter list
# ( possibly on the next few lines ) .
for i in xrange ( end_line , min ( end_line + 3 , clean_lines . NumLines ( ) ) ) :
    line = clean_lines . elided [ i ] [ end_col : ]
    match = Search ( r'\b(override|final)\b' , line )
    if match :
        error ( filename , linenum , 'readability/inheritance' , 4 , ( '"virtual" is redundant since function is ' 'already declared as "%s"' % match . group ( 1 ) ) )
    # Set end _ col to check whole lines after we are done with the
    # first line .
    end_col = 0
    if Search ( r'[^\w]\s*$' , line ) :
        break


signature:
def CheckRedundantOverrideOrFinal ( filename , clean_lines , linenum , error ) :
    """Check if line contains a redundant " override " or " final " virt - specifier .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
# Look for closing parenthesis nearby . We need one to confirm where
# the declarator ends and where the virt - specifier starts to avoid
# false positives .
line = clean_lines . elided [ linenum ]
declarator_end = line . rfind ( ')' )
if declarator_end >= 0 :
    fragment = line [ declarator_end : ]
else :
    if linenum > 1 and clean_lines . elided [ linenum - 1 ] . rfind ( ')' ) >= 0 :
        fragment = line
    else :
        return
# Check that at most one of " override " or " final " is present , not both
if Search ( r'\boverride\b' , fragment ) and Search ( r'\bfinal\b' , fragment ) :
    error ( filename , linenum , 'readability/inheritance' , 4 , ( '"override" is redundant since function is ' 'already declared as "final"' ) )


signature:
def IsBlockInNameSpace ( nesting_state , is_forward_declaration ) :
    """Checks that the new block is directly in a namespace .
 Args :
 nesting _ state : The _ NestingState object that contains info about our state .
 is _ forward _ declaration : If the class is a forward declared class .
 Returns :
 Whether or not the new block is directly in a namespace ."""

implementation:
if is_forward_declaration :
    return len ( nesting_state . stack ) >= 1 and ( isinstance ( nesting_state . stack [ - 1 ] , _NamespaceInfo ) )
return ( len ( nesting_state . stack ) > 1 and nesting_state . stack [ - 1 ] . check_namespace_indentation and isinstance ( nesting_state . stack [ - 2 ] , _NamespaceInfo ) )


signature:
def ShouldCheckNamespaceIndentation ( nesting_state , is_namespace_indent_item , raw_lines_no_comments , linenum ) :
    """This method determines if we should apply our namespace indentation check .
 Args :
 nesting _ state : The current nesting state .
 is _ namespace _ indent _ item : If we just put a new class on the stack , True .
 If the top of the stack is not a class , or we did not recently
 add the class , False .
 raw _ lines _ no _ comments : The lines without the comments .
 linenum : The current line number we are processing .
 Returns :
 True if we should apply our namespace indentation check . Currently , it
 only works for classes and namespaces inside of a namespace ."""

implementation:
is_forward_declaration = IsForwardClassDeclaration ( raw_lines_no_comments , linenum )
if not ( is_namespace_indent_item or is_forward_declaration ) :
    return False
# If we are in a macro , we do not want to check the namespace indentation .
if IsMacroDefinition ( raw_lines_no_comments , linenum ) :
    return False
return IsBlockInNameSpace ( nesting_state , is_forward_declaration )


signature:
def FlagCxx14Features ( filename , clean_lines , linenum , error ) :
    """Flag those C + + 14 features that we restrict .
 Args :
 filename : The name of the current file .
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 error : The function to call with any errors found ."""

implementation:
line = clean_lines . elided [ linenum ]
include = Match ( r'\s*#\s*include\s+[<"]([^<"]+)[">]' , line )
# Flag unapproved C + + 14 headers .
if include and include . group ( 1 ) in ( 'scoped_allocator' , 'shared_mutex' ) :
    error ( filename , linenum , 'build/c++14' , 5 , ( '<%s> is an unapproved C++14 header.' ) % include . group ( 1 ) )


signature:
def ProcessFileData ( filename , file_extension , lines , error , extra_check_functions = None ) :
    """Performs lint checks and reports any errors to the given error function .
 Args :
 filename : Filename of the file that is being processed .
 file _ extension : The extension ( dot not included ) of the file .
 lines : An array of strings , each representing a line of the file , with the
 last element being empty if the file is terminated with a newline .
 error : A callable to which errors are reported , which takes 4 arguments :
 filename , line number , error level , and message
 extra _ check _ functions : An array of additional check functions that will be
 run on each source line . Each function takes 4
 arguments : filename , clean _ lines , line , error"""

implementation:
lines = ( [ '// marker so line numbers and indices both start at 1' ] + lines + [ '// marker so line numbers end in a known way' ] )
include_state = _IncludeState ( )
function_state = _FunctionState ( )
nesting_state = NestingState ( )
ResetNolintSuppressions ( )
CheckForCopyright ( filename , lines , error )
ProcessGlobalSuppresions ( lines )
RemoveMultiLineComments ( filename , lines , error )
clean_lines = CleansedLines ( lines )
if file_extension in GetHeaderExtensions ( ) :
    CheckForHeaderGuard ( filename , clean_lines , error )
for line in range ( clean_lines . NumLines ( ) ) :
    ProcessLine ( filename , file_extension , clean_lines , line , include_state , function_state , nesting_state , error , extra_check_functions )
    FlagCxx11Features ( filename , clean_lines , line , error )
nesting_state . CheckCompletedBlocks ( filename , error )
CheckForIncludeWhatYouUse ( filename , clean_lines , include_state , error )
# Check that the . cc file has included its header if it exists .
if _IsSourceExtension ( file_extension ) :
    CheckHeaderFileIncluded ( filename , include_state , error )
# We check here rather than inside ProcessLine so that we see raw
# lines rather than " cleaned " lines .
CheckForBadCharacters ( filename , lines , error )
CheckForNewlineAtEOF ( filename , lines , error )


signature:
def ProcessConfigOverrides ( filename ) :
    """Loads the configuration files and processes the config overrides .
 Args :
 filename : The name of the file being processed by the linter .
 Returns :
 False if the current | filename | should not be processed further ."""

implementation:
abs_filename = os . path . abspath ( filename )
cfg_filters = [ ]
keep_looking = True
while keep_looking :
    abs_path , base_name = os . path . split ( abs_filename )
    if not base_name :
        break
    # Reached the root directory .
    cfg_file = os . path . join ( abs_path , "CPPLINT.cfg" )
    abs_filename = abs_path
    if not os . path . isfile ( cfg_file ) :
        continue
    try :
        with open ( cfg_file ) as file_handle :
            for line in file_handle :
                line , _ , _ = line . partition ( '#' )
                # Remove comments .
                if not line . strip ( ) :
                    continue
                name , _ , val = line . partition ( '=' )
                name = name . strip ( )
                val = val . strip ( )
                if name == 'set noparent' :
                    keep_looking = False
                elif name == 'filter' :
                    cfg_filters . append ( val )
                elif name == 'exclude_files' : # When matching exclude _ files pattern , use the base _ name of
                # the current file name or the directory name we are processing .
                # For example , if we are checking for lint errors in / foo / bar / baz . cc
                # and we found the . cfg file at / foo / CPPLINT . cfg , then the config
                # file ' s " exclude _ files " filter is meant to be checked against " bar "
                # and not " baz " nor " bar / baz . cc " .
                    if base_name :
                        pattern = re . compile ( val )
                        if pattern . match ( base_name ) :
                            _cpplint_state . PrintInfo ( 'Ignoring "%s": file excluded by ' '"%s". File path component "%s" matches pattern "%s"\n' % ( filename , cfg_file , base_name , val ) )
                            return False
                elif name == 'linelength' :
                    global _line_length
                    try :
                        _line_length = int ( val )
                    except ValueError :
                        _cpplint_state . PrintError ( 'Line length must be numeric.' )
                elif name == 'extensions' :
                    global _valid_extensions
                    try :
                        extensions = [ ext . strip ( ) for ext in val . split ( ',' ) ]
                        _valid_extensions = set ( extensions )
                    except ValueError :
                        sys . stderr . write ( 'Extensions should be a comma-separated list of values;' 'for example: extensions=hpp,cpp\n' 'This could not be parsed: "%s"' % ( val , ) )
                elif name == 'headers' :
                    global _header_extensions
                    try :
                        extensions = [ ext . strip ( ) for ext in val . split ( ',' ) ]
                        _header_extensions = set ( extensions )
                    except ValueError :
                        sys . stderr . write ( 'Extensions should be a comma-separated list of values;' 'for example: extensions=hpp,cpp\n' 'This could not be parsed: "%s"' % ( val , ) )
                elif name == 'root' :
                    global _root
                    _root = val
                else :
                    _cpplint_state . PrintError ( 'Invalid configuration option (%s) in file %s\n' % ( name , cfg_file ) )
    except IOError :
        _cpplint_state . PrintError ( "Skipping config file '%s': Can't open for reading\n" % cfg_file )
        keep_looking = False
# Apply all the accumulated filters in reverse order ( top - level directory
# config options having the least priority ) .
for cfg_filter in reversed ( cfg_filters ) :
    _AddFilters ( cfg_filter )
return True


signature:
def ProcessFile ( filename , vlevel , extra_check_functions = None ) :
    """Does google - lint on a single file .
 Args :
 filename : The name of the file to parse .
 vlevel : The level of errors to report . Every error of confidence
 > = verbose _ level will be reported . 0 is a good default .
 extra _ check _ functions : An array of additional check functions that will be
 run on each source line . Each function takes 4
 arguments : filename , clean _ lines , line , error"""

implementation:
_SetVerboseLevel ( vlevel )
_BackupFilters ( )
if not ProcessConfigOverrides ( filename ) :
    _RestoreFilters ( )
    return
lf_lines = [ ]
crlf_lines = [ ]
try : # Support the UNIX convention of using " - " for stdin . Note that
# we are not opening the file with universal newline support
# ( which codecs doesn ' t support anyway ) , so the resulting lines do
# contain trailing ' \ r ' characters if we are reading a file that
# has CRLF endings .
# If after the split a trailing ' \ r ' is present , it is removed
# below .
    if filename == '-' :
        lines = codecs . StreamReaderWriter ( sys . stdin , codecs . getreader ( 'utf8' ) , codecs . getwriter ( 'utf8' ) , 'replace' ) . read ( ) . split ( '\n' )
    else :
        lines = codecs . open ( filename , 'r' , 'utf8' , 'replace' ) . read ( ) . split ( '\n' )
    # Remove trailing ' \ r ' .
    # The - 1 accounts for the extra trailing blank line we get from split ( )
    for linenum in range ( len ( lines ) - 1 ) :
        if lines [ linenum ] . endswith ( '\r' ) :
            lines [ linenum ] = lines [ linenum ] . rstrip ( '\r' )
            crlf_lines . append ( linenum + 1 )
        else :
            lf_lines . append ( linenum + 1 )
except IOError :
    _cpplint_state . PrintError ( "Skipping input '%s': Can't open for reading\n" % filename )
    _RestoreFilters ( )
    return
# Note , if no dot is found , this will give the entire filename as the ext .
file_extension = filename [ filename . rfind ( '.' ) + 1 : ]
# When reading from stdin , the extension is unknown , so no cpplint tests
# should rely on the extension .
if filename != '-' and file_extension not in GetAllExtensions ( ) : # bazel 0.5.1 > uses four distinct generated files that gives a warning
# we suppress the warning for these files
    bazel_gen_files = set ( [ "external/local_config_cc/libtool" , "external/local_config_cc/make_hashed_objlist.py" , "external/local_config_cc/wrapped_ar" , "external/local_config_cc/wrapped_clang" , "external/local_config_cc/xcrunwrapper.sh" , ] )
    if not filename in bazel_gen_files :
        _cpplint_state . PrintError ( 'Ignoring %s; not a valid file name ' '(%s)\n' % ( filename , ', ' . join ( GetAllExtensions ( ) ) ) )
else :
    ProcessFileData ( filename , file_extension , lines , Error , extra_check_functions )
    # If end - of - line sequences are a mix of LF and CR - LF , issue
    # warnings on the lines with CR .
    # Don ' t issue any warnings if all lines are uniformly LF or CR - LF ,
    # since critique can handle these just fine , and the style guide
    # doesn ' t dictate a particular end of line sequence .
    # We can ' t depend on os . linesep to determine what the desired
    # end - of - line sequence should be , since that will return the
    # server - side end - of - line sequence .
    if lf_lines and crlf_lines : # Warn on every line with CR . An alternative approach might be to
    # check whether the file is mostly CRLF or just LF , and warn on the
    # minority , we bias toward LF here since most tools prefer LF .
        for linenum in crlf_lines :
            Error ( filename , linenum , 'whitespace/newline' , 1 , 'Unexpected \\r (^M) found; better to use only \\n' )
_RestoreFilters ( )


signature:
def PrintCategories ( ) :
    """Prints a list of all the error - categories used by error messages .
 These are the categories used to filter messages via - - filter ."""

implementation:
sys . stderr . write ( '' . join ( '  %s\n' % cat for cat in _ERROR_CATEGORIES ) )
sys . exit ( 0 )


signature:
def ParseArguments ( args ) :
    """Parses the command line arguments .
 This may set the output format and verbosity level as side - effects .
 Args :
 args : The command line arguments :
 Returns :
 The list of filenames to lint ."""

implementation:
try :
    ( opts , filenames ) = getopt . getopt ( args , '' , [ 'help' , 'output=' , 'verbose=' , 'counting=' , 'filter=' , 'root=' , 'repository=' , 'linelength=' , 'extensions=' , 'exclude=' , 'headers=' , 'quiet' , 'recursive' ] )
except getopt . GetoptError :
    PrintUsage ( 'Invalid arguments.' )
verbosity = _VerboseLevel ( )
output_format = _OutputFormat ( )
filters = ''
counting_style = ''
recursive = False
for ( opt , val ) in opts :
    if opt == '--help' :
        PrintUsage ( None )
    elif opt == '--output' :
        if val not in ( 'emacs' , 'vs7' , 'eclipse' , 'junit' ) :
            PrintUsage ( 'The only allowed output formats are emacs, vs7, eclipse ' 'and junit.' )
        output_format = val
    elif opt == '--verbose' :
        verbosity = int ( val )
    elif opt == '--filter' :
        filters = val
        if not filters :
            PrintCategories ( )
    elif opt == '--counting' :
        if val not in ( 'total' , 'toplevel' , 'detailed' ) :
            PrintUsage ( 'Valid counting options are total, toplevel, and detailed' )
        counting_style = val
    elif opt == '--root' :
        global _root
        _root = val
    elif opt == '--repository' :
        global _repository
        _repository = val
    elif opt == '--linelength' :
        global _line_length
        try :
            _line_length = int ( val )
        except ValueError :
            PrintUsage ( 'Line length must be digits.' )
    elif opt == '--exclude' :
        global _excludes
        if not _excludes :
            _excludes = set ( )
        _excludes . update ( glob . glob ( val ) )
    elif opt == '--extensions' :
        global _valid_extensions
        try :
            _valid_extensions = set ( val . split ( ',' ) )
        except ValueError :
            PrintUsage ( 'Extensions must be comma seperated list.' )
    elif opt == '--headers' :
        global _header_extensions
        try :
            _header_extensions = set ( val . split ( ',' ) )
        except ValueError :
            PrintUsage ( 'Extensions must be comma seperated list.' )
    elif opt == '--recursive' :
        recursive = True
    elif opt == '--quiet' :
        global _quiet
        _quiet = True
if not filenames :
    PrintUsage ( 'No files were specified.' )
if recursive :
    filenames = _ExpandDirectories ( filenames )
if _excludes :
    filenames = _FilterExcludedFiles ( filenames )
_SetOutputFormat ( output_format )
_SetVerboseLevel ( verbosity )
_SetFilters ( filters )
_SetCountingStyle ( counting_style )
return filenames


signature:
def _ExpandDirectories ( filenames ) :
    """Searches a list of filenames and replaces directories in the list with
 all files descending from those directories . Files with extensions not in
 the valid extensions list are excluded .
 Args :
 filenames : A list of files or directories
 Returns :
 A list of all files that are members of filenames or descended from a
 directory in filenames"""

implementation:
expanded = set ( )
for filename in filenames :
    if not os . path . isdir ( filename ) :
        expanded . add ( filename )
        continue
    for root , _ , files in os . walk ( filename ) :
        for loopfile in files :
            fullname = os . path . join ( root , loopfile )
            if fullname . startswith ( '.' + os . path . sep ) :
                fullname = fullname [ len ( '.' + os . path . sep ) : ]
            expanded . add ( fullname )
filtered = [ ]
for filename in expanded :
    if os . path . splitext ( filename ) [ 1 ] [ 1 : ] in GetAllExtensions ( ) :
        filtered . append ( filename )
return filtered


signature:
def _FilterExcludedFiles ( filenames ) :
    """Filters out files listed in the - - exclude command line switch . File paths
 in the switch are evaluated relative to the current working directory"""

implementation:
exclude_paths = [ os . path . abspath ( f ) for f in _excludes ]
return [ f for f in filenames if os . path . abspath ( f ) not in exclude_paths ]


signature:
def FindHeader ( self , header ) :
    """Check if a header has already been included .
 Args :
 header : header to check .
 Returns :
 Line number of previous occurrence , or - 1 if the header has not
 been seen before ."""

implementation:
for section_list in self . include_list :
    for f in section_list :
        if f [ 0 ] == header :
            return f [ 1 ]
return - 1


signature:
def ResetSection ( self , directive ) :
    """Reset section checking for preprocessor directive .
 Args :
 directive : preprocessor directive ( e . g . " if " , " else " ) ."""

implementation:
# The name of the current section .
self . _section = self . _INITIAL_SECTION
# The path of last found header .
self . _last_header = ''
# Update list of includes . Note that we never pop from the
# include list .
if directive in ( 'if' , 'ifdef' , 'ifndef' ) :
    self . include_list . append ( [ ] )
elif directive in ( 'else' , 'elif' ) :
    self . include_list [ - 1 ] = [ ]


signature:
def IsInAlphabeticalOrder ( self , clean_lines , linenum , header_path ) :
    """Check if a header is in alphabetical order with the previous header .
 Args :
 clean _ lines : A CleansedLines instance containing the file .
 linenum : The number of the line to check .
 header _ path : Canonicalized header to be checked .
 Returns :
 Returns true if the header is in alphabetical order ."""

implementation:
# If previous section is different from current section , _ last _ header will
# be reset to empty string , so it ' s always less than current header .
# If previous line was a blank line , assume that the headers are
# intentionally sorted the way they are .
if ( self . _last_header > header_path and Match ( r'^\s*#\s*include\b' , clean_lines . elided [ linenum - 1 ] ) ) :
    return False
return True


signature:
def CheckNextIncludeOrder ( self , header_type ) :
    """Returns a non - empty error message if the next header is out of order .
 This function also updates the internal state to be ready to check
 the next include .
 Args :
 header _ type : One of the _ XXX _ HEADER constants defined above .
 Returns :
 The empty string if the header is in the right order , or an
 error message describing what ' s wrong ."""

implementation:
error_message = ( 'Found %s after %s' % ( self . _TYPE_NAMES [ header_type ] , self . _SECTION_NAMES [ self . _section ] ) )
last_section = self . _section
if header_type == _C_SYS_HEADER :
    if self . _section <= self . _C_SECTION :
        self . _section = self . _C_SECTION
    else :
        self . _last_header = ''
        return error_message
elif header_type == _CPP_SYS_HEADER :
    if self . _section <= self . _CPP_SECTION :
        self . _section = self . _CPP_SECTION
    else :
        self . _last_header = ''
        return error_message
elif header_type == _LIKELY_MY_HEADER :
    if self . _section <= self . _MY_H_SECTION :
        self . _section = self . _MY_H_SECTION
    else :
        self . _section = self . _OTHER_H_SECTION
elif header_type == _POSSIBLE_MY_HEADER :
    if self . _section <= self . _MY_H_SECTION :
        self . _section = self . _MY_H_SECTION
    else : # This will always be the fallback because we ' re not sure
    # enough that the header is associated with this file .
        self . _section = self . _OTHER_H_SECTION
else :
    assert header_type == _OTHER_HEADER
    self . _section = self . _OTHER_H_SECTION
if last_section != self . _section :
    self . _last_header = ''
return ''


signature:
def SetVerboseLevel ( self , level ) :
    """Sets the module ' s verbosity , and returns the previous setting ."""

implementation:
last_verbose_level = self . verbose_level
self . verbose_level = level
return last_verbose_level


signature:
def AddFilters ( self , filters ) :
    """Adds more filters to the existing list of error - message filters ."""

implementation:
for filt in filters . split ( ',' ) :
    clean_filt = filt . strip ( )
    if clean_filt :
        self . filters . append ( clean_filt )
for filt in self . filters :
    if not ( filt . startswith ( '+' ) or filt . startswith ( '-' ) ) :
        raise ValueError ( 'Every filter in --filters must start with + or -' ' (%s does not)' % filt )


signature:
def IncrementErrorCount ( self , category ) :
    """Bumps the module ' s error statistic ."""

implementation:
self . error_count += 1
if self . counting in ( 'toplevel' , 'detailed' ) :
    if self . counting != 'detailed' :
        category = category . split ( '/' ) [ 0 ]
    if category not in self . errors_by_category :
        self . errors_by_category [ category ] = 0
    self . errors_by_category [ category ] += 1


signature:
def PrintErrorCounts ( self ) :
    """Print a summary of errors by category , and the total ."""

implementation:
for category , count in sorted ( iteritems ( self . errors_by_category ) ) :
    self . PrintInfo ( 'Category \'%s\' errors found: %d\n' % ( category , count ) )
if self . error_count > 0 :
    self . PrintInfo ( 'Total errors found: %d\n' % self . error_count )


signature:
def Begin ( self , function_name ) :
    """Start analyzing function body .
 Args :
 function _ name : The name of the function being tracked ."""

implementation:
self . in_a_function = True
self . lines_in_function = 0
self . current_function = function_name


signature:
def RepositoryName ( self ) :
    r"""FullName after removing the local path to the repository .
 If we have a real absolute path name here we can try to do something smart :
 detecting the root of the checkout and truncating / path / to / checkout from
 the name so that we get header guards that don ' t include things like
 " C : \ Documents and Settings \ . . . " or " / home / username / . . . " in them and thus
 people on different computers who have checked the source out to different
 locations won ' t see bogus errors ."""

implementation:
fullname = self . FullName ( )
if os . path . exists ( fullname ) :
    project_dir = os . path . dirname ( fullname )
    # If the user specified a repository path , it exists , and the file is
    # contained in it , use the specified repository path
    if _repository :
        repo = FileInfo ( _repository ) . FullName ( )
        root_dir = project_dir
        while os . path . exists ( root_dir ) : # allow case insensitive compare on Windows
            if os . path . normcase ( root_dir ) == os . path . normcase ( repo ) :
                return os . path . relpath ( fullname , root_dir ) . replace ( '\\' , '/' )
            one_up_dir = os . path . dirname ( root_dir )
            if one_up_dir == root_dir :
                break
            root_dir = one_up_dir
    if os . path . exists ( os . path . join ( project_dir , ".svn" ) ) : # If there ' s a . svn file in the current directory , we recursively look
    # up the directory tree for the top of the SVN checkout
        root_dir = project_dir
        one_up_dir = os . path . dirname ( root_dir )
        while os . path . exists ( os . path . join ( one_up_dir , ".svn" ) ) :
            root_dir = os . path . dirname ( root_dir )
            one_up_dir = os . path . dirname ( one_up_dir )
        prefix = os . path . commonprefix ( [ root_dir , project_dir ] )
        return fullname [ len ( prefix ) + 1 : ]
    # Not SVN < = 1.6 ? Try to find a git , hg , or svn top level directory by
    # searching up from the current path .
    root_dir = current_dir = os . path . dirname ( fullname )
    while current_dir != os . path . dirname ( current_dir ) :
        if ( os . path . exists ( os . path . join ( current_dir , ".git" ) ) or os . path . exists ( os . path . join ( current_dir , ".hg" ) ) or os . path . exists ( os . path . join ( current_dir , ".svn" ) ) ) :
            root_dir = current_dir
        current_dir = os . path . dirname ( current_dir )
    if ( os . path . exists ( os . path . join ( root_dir , ".git" ) ) or os . path . exists ( os . path . join ( root_dir , ".hg" ) ) or os . path . exists ( os . path . join ( root_dir , ".svn" ) ) ) :
        prefix = os . path . commonprefix ( [ root_dir , project_dir ] )
        return fullname [ len ( prefix ) + 1 : ]
# Don ' t know what to do ; header guard warnings may be wrong . . .
return fullname


signature:
def Split ( self ) :
    """Splits the file into the directory , basename , and extension .
 For ' chrome / browser / browser . cc ' , Split ( ) would
 return ( ' chrome / browser ' , ' browser ' , ' . cc ' )
 Returns :
 A tuple of ( directory , basename , extension ) ."""

implementation:
googlename = self . RepositoryName ( )
project , rest = os . path . split ( googlename )
return ( project , ) + os . path . splitext ( rest )


signature:
def _CollapseStrings ( elided ) :
    """Collapses strings and chars on a line to simple " " or ' ' blocks .
 We nix strings first so we ' re not fooled by text like ' " http : / / " '
 Args :
 elided : The line being processed .
 Returns :
 The line with collapsed strings ."""

implementation:
if _RE_PATTERN_INCLUDE . match ( elided ) :
    return elided
# Remove escaped characters first to make quote / single quote collapsing
# basic . Things that look like escaped characters shouldn ' t occur
# outside of strings and chars .
elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES . sub ( '' , elided )
# Replace quoted strings and digit separators . Both single quotes
# and double quotes are processed in the same loop , otherwise
# nested quotes wouldn ' t work .
collapsed = ''
while True : # Find the first quote character
    match = Match ( r'^([^\'"]*)([\'"])(.*)$' , elided )
    if not match :
        collapsed += elided
        break
    head , quote , tail = match . groups ( )
    if quote == '"' : # Collapse double quoted strings
        second_quote = tail . find ( '"' )
        if second_quote >= 0 :
            collapsed += head + '""'
            elided = tail [ second_quote + 1 : ]
        else : # Unmatched double quote , don ' t bother processing the rest
        # of the line since this is probably a multiline string .
            collapsed += elided
            break
    else : # Found single quote , check nearby text to eliminate digit separators .
    # There is no special handling for floating point here , because
    # the integer / fractional / exponent parts would all be parsed
    # correctly as long as there are digits on both sides of the
    # separator . So we are fine as long as we don ' t see something
    # like " 0 . ' 3 " ( gcc 4.9.0 will not allow this literal ) .
        if Search ( r'\b(?:0[bBxX]?|[1-9])[0-9a-fA-F]*$' , head ) :
            match_literal = Match ( r'^((?:\'?[0-9a-zA-Z_])*)(.*)$' , "'" + tail )
            collapsed += head + match_literal . group ( 1 ) . replace ( "'" , '' )
            elided = match_literal . group ( 2 )
        else :
            second_quote = tail . find ( '\'' )
            if second_quote >= 0 :
                collapsed += head + "''"
                elided = tail [ second_quote + 1 : ]
            else : # Unmatched single quote
                collapsed += elided
                break
return collapsed