Code Duplication    Length = 161-161 lines in 2 locations

core/build-support/cpplint.py 1 location

@@ 2888-3048 (lines=161) @@
2885
              obj.name)
2886
2887
2888
def CheckForNonStandardConstructs(filename, clean_lines, linenum,
2889
                                  nesting_state, error):
2890
  r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
2891
2892
  Complain about several constructs which gcc-2 accepts, but which are
2893
  not standard C++.  Warning about these in lint is one way to ease the
2894
  transition to new compilers.
2895
  - put storage class first (e.g. "static const" instead of "const static").
2896
  - "%lld" instead of %qd" in printf-type functions.
2897
  - "%1$d" is non-standard in printf-type functions.
2898
  - "\%" is an undefined character escape sequence.
2899
  - text after #endif is not allowed.
2900
  - invalid inner-style forward declaration.
2901
  - >? and <? operators, and their >?= and <?= cousins.
2902
2903
  Additionally, check for constructor/destructor style violations and reference
2904
  members, as it is very convenient to do so while checking for
2905
  gcc-2 compliance.
2906
2907
  Args:
2908
    filename: The name of the current file.
2909
    clean_lines: A CleansedLines instance containing the file.
2910
    linenum: The number of the line to check.
2911
    nesting_state: A NestingState instance which maintains information about
2912
                   the current stack of nested blocks being parsed.
2913
    error: A callable to which errors are reported, which takes 4 arguments:
2914
           filename, line number, error level, and message
