#
#      Copyright (c) 2023, an unpublished work by CodeSecure, Inc.
#                      ALL RIGHTS RESERVED
#
#      Copyright (c) 2017-2023, an unpublished work by GrammaTech, Inc.
#                      ALL RIGHTS RESERVED
# 
#      This software is furnished under a license and may be used and
#      copied only in accordance with the terms of such license and the
#      inclusion of the above copyright notice.  This software or any
#      other copies thereof may not be provided or otherwise made
#      available to any other person.  Title to and ownership of the
#      software is retained by CodeSecure, Inc.
# 

# UCvar_plugin.py
# 
#  a small example plugin that reports declarations for variables
#  whose names contain upper case characters

import cs

# The plug-in defines a new warning class to go with its new check. We
# do not associate any CodeSonar mnemonics or CWE identifiers with the
# new class, as none are appropriate.  The new warning class must be
# created in the top level scope.

upvar_wc = cs.analysis.create_warningclass(
    'Variable name has upper case characters',
    '',
    1.0,
    cs.warningclass_flags.PADDING,
    cs.warning_significance.STYLE
    )


# Visitors should be at the finest granularity that is appropriate
# for the check. This plug-in is checking a property of variable
# names, so we define a visitor that operates on symbols.

@cs.symbol_visitor        # \link API/PythonAPI/visitor.html visitor decorator \endlink
def check_var_case(sym):
    nm = sym.name()       # cs.symbol.name()

    # If there are one or more upper case characters and the variable
    # is declared in user code, issue a warning and return.
    if nm != nm.lower():        
        try:
            (symfi,symline) = sym.file_line()   # cs.symbol.file_line()
        except cs.result as r:
            # If no position, do not report warning. Raise any other errors.
            if r != cs.result.NO_POSITION:
                raise     
        else:
            if not symfi.is_system_include():   # cs.sfileinst.is_system_include()
                upvar_wc.report(symfi,          # cs.warningclass.report()
                                symline,
                                'Variable name %s has upper case character'%nm)
