rules:
rule-configurations:
    # This is the default value (as of the time I wrote this) but I'm making
    # it explicit since it needs to agree with the value used by clang-format.
    # Thus, if we ever change the style guide to allow longer or shorter lines
    # this should be changed (as well as the corresponding .clang-format file).
    - key: LONG_LINE
      value: 100

    # The default limit for the length of variable names is 20. Long names are
    # problematic but twenty chars results in way too many errors. So increase
    # the limit to something more reasonable.
    #
    - key: LONG_VARIABLE_NAME
      value: 30

    # We're slightly more persmissive regarding the total number of lines in a
    # function. Default is 50.
    - key: LONG_METHOD
      value: 60

    # We're slightly more persmissive regarding the number of non-comment
    # lines in a function. Default is 30.
    - key: NCSS_METHOD
      value: 40

    # We're willing to allow slighly more linearly independent paths through a
    # function. Most of our code has a lot of `switch` blocks or consecutive
    # `if` tests that are straightforward to interpret but which increase this
    # metric. Default is 10.
    - key: CYCLOMATIC_COMPLEXITY
      value: 14

    # We're willing to allow slighly more execution paths through a function.
    # Default is 200.
    - key: NPATH_COMPLEXITY
      value: 300

disable-rules:
    #
    # A few instances of "useless parentheses" errors are meaningful. Mostly
    # in the context of the `return` statement. Unfortunately the vast
    # majority would result in removing parentheses that decreases
    # readability. So we're going to ignore this warning and rely on humans to
    # notice when the parentheses are truly not needed.
    #
    # Also, some macro expansions, such as FD_SET(), trigger this warning and
    # we don't want to suppress each of those individually.
    #
    - UselessParentheses
    #
    # OCLint wants variable names to be at least three characters in length.
    # Which would be fine if it supported a reasonable set of exceptions
    # (e.g., "i", "j", "k") and allowed adding additional exceptions to match
    # conventions employed by a project. Since it doesn't, and thus generates
    # a lot of really annoying warnings, we're going to disable this rule.
    #
    - ShortVariableName
    #
    # This rule flags perfectly reasonable conditions like `if (!some_condition)`
    # and is therefore just noise. Disable this rule.
    #
    - InvertedLogic
    #
    # The idea behind the "double negative" rule is sound since constructs
    # like "!!(var & flag)" should be written as "static_cast<bool>(var &
    # flag)". Unfortunately this rule has way too many false positives;
    # especially in the context of assert statements. So disable this rule.
    #
    - DoubleNegative
    #
    # Avoiding bitwise operators in a conditional is a good idea with one
    # exception: testing whether a bit flag is set. Which happens to be the
    # only time you'll see something like `if (j->flags & JOB_CONSTRUCTED)`
    # in project source.
    #
    - BitwiseOperatorInConditional
    #
    # I don't think I've ever seen a case where assigning a value to a
    # parameter inside the function body was unclear, let along dangerour or
    # an error. This rule is therefore just noise. Disable this rule.
    #
    - ParameterReassignment
    #
    # The project makes so much use of the `goto` statement, many of which
    # will require significant refactoring to remove, that warnings about its
    # use are just noise.
    #
    - GotoStatement
    #
    # Oclint has too many false positives regarding missing `break;`
    # statements. Mostly having to do with `case` blocks that use  `goto` to
    # exit the block. In some cases because it doesn't recognize
    # `__builtin_unreachable()` to flag that the previous statement won't
    # return. And the compiler already alerts us to case blocks that fall
    # through to the next case block.
    - MissingBreakInSwitchStatement
    #
    # This warning is perfectly reasonable for most projects but not for ksh.
    # There are simply too many `switch` blocks with as little as two branches
    # but which we cannot justify rewriting.
    # TODO: Enable this warning in the future.
    #
    - TooFewBranchesInSwitchStatement
    #
    # The structure of the code means that it is often clearer to nest `if()`
    # statements even though they could be written as a single `if()`. I've
    # simplified all the instances where no clarity is lost by combining them.
    # Those instances that remain would be made harder to read and reason
    # about if they were combined. Eliminating these instances requires
    # refactoring that is hard to justify. So disable this warning.
    - CollapsibleIfStatements
    #
    # TODO: Enable These in the future after simpler or more serious issues
    # have been addressed. At this time these warnings just make it hard to
    # see the issues that are easier or more urgent to resolve. So disable them.
    #
    - HighCyclomaticComplexity
    - HighNPathComplexity
    - HighNcssMethod