2915
  """
2916
2917
  # Remove comments from the line, but leave in strings for now.
2918
  line = clean_lines.lines[linenum]
2919
2920
  if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
2921
    error(filename, linenum, 'runtime/printf_format', 3,
2922
          '%q in format strings is deprecated.  Use %ll instead.')
2923
2924
  if Search(r'printf\s*\(.*".*%\d+\$', line):
2925
    error(filename, linenum, 'runtime/printf_format', 2,
2926
          '%N$ formats are unconventional.  Try rewriting to avoid them.')
2927
2928
  # Remove escaped backslashes before looking for undefined escapes.
2929
  line = line.replace('\\\\', '')
2930
2931
  if Search(r'("|\').*\\(%|\[|\(|{)', line):
2932
    error(filename, linenum, 'build/printf_format', 3,
2933
          '%, [, (, and { are undefined character escapes.  Unescape them.')
2934
2935
  # For the rest, work with both comments and strings removed.
2936
  line = clean_lines.elided[linenum]
2937
2938
  if Search(r'\b(const|volatile|void|char|short|int|long'
2939
            r'|float|double|signed|unsigned'
2940
            r'|schar|u?int8|u?int16|u?int32|u?int64)'
2941
            r'\s+(register|static|extern|typedef)\b',
2942
            line):
2943
    error(filename, linenum, 'build/storage_class', 5,
2944
          'Storage-class specifier (static, extern, typedef, etc) should be '
2945
          'at the beginning of the declaration.')
2946
2947
  if Match(r'\s*#\s*endif\s*[^/\s]+', line):
2948
    error(filename, linenum, 'build/endif_comment', 5,
2949
          'Uncommented text after #endif is non-standard.  Use a comment.')
2950
2951
  if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
2952
    error(filename, linenum, 'build/forward_decl', 5,
2953
          'Inner-style forward declarations are invalid.  Remove this line.')
2954
2955
  if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
2956
            line):
2957
    error(filename, linenum, 'build/deprecated', 3,
2958
          '>? and <? (max and min) operators are non-standard and deprecated.')
2959
2960
  if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line):
2961
    # TODO(unknown): Could it be expanded safely to arbitrary references,
2962
    # without triggering too many false positives? The first
2963
    # attempt triggered 5 warnings for mostly benign code in the regtest, hence
2964
    # the restriction.
2965
    # Here's the original regexp, for the reference:
2966
    # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?'
2967
    # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;'
2968
    error(filename, linenum, 'runtime/member_string_references', 2,
2969
          'const string& members are dangerous. It is much better to use '
2970
          'alternatives, such as pointers or simple constants.')
2971
2972
  # Everything else in this function operates on class declarations.
2973
  # Return early if the top of the nesting stack is not a class, or if
2974
  # the class head is not completed yet.
2975
  classinfo = nesting_state.InnermostClass()
2976
  if not classinfo or not classinfo.seen_open_brace:
2977
    return
2978
2979
  # The class may have been declared with namespace or classname qualifiers.
2980
  # The constructor and destructor will not have those qualifiers.
2981
  base_classname = classinfo.name.split('::')[-1]
2982
2983
  # Look for single-argument constructors that aren't marked explicit.
2984
  # Technically a valid construct, but against style.
2985
  explicit_constructor_match = Match(
2986
      r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*'
2987
      r'\(((?:[^()]|\([^()]*\))*)\)'
2988
      % re.escape(base_classname),
2989
      line)
2990
2991
  if explicit_constructor_match:
2992
    is_marked_explicit = explicit_constructor_match.group(1)
2993
2994
    if not explicit_constructor_match.group(2):
2995
      constructor_args = []
2996
    else:
2997
      constructor_args = explicit_constructor_match.group(2).split(',')
2998
2999
    # collapse arguments so that commas in template parameter lists and function
3000
    # argument parameter lists don't split arguments in two
3001
    i = 0
3002
    while i < len(constructor_args):
3003
      constructor_arg = constructor_args[i]
3004
      while (constructor_arg.count('<') > constructor_arg.count('>') or
3005
             constructor_arg.count('(') > constructor_arg.count(')')):
3006
        constructor_arg += ',' + constructor_args[i + 1]
3007
        del constructor_args[i + 1]
3008
      constructor_args[i] = constructor_arg
3009
      i += 1
3010
3011
    variadic_args = [arg for arg in constructor_args if '&&...' in arg]
3012
    defaulted_args = [arg for arg in constructor_args if '=' in arg]
3013
    noarg_constructor = (not constructor_args or  # empty arg list
3014
                         # 'void' arg specifier
3015
                         (len(constructor_args) == 1 and
3016
                          constructor_args[0].strip() == 'void'))
3017
    onearg_constructor = ((len(constructor_args) == 1 and  # exactly one arg
3018
                           not noarg_constructor) or
3019
                          # all but at most one arg defaulted
3020
                          (len(constructor_args) >= 1 and
3021
                           not noarg_constructor and
3022
                           len(defaulted_args) >= len(constructor_args) - 1) or
3023
                          # variadic arguments with zero or one argument
3024
                          (len(constructor_args) <= 2 and
3025
                           len(variadic_args) >= 1))
3026
    initializer_list_constructor = bool(
3027
        onearg_constructor and
3028
        Search(r'\bstd\s*::\s*initializer_list\b', constructor_args[0]))
3029
    copy_constructor = bool(
3030
        onearg_constructor and
3031
        Match(r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&'
3032
              % re.escape(base_classname), constructor_args[0].strip()))
3033
3034
    if (not is_marked_explicit and
3035
        onearg_constructor and
3036
        not initializer_list_constructor and
3037
        not copy_constructor):
3038
      if defaulted_args or variadic_args:
3039
        error(filename, linenum, 'runtime/explicit', 5,
3040
              'Constructors callable with one argument '
3041
              'should be marked explicit.')
3042
      else:
3043
        error(filename, linenum, 'runtime/explicit', 5,
3044
              'Single-parameter constructors should be marked explicit.')
3045
    elif is_marked_explicit and not onearg_constructor:
3046
      if noarg_constructor:
3047
        error(filename, linenum, 'runtime/explicit', 5,
3048
              'Zero-parameter constructors should not be marked explicit.')
3049
3050
3051
def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error):

sdk/build-support/cpplint.py 1 location

@@ 2888-3048 (lines=161) @@
2885
              obj.name)
2886
2887
2888
def CheckForNonStandardConstructs(filename, clean_lines, linenum,
2889
                                  nesting_state, error):
2890
  r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
2891
2892
  Complain about several constructs which gcc-2 accepts, but which are
2893
  not standard C++.  Warning about these in lint is one way to ease the
2894
  transition to new compilers.
2895
  - put storage class first (e.g. "static const" instead of "const static").
2896
  - "%lld" instead of %qd" in printf-type functions.
2897
  - "%1$d" is non-standard in printf-type functions.
2898
  - "\%" is an undefined character escape sequence.
2899
  - text after #endif is not allowed.
2900
  - invalid inner-style forward declaration.
2901
  - >? and <? operators, and their >?= and <?= cousins.
2902
2903
  Additionally, check for constructor/destructor style violations and reference
2904
  members, as it is very convenient to do so while checking for
2905
  gcc-2 compliance.
2906
2907
  Args:
2908
    filename: The name of the current file.
2909
    clean_lines: A CleansedLines instance containing the file.
2910
    linenum: The number of the line to check.
2911
    nesting_state: A NestingState instance which maintains information about
2912
                   the current stack of nested blocks being parsed.
2913
    error: A callable to which errors are reported, which takes 4 arguments:
2914
           filename, line number, error level, and message
2915
  """
