wpiformat/wpiformat/cpplint.py
def CheckForNonStandardConstructs(filename, clean_lines, linenum,
                                  nesting_state, error):
  r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.

  Complain about several constructs which gcc-2 accepts, but which are
  not standard C++.  Warning about these in lint is one way to ease the
  transition to new compilers.
  - put storage class first (e.g. "static const" instead of "const static").
  - "%lld" instead of %qd" in printf-type functions.
  - "%1$d" is non-standard in printf-type functions.
  - "\%" is an undefined character escape sequence.
  - text after #endif is not allowed.
  - invalid inner-style forward declaration.
  - >? and <? operators, and their >?= and <?= cousins.

  Additionally, check for constructor/destructor style violations and reference
  members, as it is very convenient to do so while checking for
  gcc-2 compliance.

  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: A callable to which errors are reported, which takes 4 arguments:
           filename, line number, error level, and message
  """

  # Remove comments from the line, but leave in strings for now.
  line = clean_lines.lines[linenum]

  if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
    error(filename, linenum, 'runtime/printf_format', 3,
          '%q in format strings is deprecated.  Use %ll instead.')

  if Search(r'printf\s*\(.*".*%\d+\$', line):
    error(filename, linenum, 'runtime/printf_format', 2,
          '%N$ formats are unconventional.  Try rewriting to avoid them.')

  # Remove escaped backslashes before looking for undefined escapes.
  line = line.replace('\\\\', '')

  if Search(r'("|\').*\\(%|\[|\(|{)', line):
    error(filename, linenum, 'build/printf_format', 3,
          '%, [, (, and { are undefined character escapes.  Unescape them.')

  # For the rest, work with both comments and strings removed.
  line = clean_lines.elided[linenum]

  if Search(r'\b(const|volatile|void|char|short|int|long'
            r'|float|double|signed|unsigned'
            r'|schar|u?int8|u?int16|u?int32|u?int64)'
            r'\s+(register|static|extern|typedef)\b',
            line):
    error(filename, linenum, 'build/storage_class', 5,
          'Storage-class specifier (static, extern, typedef, etc) should be '
          'at the beginning of the declaration.')

  if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line):
    # TODO(unknown): Could it be expanded safely to arbitrary references,
    # without triggering too many false positives? The first
    # attempt triggered 5 warnings for mostly benign code in the regtest, hence
    # the restriction.
    # Here's the original regexp, for the reference:
    # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?'
    # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;'
    error(filename, linenum, 'runtime/member_string_references', 2,
          'const string& members are dangerous. It is much better to use '
          'alternatives, such as pointers or simple constants.')

  # Everything else in this function operates on class declarations.
  # Return early if the top of the nesting stack is not a class, or if
  # the class head is not completed yet.
  classinfo = nesting_state.InnermostClass()
  if not classinfo or not classinfo.seen_open_brace:
    return

  # The class may have been declared with namespace or classname qualifiers.
  # The constructor and destructor will not have those qualifiers.
  base_classname = classinfo.name.split('::')[-1]

  # Look for single-argument constructors that aren't marked explicit.
  # Technically a valid construct, but against style.
  explicit_constructor_match = Match(
      r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*'
      r'\(((?:[^()]|\([^()]*\))*)\)'
      % regex.escape(base_classname),
      line)

  if explicit_constructor_match:
    is_marked_explicit = explicit_constructor_match.group(1)

    if not explicit_constructor_match.group(2):
      constructor_args = []
    else:
      constructor_args = explicit_constructor_match.group(2).split(',')

    # collapse arguments so that commas in template parameter lists and function
    # argument parameter lists don't split arguments in two
    i = 0
    while i < len(constructor_args):
      constructor_arg = constructor_args[i]
      while (constructor_arg.count('<') > constructor_arg.count('>') or
             constructor_arg.count('(') > constructor_arg.count(')')):
        constructor_arg += ',' + constructor_args[i + 1]
        del constructor_args[i + 1]
      constructor_args[i] = constructor_arg
      i += 1

    variadic_args = [arg for arg in constructor_args if '&&...' in arg]
    defaulted_args = [arg for arg in constructor_args if '=' in arg]
    noarg_constructor = (not constructor_args or  # empty arg list
                         # 'void' arg specifier
                         (len(constructor_args) == 1 and
                          constructor_args[0].strip() == 'void'))
    onearg_constructor = ((len(constructor_args) == 1 and  # exactly one arg
                           not noarg_constructor) or
                          # all but at most one arg defaulted
                          (len(constructor_args) >= 1 and
                           not noarg_constructor and
                           len(defaulted_args) >= len(constructor_args) - 1) or
                          # variadic arguments with zero or one argument
                          (len(constructor_args) <= 2 and
                           len(variadic_args) >= 1))
    initializer_list_constructor = bool(
        onearg_constructor and
        Search(r'\bstd\s*::\s*initializer_list\b', constructor_args[0]))
    copy_constructor = bool(
        onearg_constructor and
        Match(r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&'
              % regex.escape(base_classname), constructor_args[0].strip()))

    if (not is_marked_explicit and
        onearg_constructor and
        not initializer_list_constructor and
        not copy_constructor):
      if defaulted_args or variadic_args:
        error(filename, linenum, 'runtime/explicit', 5,
              'Constructors callable with one argument '
              'should be marked explicit.')
      else:
        error(filename, linenum, 'runtime/explicit', 5,
              'Single-parameter constructors should be marked explicit.')
    elif is_marked_explicit and not onearg_constructor:
      if noarg_constructor:
        error(filename, linenum, 'runtime/explicit', 5,
              'Zero-parameter constructors should not be marked explicit.')
r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.

  Complain about several constructs which gcc-2 accepts, but which are
  not standard C++.  Warning about these in lint is one way to ease the
  transition to new compilers.
  - put storage class first (e.g. "static const" instead of "const static").
  - "%lld" instead of %qd" in printf-type functions.
  - "%1$d" is non-standard in printf-type functions.
  - "\%" is an undefined character escape sequence.
  - text after #endif is not allowed.
  - invalid inner-style forward declaration.
  - >? and <? operators, and their >?= and <?= cousins.

  Additionally, check for constructor/destructor style violations and reference
  members, as it is very convenient to do so while checking for
  gcc-2 compliance.

  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: A callable to which errors are reported, which takes 4 arguments:
           filename, line number, error level, and message
  
r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
Complain about several constructs which gcc-2 accepts, but which are
not standard C++.  Warning about these in lint is one way to ease the
transition to new compilers.
put storage class first .
"%lld" instead of %qd" in printf-type functions.
"%1$d" is non-standard in printf-type functions.
"\%" is an undefined character escape sequence.
text after #endif is not allowed.
invalid inner-style forward declaration.

Additionally, check for constructor/destructor style violations and reference
members, as it is very convenient to do so while checking for
gcc-2 compliance.
r " " " Logs an error if we see certain non - ANSI constructs ignored by gcc - 2 . Complain about several constructs which gcc - 2 accepts but which are not standard C ++ . Warning about these in lint is one way to ease the transition to new compilers . put storage class first . " %lld " instead of %qd " in printf - type functions . " %1$d " is non - standard in printf - type functions . " \ % " is an undefined character escape sequence . text after #endif is not allowed . invalid inner - style forward declaration . Additionally check for constructor / destructor style violations and reference members as it is very convenient to do so while checking for gcc - 2 compliance .
def CheckForNonStandardConstructs(filename, clean_lines, linenum,
                                  nesting_state, error):
  line = clean_lines.lines[linenum]
  if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
    error(filename, linenum, 'runtime/printf_format', 3,
          '%q in format strings is deprecated.  Use %ll instead.')
  if Search(r'printf\s*\(.*".*%\d+\$', line):
    error(filename, linenum, 'runtime/printf_format', 2,
          '%N$ formats are unconventional.  Try rewriting to avoid them.')
  line = line.replace('\\\\', '')
  if Search(r'("|\').*\\(%|\[|\(|{)', line):
    error(filename, linenum, 'build/printf_format', 3,
          '%, [, (, and { are undefined character escapes.  Unescape them.')
  line = clean_lines.elided[linenum]
  if Search(r'\b(const|volatile|void|char|short|int|long'
            r'|float|double|signed|unsigned'
            r'|schar|u?int8|u?int16|u?int32|u?int64)'
            r'\s+(register|static|extern|typedef)\b',
            line):
    error(filename, linenum, 'build/storage_class', 5,
          'Storage-class specifier (static, extern, typedef, etc) should be '
          'at the beginning of the declaration.')
  if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line):
    error(filename, linenum, 'runtime/member_string_references', 2,
          'const string& members are dangerous. It is much better to use '
          'alternatives, such as pointers or simple constants.')
  classinfo = nesting_state.InnermostClass()
  if not classinfo or not classinfo.seen_open_brace:
    return
  base_classname = classinfo.name.split('::')[-1]
  explicit_constructor_match = Match(
      r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*'
      r'\(((?:[^()]|\([^()]*\))*)\)'
      % regex.escape(base_classname),
      line)
  if explicit_constructor_match:
    is_marked_explicit = explicit_constructor_match.group(1)
    if not explicit_constructor_match.group(2):
      constructor_args = []
    else:
      constructor_args = explicit_constructor_match.group(2).split(',')
    i = 0
    while i < len(constructor_args):
      constructor_arg = constructor_args[i]
      while (constructor_arg.count('<') > constructor_arg.count('>') or
             constructor_arg.count('(') > constructor_arg.count(')')):
        constructor_arg += ',' + constructor_args[i + 1]
        del constructor_args[i + 1]
      constructor_args[i] = constructor_arg
      i += 1
    variadic_args = [arg for arg in constructor_args if '&&...' in arg]
    defaulted_args = [arg for arg in constructor_args if '=' in arg]
    noarg_constructor = (not constructor_args or  
                         (len(constructor_args) == 1 and
                          constructor_args[0].strip() == 'void'))
    onearg_constructor = ((len(constructor_args) == 1 and  
                           not noarg_constructor) or
                          (len(constructor_args) >= 1 and
                           not noarg_constructor and
                           len(defaulted_args) >= len(constructor_args) - 1) or
                          (len(constructor_args) <= 2 and
                           len(variadic_args) >= 1))
    initializer_list_constructor = bool(
        onearg_constructor and
        Search(r'\bstd\s*::\s*initializer_list\b', constructor_args[0]))
    copy_constructor = bool(
        onearg_constructor and
        Match(r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&'
              % regex.escape(base_classname), constructor_args[0].strip()))
    if (not is_marked_explicit and
        onearg_constructor and
        not initializer_list_constructor and
        not copy_constructor):
      if defaulted_args or variadic_args:
        error(filename, linenum, 'runtime/explicit', 5,
              'Constructors callable with one argument '
              'should be marked explicit.')
      else:
        error(filename, linenum, 'runtime/explicit', 5,
              'Single-parameter constructors should be marked explicit.')
    elif is_marked_explicit and not onearg_constructor:
      if noarg_constructor:
        error(filename, linenum, 'runtime/explicit', 5,
              'Zero-parameter constructors should not be marked explicit.')
def CheckForNonStandardConstructs ( filename , clean_lines , linenum , nesting_state , error ) : line = clean_lines . lines [ linenum ] if Search ( r'printf\s*\(.*".*%[-+ ]?\d*q' , line ) : error ( filename , linenum , 'runtime/printf_format' , 3 , '%q in format strings is deprecated.  Use %ll instead.' ) if Search ( r'printf\s*\(.*".*%\d+\$' , line ) : error ( filename , linenum , 'runtime/printf_format' , 2 , '%N$ formats are unconventional.  Try rewriting to avoid them.' ) line = line . replace ( '\\\\' , '' ) if Search ( r'("|\').*\\(%|\[|\(|{)' , line ) : error ( filename , linenum , 'build/printf_format' , 3 , '%, [, (, and { are undefined character escapes.  Unescape them.' ) line = clean_lines . elided [ linenum ] if Search ( r'\b(const|volatile|void|char|short|int|long' r'|float|double|signed|unsigned' r'|schar|u?int8|u?int16|u?int32|u?int64)' r'\s+(register|static|extern|typedef)\b' , line ) : error ( filename , linenum , 'build/storage_class' , 5 , 'Storage-class specifier (static, extern, typedef, etc) should be ' 'at the beginning of the declaration.' ) if Search ( r'^\s*const\s*string\s*&\s*\w+\s*;' , line ) : error ( filename , linenum , 'runtime/member_string_references' , 2 , 'const string& members are dangerous. It is much better to use ' 'alternatives, such as pointers or simple constants.' ) classinfo = nesting_state . InnermostClass ( ) if not classinfo or not classinfo . seen_open_brace : return base_classname = classinfo . name . split ( '::' ) [ - 1 ] explicit_constructor_match = Match ( r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*' r'\(((?:[^()]|\([^()]*\))*)\)' % regex . escape ( base_classname ) , line ) if explicit_constructor_match : is_marked_explicit = explicit_constructor_match . group ( 1 ) if not explicit_constructor_match . group ( 2 ) : constructor_args = [ ] else : constructor_args = explicit_constructor_match . group ( 2 ) . split ( ',' ) i = 0 while i < len ( constructor_args ) : constructor_arg = constructor_args [ i ] while ( constructor_arg . count ( '<' ) > constructor_arg . count ( '>' ) or constructor_arg . count ( '(' ) > constructor_arg . count ( ')' ) ) : constructor_arg += ',' + constructor_args [ i + 1 ] del constructor_args [ i + 1 ] constructor_args [ i ] = constructor_arg i += 1 variadic_args = [ arg for arg in constructor_args if '&&...' in arg ] defaulted_args = [ arg for arg in constructor_args if '=' in arg ] noarg_constructor = ( not constructor_args or ( len ( constructor_args ) == 1 and constructor_args [ 0 ] . strip ( ) == 'void' ) ) onearg_constructor = ( ( len ( constructor_args ) == 1 and not noarg_constructor ) or ( len ( constructor_args ) >= 1 and not noarg_constructor and len ( defaulted_args ) >= len ( constructor_args ) - 1 ) or ( len ( constructor_args ) <= 2 and len ( variadic_args ) >= 1 ) ) initializer_list_constructor = bool ( onearg_constructor and Search ( r'\bstd\s*::\s*initializer_list\b' , constructor_args [ 0 ] ) ) copy_constructor = bool ( onearg_constructor and Match ( r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&' % regex . escape ( base_classname ) , constructor_args [ 0 ] . strip ( ) ) ) if ( not is_marked_explicit and onearg_constructor and not initializer_list_constructor and not copy_constructor ) : if defaulted_args or variadic_args : error ( filename , linenum , 'runtime/explicit' , 5 , 'Constructors callable with one argument ' 'should be marked explicit.' ) else : error ( filename , linenum , 'runtime/explicit' , 5 , 'Single-parameter constructors should be marked explicit.' ) elif is_marked_explicit and not onearg_constructor : if noarg_constructor : error ( filename , linenum , 'runtime/explicit' , 5 , 'Zero-parameter constructors should not be marked explicit.' )
r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
r " " " Logs an error if we see certain non - ANSI constructs ignored by gcc - 2 .
r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.

  Complain about several constructs which gcc-2 accepts, but which are
  not standard C++.  Warning about these in lint is one way to ease the
  transition to new compilers.
  - put storage class first (e.g. "static const" instead of "const static").
  - "%lld" instead of %qd" in printf-type functions.
  - "%1$d" is non-standard in printf-type functions.
  - "\%" is an undefined character escape sequence.
  - text after #endif is not allowed.
  - invalid inner-style forward declaration.
  - >? and <? operators, and their >?= and <?= cousins.

  Additionally, check for constructor/destructor style violations and reference
  members, as it is very convenient to do so while checking for
  gcc-2 compliance.

  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: A callable to which errors are reported, which takes 4 arguments:
           filename, line number, error level, and message
  """ # Remove comments from the line, but leave in strings for now. # Remove escaped backslashes before looking for undefined escapes. # For the rest, work with both comments and strings removed. # TODO(unknown): Could it be expanded safely to arbitrary references, # without triggering too many false positives? The first # attempt triggered 5 warnings for mostly benign code in the regtest, hence # the restriction. # Here's the original regexp, for the reference: # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?' # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;' # Everything else in this function operates on class declarations. # Return early if the top of the nesting stack is not a class, or if # the class head is not completed yet. # The class may have been declared with namespace or classname qualifiers. # The constructor and destructor will not have those qualifiers. # Look for single-argument constructors that aren't marked explicit. # Technically a valid construct, but against style. # collapse arguments so that commas in template parameter lists and function # argument parameter lists don't split arguments in two # empty arg list # 'void' arg specifier # exactly one arg # all but at most one arg defaulted # variadic arguments with zero or one argument
filename
The name of the current file.
The name of the current file .
clean_lines
A CleansedLines instance containing the file.
A CleansedLines instance containing the file .
linenum
The number of the line to check.
The number of the line to check .
nesting_state
A NestingState instance which maintains information about
the current stack of nested blocks being parsed.
A NestingState instance which maintains information about the current stack of nested blocks being parsed .
error
A callable to which errors are reported, which takes 4 arguments:
filename, line number, error level, and message
A callable to which errors are reported which takes 4 arguments : filename line number error level and message