`namingng.py` somewhat supported specifying a dict instead of a list for
regular expressions, until the feature was broken by a patch of mine
recently. This PR contains a patch rewriting the feature and expanding
relevant unit tests.
To improve maintainability, a second patch is added that refactors the
code for better readability and structure.
For naming issues reported, column was always set to `0`, which is now
fixed.
Global variable naming errors were reported as "Public member" issues,
which is also fixed.
The unit test now covers namespaces, class names, public and private
member variables.
Include guard naming can be validated against various patterns:
- prefixes/suffixes (`_FILE_H`, `PROJECT_FILE_H`, `FILE_H_`)
- basename/full path (`FILE_H`, `SUB_DIR_INC_FILE_H`)
- upper- or lowercase (`FILE_H`, `file_h`)
- any combination of the above (`project_sub_dir_inc_file_h_`)
A regexp can be specified to match header filenames. The example matches
any filename not starting with / and ending with `.h`, intended to match
C header files while exluding system files.
The test is not limited to naming only; validity and presence of include
guards can also be tested by setting `"required":true` in the config
file.
Enabling this feature requires adding the key `"include_guard"` to the
namingng config file used.
The namingng unit test is extended to test various features of the
include guard test.
Also, config handling is improved, adding (superficial) validation and a
unit test.
namingng.py was only usable in standalone mode, but now supports CLI
mode, i.e. with cppcheck --addon=namingng. It uses the generic reporting
provided by cppcheckdata.reportError(). All output other than reported
errors is suppressed.
A local function reportNamingError() is implemented to call through to
cppcheckdata.reportError(), filling in common defaults.
The collection of errors and the --verify feature are removed, including
related workflow and a test file. These are replaced by a unit test.
(note: comment updated after force push; initial PR was incomplete)
namingng.py attempted to derive the source filename from the name of the
dumpfile. However, the dumpfile is not necessarily named according to
this pattern, e.g. cppcheck will add the pid to the filename, making
RE_FILE rules
fail. Taking the first item of data.files seem to be more robust.
To get the basename of the file, `os.path.basename()` is used. This
solves (theoretical) issues on platforms with a different path
separator.
With this patch, all filenames are checked, not just those provided on
the cppcheck command line. This is useful as header files will now also
be part of this check, even if not explicitly specified on the command
line.
The "RE_FILE" key of the configuration JSON may contain a list of
regular expressions, where any match will lead to acceptance of the
filename.
Both the full path and the basename of the files are tested.
One use case for this combination of features is:
```
"RE_FILE":[
"/.*\\.h\\Z",
"[a-z][a-z0-9_]*[a-z0-9]\\.[ch]\\Z"
]
```
This will accept any file naming convention of the platform used
(assuming platform files are all referenced using an absolute path),
while enforcing a particular naming scheme for project files.
This patch allows a config file to have RE_VARNAME and RE_FUNCTIONNAME
without the corresponding var_prefixes and function_prefixes keys. The
namingng.py processing function would otherwise raise an exception
trying to get these keys, while they are not strictly necessary, if no
prefixes are required.
The attribute movedValue is misspelled with an uppercase V, this leads
to errors when printing token values:
```
$ python3 runaddon.py test.py test.c.dump
Checking test.c.dump...
Checking test.c.dump, config ...
line 2 str=""lala\n""
Traceback (most recent call last):
File "/home/eric/tools/cppcheck/addons/runaddon.py", line 11, in <module>
cppcheck.runcheckers()
File "/home/eric/tools/cppcheck/addons/cppcheck.py", line 39, in runcheckers
c(cfg, data)
File "test.py", line 9, in func
print(f' {value}')
File "/home/eric/tools/cppcheck/addons/cppcheckdata.py", line 907, in __repr__
", ".join(("{}={}".format(a, repr(getattr(self, a))) for a in attrs))
File "/home/eric/tools/cppcheck/addons/cppcheckdata.py", line 907, in <genexpr>
", ".join(("{}={}".format(a, repr(getattr(self, a))) for a in attrs))
AttributeError: 'Value' object has no attribute 'movedValue'
```
This fixes a crash with following error:
```
Traceback (most recent call last):
File "/usr/local/share/Cppcheck/addons/runaddon.py", line 8, in <module>
runpy.run_path(addon, run_name='__main__')
File "<frozen runpy>", line 291, in run_path
File "<frozen runpy>", line 98, in _run_module_code
File "<frozen runpy>", line 88, in _run_code
File "/usr/local/share/Cppcheck/addons/misra.py", line 4737, in <module>
main()
File "/usr/local/share/Cppcheck/addons/misra.py", line 4679, in main
checker.parseDump(item)
File "/usr/local/share/Cppcheck/addons/misra.py", line 4335, in parseDump
self.executeCheck(902, self.misra_9_2, cfg)
File "/usr/local/share/Cppcheck/addons/misra.py", line 4246, in executeCheck
check_function(*args)
File "/usr/local/share/Cppcheck/addons/misra.py", line 2104, in misra_9_2
misra_9.misra_9_x(self, data, 902)
File "/usr/local/share/Cppcheck/addons/misra_9.py", line 414, in misra_9_x
parser.parseInitializer(ed, eq.astOperand2)
File "/usr/local/share/Cppcheck/addons/misra_9.py", line 320, in parseInitializer
child = self.root.getChildByValueElement(self.ed)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'getChildByValueElement'
```
A minimal example and testcase is added.
The extra check for nextChild seems to fix it, however i did not read
the whole codebase, so maybe this creates other issues.
---------
Co-authored-by: Tim Blume <tbl@sevenstax-intern.de>
I also changed the comment header to run tests on misra-test-avr8.c
because I thought that was the intention to use it like misra-test.c; if
not, I can revert.
* Update cppcheckdata.py
- added links to cpp-file/function that writes this part of the dump-file
- updated documentation (Added list of possible return values for a number of variables)
- added MacroUsage isKnownValue
- added ValueType reference
- added Token isBoolean
- added Token isCast
- added Token externLang
- added Token isComplex
- added Token isRestrict
- added Token isAttributeExport
- added Token originalName
- added Scope functions
- added Scope definedType
- added Function hasVirtualSpecifier
- removed Function isVirtual
- added Function isAttributeNoreturn
- added Function overriddenFunction
- added Variable isVolatile
- class Container added
- added Value movedValue
- added Value uninit
- added Value bufferSize
- removed Value inconclusive and added it to valueKind
* Update cppcheckdata.py
removed encoding from open (needed to make python 2.7 check pass) where python 2.7 should not be used anymore
* Update cppcheckdata.py after feedback
made sure that attributes I added to the class always have a value
added some missing attributes in the print