2916
2917
  # Remove comments from the line, but leave in strings for now.
2918
  line = clean_lines.lines[linenum]
2919
2920
  if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
2921
    error(filename, linenum, 'runtime/printf_format', 3,
2922
          '%q in format strings is deprecated.  Use %ll instead.')
2923
2924
  if Search(r'printf\s*\(.*".*%\d+\$', line):
2925
    error(filename, linenum, 'runtime/printf_format', 2,
2926
          '%N$ formats are unconventional.  Try rewriting to avoid them.')
2927
2928
  # Remove escaped backslashes before looking for undefined escapes.
2929
  line = line.replace('\\\\', '')
2930
2931
  if Search(r'("|\').*\\(%|\[|\(|{)', line):
2932
    error(filename, linenum, 'build/printf_format', 3,
2933
          '%, [, (, and { are undefined character escapes.  Unescape them.')
2934
2935
  # For the rest, work with both comments and strings removed.
2936
  line = clean_lines.elided[linenum]
2937
2938
  if Search(r'\b(const|volatile|void|char|short|int|long'
2939
            r'|float|double|signed|unsigned'
2940
            r'|schar|u?int8|u?int16|u?int32|u?int64)'
2941
            r'\s+(register|static|extern|typedef)\b',
2942
            line):
2943
    error(filename, linenum, 'build/storage_class', 5,
2944
          'Storage-class specifier (static, extern, typedef, etc) should be '
2945
          'at the beginning of the declaration.')
2946
2947
  if Match(r'\s*#\s*endif\s*[^/\s]+', line):
2948
    error(filename, linenum, 'build/endif_comment', 5,
2949
          'Uncommented text after #endif is non-standard.  Use a comment.')
2950
2951
  if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
2952
    error(filename, linenum, 'build/forward_decl', 5,
2953
          'Inner-style forward declarations are invalid.  Remove this line.')
2954
2955
  if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
2956
            line):
2957
    error(filename, linenum, 'build/deprecated', 3,
2958
          '>? and <? (max and min) operators are non-standard and deprecated.')
2959
2960
  if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line):
2961
    # TODO(unknown): Could it be expanded safely to arbitrary references,
2962
    # without triggering too many false positives? The first
2963
    # attempt triggered 5 warnings for mostly benign code in the regtest, hence
2964
    # the restriction.
2965
    # Here's the original regexp, for the reference:
2966
    # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?'
2967
    # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;'
2968
    error(filename, linenum, 'runtime/member_string_references', 2,
2969
          'const string& members are dangerous. It is much better to use '
2970
          'alternatives, such as pointers or simple constants.')
2971
2972
  # Everything else in this function operates on class declarations.
2973
  # Return early if the top of the nesting stack is not a class, or if
2974
  # the class head is not completed yet.
2975
  classinfo = nesting_state.InnermostClass()
2976
  if not classinfo or not classinfo.seen_open_brace:
2977
    return
2978
2979
  # The class may have been declared with namespace or classname qualifiers.
2980
  # The constructor and destructor will not have those qualifiers.
2981
  base_classname = classinfo.name.split('::')[-1]
2982
2983
  # Look for single-argument constructors that aren't marked explicit.
2984
  # Technically a valid construct, but against style.
2985
  explicit_constructor_match = Match(
2986
      r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*'
2987
      r'\(((?:[^()]|\([^()]*\))*)\)'
2988
      % re.escape(base_classname),
2989
      line)
2990
2991
  if explicit_constructor_match:
2992
    is_marked_explicit = explicit_constructor_match.group(1)
2993
2994
    if not explicit_constructor_match.group(2):
2995
      constructor_args = []
2996
    else:
2997
      constructor_args = explicit_constructor_match.group(2).split(',')
2998
2999
    # collapse arguments so that commas in template parameter lists and function
3000
    # argument parameter lists don't split arguments in two
3001
    i = 0
3002
    while i < len(constructor_args):
3003
      constructor_arg = constructor_args[i]
3004
      while (constructor_arg.count('<') > constructor_arg.count('>') or
3005
             constructor_arg.count('(') > constructor_arg.count(')')):
3006
        constructor_arg += ',' + constructor_args[i + 1]
3007
        del constructor_args[i + 1]
3008
      constructor_args[i] = constructor_arg
3009
      i += 1
3010
3011
    variadic_args = [arg for arg in constructor_args if '&&...' in arg]
3012
    defaulted_args = [arg for arg in constructor_args if '=' in arg]
3013
    noarg_constructor = (not constructor_args or  # empty arg list
3014
                         # 'void' arg specifier
3015
                         (len(constructor_args) == 1 and
3016
                          constructor_args[0].strip() == 'void'))
3017
    onearg_constructor = ((len(constructor_args) == 1 and  # exactly one arg
3018
                           not noarg_constructor) or
3019
                          # all but at most one arg defaulted
3020
                          (len(constructor_args) >= 1 and
3021
                           not noarg_constructor and
3022
                           len(defaulted_args) >= len(constructor_args) - 1) or
3023
                          # variadic arguments with zero or one argument
3024
                          (len(constructor_args) <= 2 and
3025
                           len(variadic_args) >= 1))
3026
    initializer_list_constructor = bool(
3027
        onearg_constructor and
3028
        Search(r'\bstd\s*::\s*initializer_list\b', constructor_args[0]))
3029
    copy_constructor = bool(
3030
        onearg_constructor and
3031
        Match(r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&'
3032
              % re.escape(base_classname), constructor_args[0].strip()))
3033
3034
    if (not is_marked_explicit and
3035
        onearg_constructor and
3036
        not initializer_list_constructor and
3037
        not copy_constructor):
3038
      if defaulted_args or variadic_args:
3039
        error(filename, linenum, 'runtime/explicit', 5,
3040
              'Constructors callable with one argument '
3041
              'should be marked explicit.')
3042
      else:
3043
        error(filename, linenum, 'runtime/explicit', 5,
3044
              'Single-parameter constructors should be marked explicit.')
3045
    elif is_marked_explicit and not onearg_constructor:
3046
      if noarg_constructor:
3047
        error(filename, linenum, 'runtime/explicit', 5,
3048
              'Zero-parameter constructors should not be marked explicit.')
3049
3050
3051
def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error):