2022-09-06 23:11:39 +02:00
# python -m pytest test-other.py
import os
2023-11-16 13:44:50 +01:00
import sys
2022-09-06 23:11:39 +02:00
import pytest
2023-11-06 19:06:22 +01:00
from testutils import cppcheck , assert_cppcheck
2022-09-06 23:11:39 +02:00
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def __test_missing_include ( tmpdir , use_j ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
#include "test.h"
""" )
2023-03-04 09:02:35 +01:00
args = [ ' --enable=missingInclude ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
2022-09-06 23:11:39 +02:00
if use_j :
2023-03-04 09:02:35 +01:00
args . insert ( 0 , ' -j2 ' )
2022-09-06 23:11:39 +02:00
2023-03-04 09:02:35 +01:00
_ , _ , stderr = cppcheck ( args )
assert stderr == ' {} :2:0: information: Include file: " test.h " not found. [missingInclude] \n ' . format ( test_file )
2022-09-06 23:11:39 +02:00
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def test_missing_include ( tmpdir ) :
__test_missing_include ( tmpdir , False )
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def test_missing_include_j ( tmpdir ) : #11283
__test_missing_include ( tmpdir , True )
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def __test_missing_include_check_config ( tmpdir , use_j ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
#include "test.h"
""" )
# TODO: -rp is not working requiring the full path in the assert
args = ' --check-config -rp= {} {} ' . format ( tmpdir , test_file )
if use_j :
args = ' -j2 ' + args
_ , _ , stderr = cppcheck ( args . split ( ) )
2023-03-04 09:02:35 +01:00
assert stderr == ' ' # --check-config no longer reports the missing includes
2022-09-06 23:11:39 +02:00
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def test_missing_include_check_config ( tmpdir ) :
__test_missing_include_check_config ( tmpdir , False )
2023-08-23 11:20:20 +02:00
2022-09-06 23:11:39 +02:00
def test_missing_include_check_config_j ( tmpdir ) :
2023-04-21 10:14:34 +02:00
__test_missing_include_check_config ( tmpdir , True )
2023-08-23 11:20:20 +02:00
2023-04-21 10:14:34 +02:00
def test_missing_include_inline_suppr ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
/ / cppcheck - suppress missingInclude
#include "missing.h"
/ / cppcheck - suppress missingIncludeSystem
#include <missing2.h>
""" )
args = [ ' --enable=missingInclude ' , ' --inline-suppr ' , test_file ]
_ , _ , stderr = cppcheck ( args )
2023-08-07 19:48:11 +02:00
assert stderr == ' '
2023-08-23 11:20:20 +02:00
2023-11-16 17:25:49 +01:00
def test_preprocessor_error ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' 10866.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( ' #error test \n x=1; \n ' )
exitcode , _ , stderr = cppcheck ( [ ' --error-exitcode=1 ' , test_file ] )
assert ' preprocessorErrorDirective ' in stderr
assert exitcode != 0
2023-08-07 19:48:11 +02:00
def test_invalid_library ( tmpdir ) :
2023-09-11 11:08:23 +02:00
args = [ ' --library=none ' , ' --library=posix ' , ' --library=none2 ' , ' file.c ' ]
2023-08-07 19:48:11 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 1
assert ( stdout == " cppcheck: Failed to load library configuration file ' none ' . File not found \n "
" cppcheck: Failed to load library configuration file ' none2 ' . File not found \n " )
assert stderr == " "
2023-08-21 12:17:08 +02:00
def test_message_j ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( " " )
2023-09-11 11:08:23 +02:00
args = [ ' -j2 ' , test_file ]
2023-08-21 12:17:08 +02:00
_ , stdout , _ = cppcheck ( args )
assert stdout == " Checking {} ... \n " . format ( test_file ) # we were adding stray \0 characters at the end
2023-08-23 11:20:20 +02:00
# TODO: test missing std.cfg
def test_progress ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
int main ( int argc )
{
}
""" )
2023-09-11 11:08:23 +02:00
args = [ ' --report-progress=0 ' , ' --enable=all ' , ' --inconclusive ' , test_file ]
2023-08-23 11:20:20 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
pos = stdout . find ( ' \n ' )
assert ( pos != - 1 )
pos + = 1
assert stdout [ : pos ] == " Checking {} ... \n " . format ( test_file )
assert ( stdout [ pos : ] ==
" progress: Tokenize (typedef) 0 % \n "
" progress: Tokenize (typedef) 12 % \n "
" progress: Tokenize (typedef) 25 % \n "
" progress: Tokenize (typedef) 37 % \n "
" progress: Tokenize (typedef) 50 % \n "
" progress: Tokenize (typedef) 62 % \n "
" progress: Tokenize (typedef) 75 % \n "
" progress: Tokenize (typedef) 87 % \n "
" progress: SymbolDatabase 0 % \n "
" progress: SymbolDatabase 12 % \n "
" progress: SymbolDatabase 87 % \n "
)
assert stderr == " "
def test_progress_j ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
int main ( int argc )
{
}
""" )
2023-09-11 11:08:23 +02:00
args = [ ' --report-progress=0 ' , ' --enable=all ' , ' --inconclusive ' , ' -j2 ' , ' --disable=unusedFunction ' , test_file ]
2023-08-23 11:20:20 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
assert stdout == " Checking {} ... \n " . format ( test_file )
assert stderr == " "
2023-08-30 19:35:43 +02:00
2023-08-31 13:33:29 +02:00
def test_execute_addon_failure ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
void f ( ) ;
""" )
args = [ ' --addon=naming ' , test_file ]
# provide empty PATH environment variable so python is not found and execution of addon fails
env = { ' PATH ' : ' ' }
_ , _ , stderr = cppcheck ( args , env )
assert stderr == ' {} :0:0: error: Bailing out from analysis: Checking file failed: Failed to auto detect python [internalError] \n \n ^ \n ' . format ( test_file )
def test_execute_addon_failure_2 ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
void f ( ) ;
""" )
# specify non-existent python executbale so execution of addon fails
args = [ ' --addon=naming ' , ' --addon-python=python5.x ' , test_file ]
_ , _ , stderr = cppcheck ( args )
2023-09-20 10:40:57 +02:00
ec = 1 if os . name == ' nt ' else 127
assert stderr == " {} :0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon ' naming ' - exitcode is {} [internalError] \n \n ^ \n " . format ( test_file , ec )
2023-08-31 13:33:29 +02:00
2023-11-04 17:07:30 +01:00
def test_execute_addon_file0 ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file , ' wt ' ) as f :
f . write ( ' void foo() {} \n ' )
args = [ ' --xml ' , ' --addon=misra ' , ' --enable=style ' , test_file ]
_ , _ , stderr = cppcheck ( args )
assert ' misra-c2012-8.2 ' in stderr
assert ' .dump ' not in stderr
2023-08-31 13:33:29 +02:00
# TODO: find a test case which always fails
@pytest.mark.skip
def test_internal_error ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
#include <cstdio>
void f ( ) {
double gc = 3333.3333 ;
char stat [ 80 ] ;
sprintf ( stat , " ' %2.1f ' " , gc ) ;
}
""" )
args = [ test_file ]
_ , _ , stderr = cppcheck ( args )
2023-09-14 09:41:39 +02:00
assert stderr == ' {} :0:0: error: Bailing from out analysis: Checking file failed: converting \' 1f \' to integer failed - not an integer [internalError] \n \n ^ \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
def test_addon_misra ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon=misra ' , ' --enable=all ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == ' {} :2:1: style: misra violation (use --rule-texts=<file> to get proper output) [misra-c2012-2.3] \n typedef int MISRA_5_6_VIOLATION; \n ^ \n ' . format ( test_file )
def test_addon_y2038 ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
# TODO: trigger warning
with open ( test_file , ' wt ' ) as f :
f . write ( """
2023-09-25 13:39:17 +02:00
extern void f ( )
{
time_t t = std : : time ( nullptr ) ;
( void ) t ;
}
2023-09-20 10:40:57 +02:00
""" )
2023-09-25 13:39:17 +02:00
args = [ ' --addon=y2038 ' , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
2023-09-20 10:40:57 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
2023-09-25 13:39:17 +02:00
assert stderr == ' {} :4:21: warning: time is Y2038-unsafe [y2038-unsafe-call] \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
def test_addon_threadsafety ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
2023-09-25 13:39:17 +02:00
extern const char * f ( )
{
return strerror ( 1 ) ;
}
2023-09-20 10:40:57 +02:00
""" )
2023-09-25 13:39:17 +02:00
args = [ ' --addon=threadsafety ' , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
2023-09-20 10:40:57 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
2023-09-25 13:39:17 +02:00
assert stderr == ' {} :4:12: warning: strerror is MT-unsafe [threadsafety-unsafe-call] \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
2023-12-25 05:49:17 +01:00
def test_addon_invalidjson ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' invalid.json ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
{
" Script " : " addons/something.py "
}
""" )
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , ' nonexistent.cpp ' ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode != 0
assert stdout == ' Loading {} failed. script must be set to a string value. \n ' . format ( addon_file )
2023-09-20 10:40:57 +02:00
def test_addon_naming ( tmpdir ) :
2023-09-25 13:39:17 +02:00
# the addon does nothing without a config
addon_file = os . path . join ( tmpdir , ' naming1.json ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
{
" script " : " addons/naming.py " ,
" args " : [
" --var=[_a-z].* "
]
}
""" )
2023-09-20 10:40:57 +02:00
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
2023-09-25 13:39:17 +02:00
int Var ;
2023-09-20 10:40:57 +02:00
""" )
2023-09-25 13:39:17 +02:00
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
2023-09-20 10:40:57 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
2023-09-25 13:39:17 +02:00
assert stderr == ' {} :2:1: style: Variable Var violates naming convention [naming-varname] \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
def test_addon_namingng ( tmpdir ) :
2023-12-30 20:54:03 +01:00
addon_file = os . path . join ( tmpdir , ' namingng.json ' )
addon_config_file = os . path . join ( tmpdir , ' namingng.config.json ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
{
" script " : " addons/namingng.py " ,
" args " : [
" --configfile= %s "
]
}
""" % (addon_config_file).replace( ' \\ ' , ' \\ \\ ' ))
with open ( addon_config_file , ' wt ' ) as f :
f . write ( """
{
" RE_FILE " : [
" [^/]*[a-z][a-z0-9_]*[a-z0-9] \\ .c \\ Z "
] ,
2024-01-03 14:00:47 +01:00
" RE_CLASS_NAME " : [ " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ] ,
" RE_NAMESPACE " : [ " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ] ,
2023-12-30 20:54:03 +01:00
" RE_VARNAME " : [ " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ] ,
2024-01-03 14:00:47 +01:00
" RE_PUBLIC_MEMBER_VARIABLE " : [ " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ] ,
2024-01-04 16:26:54 +01:00
" RE_PRIVATE_MEMBER_VARIABLE " : {
" .*_tmp \\ Z " : [ true , " illegal suffix _tmp " ] ,
" priv_.* \\ Z " : [ false , " required prefix priv_ missing " ]
} ,
2023-12-30 20:54:03 +01:00
" RE_GLOBAL_VARNAME " : [ " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ] ,
" RE_FUNCTIONNAME " : [ " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ] ,
2024-01-02 15:01:02 +01:00
" include_guard " : {
" input " : " basename " ,
" prefix " : " _ " ,
" suffix " : " " ,
" case " : " upper " ,
" max_linenr " : 5 ,
" RE_HEADERFILE " : " .* \\ .h \\ Z " ,
" required " : true
} ,
2023-12-30 20:54:03 +01:00
" var_prefixes " : { " uint32_t " : " ui32 " } ,
" function_prefixes " : { " uint16_t " : " ui16 " ,
" uint32_t " : " ui32 " } ,
" skip_one_char_variables " : false
}
""" .replace( ' \\ ' , ' \\ \\ ' ))
2024-01-02 15:01:02 +01:00
test_unguarded_include_file_basename = ' test_unguarded.h '
test_unguarded_include_file = os . path . join ( tmpdir , test_unguarded_include_file_basename )
with open ( test_unguarded_include_file , ' wt ' ) as f :
f . write ( """
void InvalidFunctionUnguarded ( ) ;
""" )
2023-12-30 20:54:03 +01:00
test_include_file_basename = ' _test.h '
test_include_file = os . path . join ( tmpdir , test_include_file_basename )
with open ( test_include_file , ' wt ' ) as f :
f . write ( """
#ifndef TEST_H
#define TEST_H
void InvalidFunction ( ) ;
extern int _invalid_extern_global ;
2024-01-02 15:01:02 +01:00
#include "{}"
2023-12-30 20:54:03 +01:00
#endif
2024-01-02 15:01:02 +01:00
""" .format(test_unguarded_include_file))
2023-12-30 20:54:03 +01:00
2024-01-03 14:00:47 +01:00
test_file_basename = ' test_.cpp '
2023-12-30 20:54:03 +01:00
test_file = os . path . join ( tmpdir , test_file_basename )
2023-09-20 10:40:57 +02:00
with open ( test_file , ' wt ' ) as f :
f . write ( """
2024-01-03 14:00:47 +01:00
#include "%s"
2023-12-30 20:54:03 +01:00
void invalid_function_ ( ) ;
void _invalid_function ( ) ;
void valid_function1 ( ) ;
void valid_function2 ( int _invalid_arg ) ;
void valid_function3 ( int invalid_arg_ ) ;
void valid_function4 ( int valid_arg32 ) ;
void valid_function5 ( uint32_t invalid_arg32 ) ;
void valid_function6 ( uint32_t ui32_valid_arg ) ;
uint16_t invalid_function7 ( int valid_arg ) ;
uint16_t ui16_valid_function8 ( int valid_arg ) ;
int _invalid_global ;
static int _invalid_static_global ;
2024-01-03 14:00:47 +01:00
class _clz {
public :
2024-01-04 16:26:54 +01:00
_clz ( ) : _invalid_public ( 0 ) , _invalid_private ( 0 ) , priv_good ( 0 ) , priv_bad_tmp ( 0 ) { }
2024-01-03 14:00:47 +01:00
int _invalid_public ;
private :
char _invalid_private ;
2024-01-04 16:26:54 +01:00
int priv_good ;
int priv_bad_tmp ;
2024-01-03 14:00:47 +01:00
} ;
namespace _invalid_namespace { }
""" % (test_include_file_basename))
2023-09-20 10:40:57 +02:00
2023-12-30 20:54:03 +01:00
args = [ ' --addon= ' + addon_file , ' --verbose ' , ' --enable=all ' , test_file ]
2023-09-20 10:40:57 +02:00
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
2023-12-30 20:54:03 +01:00
' Checking {} ... ' . format ( test_file ) ,
' Defines: ' ,
' Undefines: ' ,
' Includes: ' ,
' Platform:native '
2023-09-20 10:40:57 +02:00
]
2024-01-03 14:00:47 +01:00
lines = [ line for line in stderr . splitlines ( ) if line != ' ' ]
2023-12-30 20:54:03 +01:00
expect = [
' {} :0:0: style: File name {} violates naming convention [namingng-namingConvention] ' . format ( test_include_file , test_include_file_basename ) ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :2:9: style: include guard naming violation; TEST_H != _TEST_H [namingng-includeGuardName] ' . format ( test_include_file ) ,
2024-01-02 15:01:02 +01:00
' #ifndef TEST_H ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :5:6: style: Function InvalidFunction violates naming convention [namingng-namingConvention] ' . format ( test_include_file ) ,
2023-12-30 20:54:03 +01:00
' void InvalidFunction(); ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :6:12: style: Global variable _invalid_extern_global violates naming convention [namingng-namingConvention] ' . format ( test_include_file ) ,
2023-12-30 20:54:03 +01:00
' extern int _invalid_extern_global; ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
2023-12-30 20:54:03 +01:00
2024-01-02 15:01:02 +01:00
' {} :0:0: style: File name {} violates naming convention [namingng-namingConvention] ' . format ( test_unguarded_include_file , test_unguarded_include_file_basename ) ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
2024-01-02 15:01:02 +01:00
' {} :0:0: style: Missing include guard [namingng-includeGuardMissing] ' . format ( test_unguarded_include_file ) ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :2:6: style: Function InvalidFunctionUnguarded violates naming convention [namingng-namingConvention] ' . format ( test_unguarded_include_file ) ,
2024-01-02 15:01:02 +01:00
' void InvalidFunctionUnguarded(); ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
2024-01-02 15:01:02 +01:00
2023-12-30 20:54:03 +01:00
' {} :0:0: style: File name {} violates naming convention [namingng-namingConvention] ' . format ( test_file , test_file_basename ) ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :7:26: style: Variable _invalid_arg violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
2023-12-30 20:54:03 +01:00
' void valid_function2(int _invalid_arg); ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :8:26: style: Variable invalid_arg_ violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
2023-12-30 20:54:03 +01:00
' void valid_function3(int invalid_arg_); ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :10:31: style: Variable invalid_arg32 violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
2023-12-30 20:54:03 +01:00
' void valid_function5(uint32_t invalid_arg32); ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :4:6: style: Function invalid_function_ violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
2023-12-30 20:54:03 +01:00
' void invalid_function_(); ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :5:6: style: Function _invalid_function violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
2023-12-30 20:54:03 +01:00
' void _invalid_function(); ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
2023-12-30 20:54:03 +01:00
' {} :12:10: style: Function invalid_function7 violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
' uint16_t invalid_function7(int valid_arg); ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :15:5: style: Global variable _invalid_global violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
2023-12-30 20:54:03 +01:00
' int _invalid_global; ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :16:12: style: Global variable _invalid_static_global violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
2023-12-30 20:54:03 +01:00
' static int _invalid_static_global; ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :20:5: style: Class Constructor _clz violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
2024-01-04 16:26:54 +01:00
' _clz() : _invalid_public(0), _invalid_private(0), priv_good(0), priv_bad_tmp(0) { } ' ,
2024-01-03 14:00:47 +01:00
' ^ ' ,
' {} :21:9: style: Public member variable _invalid_public violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
' int _invalid_public; ' ,
' ^ ' ,
2024-01-04 16:26:54 +01:00
' {} :23:10: style: Private member variable _invalid_private violates naming convention: required prefix priv_ missing [namingng-namingConvention] ' . format ( test_file ) ,
2024-01-03 14:00:47 +01:00
' char _invalid_private; ' ,
' ^ ' ,
2024-01-04 16:26:54 +01:00
' {} :25:9: style: Private member variable priv_bad_tmp violates naming convention: illegal suffix _tmp [namingng-namingConvention] ' . format ( test_file ) ,
' int priv_bad_tmp; ' ,
' ^ ' ,
' {} :28:11: style: Namespace _invalid_namespace violates naming convention [namingng-namingConvention] ' . format ( test_file ) ,
2024-01-03 14:00:47 +01:00
' namespace _invalid_namespace { } ' ,
' ^ ' ,
2023-12-30 20:54:03 +01:00
]
# test sorted lines; the order of messages may vary and is not of importance
lines . sort ( )
expect . sort ( )
assert lines == expect
2023-09-20 10:40:57 +02:00
2024-01-02 15:01:02 +01:00
def test_addon_namingng_config ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' namingng.json ' )
addon_config_file = os . path . join ( tmpdir , ' namingng.config.json ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
{
" script " : " addons/namingng.py " ,
" args " : [
" --configfile= %s "
]
}
""" % (addon_config_file).replace( ' \\ ' , ' \\ \\ ' ))
with open ( addon_config_file , ' wt ' ) as f :
f . write ( """
{
" RE_FILE " : " [^/]*[a-z][a-z0-9_]*[a-z0-9] \\ .c \\ Z " ,
" RE_NAMESPACE " : false ,
" RE_VARNAME " : [ " +bad pattern " , " [a-z]_good_pattern \\ Z " , " (parentheses? " ] ,
" RE_PRIVATE_MEMBER_VARIABLE " : " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ,
2024-01-04 16:26:54 +01:00
" RE_PUBLIC_MEMBER_VARIABLE " : {
" tmp_.* \\ Z " : [ true , " illegal prefix tmp_ " ] ,
" bad_.* \\ Z " : true ,
" public_.* \\ Z " : [ false ] ,
" pub_.* \\ Z " : [ 0 , " required prefix pub_ missing " ]
} ,
2024-01-02 15:01:02 +01:00
" RE_GLOBAL_VARNAME " : " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ,
" RE_FUNCTIONNAME " : " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ,
" RE_CLASS_NAME " : " [a-z][a-z0-9_]*[a-z0-9] \\ Z " ,
" _comment1 " : " these should all be arrays, or null, or not set " ,
" include_guard " : true ,
" var_prefixes " : [ " bad " ] ,
" function_prefixes " : false ,
" _comment2 " : " these should all be dict " ,
" skip_one_char_variables " : " false " ,
" _comment3 " : " this should be bool " ,
" RE_VAR_NAME " : " typo "
}
""" .replace( ' \\ ' , ' \\ \\ ' ))
test_file_basename = ' test.c '
test_file = os . path . join ( tmpdir , test_file_basename )
with open ( test_file , ' a ' ) as f :
# only create the file
pass
args = [ ' --addon= ' + addon_file , ' --verbose ' , ' --enable=all ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file ) ,
' Defines: ' ,
' Undefines: ' ,
' Includes: ' ,
' Platform:native '
]
lines = stderr . splitlines ( )
# ignore the first line, stating that the addon failed to run properly
lines . pop ( 0 )
assert lines == [
" Output: " ,
" config error: RE_FILE must be list (not str), or not set " ,
2024-01-04 16:26:54 +01:00
" config error: RE_NAMESPACE must be list or dict (not bool), or not set " ,
2024-01-02 15:01:02 +01:00
" config error: include_guard must be dict (not bool), or not set " ,
" config error: item ' +bad pattern ' of ' RE_VARNAME ' is not a valid regular expression: nothing to repeat at position 0 " ,
" config error: item ' (parentheses? ' of ' RE_VARNAME ' is not a valid regular expression: missing ), unterminated subpattern at position 0 " ,
" config error: var_prefixes must be dict (not list), or not set " ,
2024-01-04 16:26:54 +01:00
" config error: RE_PRIVATE_MEMBER_VARIABLE must be list or dict (not str), or not set " ,
" config error: item ' bad_.* \\ Z ' of ' RE_PUBLIC_MEMBER_VARIABLE ' must be an array [bool,string] " ,
" config error: item ' public_.* \\ Z ' of ' RE_PUBLIC_MEMBER_VARIABLE ' must be an array [bool,string] " ,
" config error: item ' pub_.* \\ Z ' of ' RE_PUBLIC_MEMBER_VARIABLE ' must be an array [bool,string] " ,
" config error: RE_GLOBAL_VARNAME must be list or dict (not str), or not set " ,
" config error: RE_FUNCTIONNAME must be list or dict (not str), or not set " ,
2024-01-02 15:01:02 +01:00
" config error: function_prefixes must be dict (not bool), or not set " ,
2024-01-04 16:26:54 +01:00
" config error: RE_CLASS_NAME must be list or dict (not str), or not set " ,
2024-01-02 15:01:02 +01:00
" config error: skip_one_char_variables must be bool (not str), or not set " ,
" config error: unknown config key ' RE_VAR_NAME ' [internalError] " ,
" " ,
" ^ " ,
]
2023-09-25 13:39:17 +02:00
def test_addon_findcasts ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
extern void f ( char c )
{
int i = ( int ) c ;
( void ) i ;
}
""" )
args = [ ' --addon=findcasts ' , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == ' {} :4:21: information: found a cast [findcasts-cast] \n ' . format ( test_file )
def test_addon_misc ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
extern void f ( )
{
char char * [ ] = { " a " " b " }
}
""" )
args = [ ' --addon=misc ' , ' --enable=all ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == ' {} :4:26: style: String concatenation in array initialization, missing comma? [misc-stringConcatInArrayInit] \n ' . format ( test_file )
2023-09-20 10:40:57 +02:00
def test_invalid_addon_json ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' addon1.json ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
""" )
test_file = os . path . join ( tmpdir , ' file.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
2023-10-08 21:28:57 +02:00
assert exitcode == 1
2023-09-20 10:40:57 +02:00
lines = stdout . splitlines ( )
assert lines == [
' Loading {} failed. syntax error at line 2 near: ' . format ( addon_file )
]
assert stderr == ' '
def test_invalid_addon_py ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' addon1.py ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
raise Exception ( )
""" )
test_file = os . path . join ( tmpdir , ' file.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
2023-12-17 19:13:14 +01:00
assert exitcode == 0 # TODO: needs to be 1
2023-09-20 10:40:57 +02:00
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == " {} :0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon ' addon1 ' - exitcode is 1 [internalError] \n \n ^ \n " . format ( test_file )
def test_invalid_addon_py_verbose ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' addon1.py ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
raise Exception ( )
""" )
test_file = os . path . join ( tmpdir , ' file.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , ' --verbose ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
2023-12-17 19:13:14 +01:00
assert exitcode == 0 # TODO: needs to be 1
2023-09-20 10:40:57 +02:00
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file ) ,
' Defines: ' ,
' Undefines: ' ,
' Includes: ' ,
' Platform:native '
]
"""
/ tmp / pytest - of - user / pytest - 11 / test_invalid_addon_py_20 / file . cpp : 0 : 0 : error : Bailing out from analysis : Checking file failed : Failed to execute addon ' addon1 ' - exitcode is 1 : python3 / home / user / CLionProjects / cppcheck / addons / runaddon . py / tmp / pytest - of - user / pytest - 11 / test_invalid_addon_py_20 / addon1 . py - - cli / tmp / pytest - of - user / pytest - 11 / test_invalid_addon_py_20 / file . cpp .24762 . dump
Output :
Traceback ( most recent call last ) :
File " /home/user/CLionProjects/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 " /tmp/pytest-of-user/pytest-11/test_invalid_addon_py_20/addon1.py " , line 2 , in < module >
raise Exception ( )
Exceptio [ internalError ]
"""
# /tmp/pytest-of-user/pytest-10/test_invalid_addon_py_20/file.cpp:0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon 'addon1' - exitcode is 256.: python3 /home/user/CLionProjects/cppcheck/addons/runaddon.py /tmp/pytest-of-user/pytest-10/test_invalid_addon_py_20/addon1.py --cli /tmp/pytest-of-user/pytest-10/test_invalid_addon_py_20/file.cpp.24637.dump
assert stderr . startswith ( " {} :0:0: error: Bailing out from analysis: Checking file failed: Failed to execute addon ' addon1 ' - exitcode is 1: " . format ( test_file ) )
assert stderr . count ( ' Output: \n Traceback ' )
assert stderr . endswith ( ' raise Exception() \n Exception [internalError] \n \n ^ \n ' )
def test_addon_result ( tmpdir ) :
addon_file = os . path . join ( tmpdir , ' addon1.py ' )
with open ( addon_file , ' wt ' ) as f :
f . write ( """
print ( " Checking ... " )
print ( " " )
print ( ' { " file " : " test.cpp " , " linenr " : 1, " column " : 1, " severity " : " style " , " message " : " msg " , " addon " : " addon1 " , " errorId " : " id " , " extra " : " " } ' )
print ( ' { " loc " : [ { " file " : " test.cpp " , " linenr " : 1, " column " : 1, " info " : " " }], " severity " : " style " , " message " : " msg " , " addon " : " addon1 " , " errorId " : " id " , " extra " : " " } ' )
""" )
test_file = os . path . join ( tmpdir , ' file.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
typedef int MISRA_5_6_VIOLATION ;
""" )
args = [ ' --addon= {} ' . format ( addon_file ) , ' --enable=all ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0 # TODO: needs to be 1
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file )
]
assert stderr == ' test.cpp:1:1: style: msg [addon1-id] \n \n ^ \n '
2023-09-20 14:45:44 +02:00
# #11483
def test_unused_function_include ( tmpdir ) :
test_cpp_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_cpp_file , ' wt ' ) as f :
f . write ( """
#include "test.h"
""" )
test_h_file = os . path . join ( tmpdir , ' test.h ' )
with open ( test_h_file , ' wt ' ) as f :
f . write ( """
class A {
public :
void f ( ) { }
/ / cppcheck - suppress unusedFunction
void f2 ( ) { }
} ;
""" )
args = [ ' --enable=unusedFunction ' , ' --inline-suppr ' , ' --template= {file} : {line} : {column} : {severity} : { inconclusive:inconclusive:} {message} [ {id} ] ' , test_cpp_file ]
_ , _ , stderr = cppcheck ( args )
assert stderr == " {} :4:0: style: The function ' f ' is never used. [unusedFunction] \n " . format ( test_h_file )
2023-10-05 19:04:06 +02:00
# TODO: test with -j and all other types
def test_showtime_top5_file ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( """
int main ( int argc )
{
}
""" )
args = [ ' --showtime=top5_file ' , ' --quiet ' , test_file ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0 # TODO: needs to be 1
lines = stdout . splitlines ( )
assert len ( lines ) == 7
assert lines [ 0 ] == ' '
for i in range ( 1 , 5 ) :
assert lines [ i ] . endswith ( ' - 1 result(s)) ' )
assert lines [ 6 ] . startswith ( ' Overall time: ' )
assert stderr == ' '
2023-10-08 21:28:57 +02:00
def test_missing_addon ( tmpdir ) :
args = [ ' --addon=misra3 ' , ' --addon=misra ' , ' --addon=misra2 ' , ' file.c ' ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 1
lines = stdout . splitlines ( )
lines . sort ( )
assert lines == [
' Did not find addon misra2.py ' ,
' Did not find addon misra3.py '
]
assert stderr == " "
2023-11-06 19:06:22 +01:00
def test_file_filter ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
pass
args = [ ' --file-filter=*.cpp ' , test_file ]
out_lines = [
' Checking {} ... ' . format ( test_file )
]
assert_cppcheck ( args , ec_exp = 0 , err_exp = [ ] , out_exp = out_lines )
def test_file_filter_2 ( tmpdir ) :
test_file_1 = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file_1 , ' wt ' ) as f :
pass
test_file_2 = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file_2 , ' wt ' ) as f :
pass
args = [ ' --file-filter=*.cpp ' , test_file_1 , test_file_2 ]
out_lines = [
' Checking {} ... ' . format ( test_file_1 )
]
assert_cppcheck ( args , ec_exp = 0 , err_exp = [ ] , out_exp = out_lines )
def test_file_filter_3 ( tmpdir ) :
test_file_1 = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file_1 , ' wt ' ) as f :
pass
test_file_2 = os . path . join ( tmpdir , ' test.c ' )
with open ( test_file_2 , ' wt ' ) as f :
pass
args = [ ' --file-filter=*.c ' , test_file_1 , test_file_2 ]
out_lines = [
' Checking {} ... ' . format ( test_file_2 )
]
assert_cppcheck ( args , ec_exp = 0 , err_exp = [ ] , out_exp = out_lines )
def test_file_filter_no_match ( tmpdir ) :
2023-12-14 16:55:42 +01:00
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) :
pass
args = [ ' --file-filter=*.c ' , test_file ]
2023-11-06 19:06:22 +01:00
out_lines = [
' cppcheck: error: could not find any files matching the filter. '
]
assert_cppcheck ( args , ec_exp = 1 , err_exp = [ ] , out_exp = out_lines )
2023-11-07 21:21:24 +01:00
def test_file_order ( tmpdir ) :
test_file_a = os . path . join ( tmpdir , ' a.c ' )
with open ( test_file_a , ' wt ' ) :
pass
test_file_b = os . path . join ( tmpdir , ' b.c ' )
with open ( test_file_b , ' wt ' ) :
pass
test_file_c = os . path . join ( tmpdir , ' c.c ' )
with open ( test_file_c , ' wt ' ) :
pass
test_file_d = os . path . join ( tmpdir , ' d.c ' )
with open ( test_file_d , ' wt ' ) :
pass
args = [ test_file_c , test_file_d , test_file_b , test_file_a ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file_c ) ,
' 1/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_d ) ,
' 2/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_b ) ,
' 3/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_a ) ,
' 4/4 files checked 0 % d one '
]
assert stderr == ' '
2023-11-09 10:17:30 +01:00
def test_markup ( tmpdir ) :
test_file_1 = os . path . join ( tmpdir , ' test_1.qml ' )
with open ( test_file_1 , ' wt ' ) as f :
pass
test_file_2 = os . path . join ( tmpdir , ' test_2.cpp ' )
with open ( test_file_2 , ' wt ' ) as f :
pass
test_file_3 = os . path . join ( tmpdir , ' test_3.qml ' )
with open ( test_file_3 , ' wt ' ) as f :
pass
test_file_4 = os . path . join ( tmpdir , ' test_4.cpp ' )
with open ( test_file_4 , ' wt ' ) as f :
pass
args = [ ' --library=qt ' , test_file_1 , test_file_2 , test_file_3 , test_file_4 ]
out_lines = [
' Checking {} ... ' . format ( test_file_2 ) ,
' 1/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_4 ) ,
' 2/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_1 ) ,
' 3/4 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_3 ) ,
' 4/4 files checked 0 % d one '
]
assert_cppcheck ( args , ec_exp = 0 , err_exp = [ ] , out_exp = out_lines )
def test_markup_j ( tmpdir ) :
test_file_1 = os . path . join ( tmpdir , ' test_1.qml ' )
with open ( test_file_1 , ' wt ' ) as f :
pass
test_file_2 = os . path . join ( tmpdir , ' test_2.cpp ' )
with open ( test_file_2 , ' wt ' ) as f :
pass
test_file_3 = os . path . join ( tmpdir , ' test_3.qml ' )
with open ( test_file_3 , ' wt ' ) as f :
pass
test_file_4 = os . path . join ( tmpdir , ' test_4.cpp ' )
with open ( test_file_4 , ' wt ' ) as f :
pass
args = [ ' --library=qt ' , test_file_1 , test_file_2 , test_file_3 , test_file_4 ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
for i in range ( 1 , 5 ) :
lines . remove ( ' {} /4 files checked 0 % d one ' . format ( i ) )
assert lines == [
' Checking {} ... ' . format ( test_file_2 ) ,
' Checking {} ... ' . format ( test_file_4 ) ,
' Checking {} ... ' . format ( test_file_1 ) ,
' Checking {} ... ' . format ( test_file_3 )
]
assert stderr == ' '
2023-11-16 13:44:50 +01:00
def test_valueflow_debug ( tmpdir ) :
test_file_cpp = os . path . join ( tmpdir , ' test_1.cpp ' )
with open ( test_file_cpp , ' wt ' ) as f :
f . write ( """
#include "test.h"
void f ( )
{
int i = 0 ;
}
"""
)
test_file_h = os . path . join ( tmpdir , ' test.h ' )
with open ( test_file_h , ' wt ' ) as f :
f . write ( """
#include "test2.h"
inline void f1 ( )
{
int i = 0 ;
}
"""
)
pass
test_file_h_2 = os . path . join ( tmpdir , ' test2.h ' )
with open ( test_file_h_2 , ' wt ' ) as f :
f . write ( """
inline void f2 ( )
{
int i = 0 ;
}
"""
)
args = [ ' --debug ' , test_file_cpp ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
if sys . platform == " win32 " :
stdout = stdout . replace ( ' / ' , ' \\ ' )
assert stdout == ''' Checking {} ...
##file {}
2 : void f2 ( )
3 : { {
2023-12-05 14:22:32 +01:00
4 : int i @var1 ; i @var1 = 0 ;
2023-11-16 13:44:50 +01:00
5 : } }
##file {}
1 :
2 :
3 : void f1 ( )
4 : { {
2023-12-05 14:22:32 +01:00
5 : int i @var2 ; i @var2 = 0 ;
2023-11-16 13:44:50 +01:00
6 : } }
##file {}
1 :
2 :
3 :
4 : void f ( )
5 : { {
2023-12-05 14:22:32 +01:00
6 : int i @var3 ; i @var3 = 0 ;
2023-11-16 13:44:50 +01:00
7 : } }
##Value flow
File { }
Line 4
= always 0
0 always 0
File { }
Line 5
= always 0
0 always 0
File { }
Line 6
= always 0
0 always 0
''' .format(test_file_cpp, test_file_h_2, test_file_h, test_file_cpp, test_file_h_2, test_file_h, test_file_cpp)
assert stderr == ' '
2023-12-08 22:17:22 +01:00
def test_file_duplicate ( tmpdir ) :
test_file_a = os . path . join ( tmpdir , ' a.c ' )
with open ( test_file_a , ' wt ' ) :
pass
args = [ test_file_a , test_file_a , str ( tmpdir ) ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file_a )
]
assert stderr == ' '
def test_file_duplicate_2 ( tmpdir ) :
test_file_a = os . path . join ( tmpdir , ' a.c ' )
with open ( test_file_a , ' wt ' ) :
pass
test_file_b = os . path . join ( tmpdir , ' b.c ' )
with open ( test_file_b , ' wt ' ) :
pass
test_file_c = os . path . join ( tmpdir , ' c.c ' )
with open ( test_file_c , ' wt ' ) :
pass
args = [ test_file_c , test_file_a , test_file_b , str ( tmpdir ) , test_file_b , test_file_c , test_file_a , str ( tmpdir ) ]
exitcode , stdout , stderr = cppcheck ( args )
assert exitcode == 0
lines = stdout . splitlines ( )
assert lines == [
' Checking {} ... ' . format ( test_file_c ) ,
' 1/3 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_a ) ,
' 2/3 files checked 0 % d one ' ,
' Checking {} ... ' . format ( test_file_b ) ,
' 3/3 files checked 0 % d one '
]
assert stderr == ' '
2023-12-14 16:55:42 +01:00
def test_file_ignore ( tmpdir ) :
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) :
pass
args = [ ' -itest.cpp ' , test_file ]
out_lines = [
' cppcheck: error: could not find or open any of the paths given. ' ,
' cppcheck: Maybe all paths were ignored? '
]
assert_cppcheck ( args , ec_exp = 1 , err_exp = [ ] , out_exp = out_lines )
2023-12-17 15:07:13 +01:00
def test_build_dir_j_memleak ( tmpdir ) : #12111
build_dir = os . path . join ( tmpdir , ' build-dir ' )
os . mkdir ( build_dir )
test_file = os . path . join ( tmpdir , ' test.cpp ' )
with open ( test_file , ' wt ' ) as f :
f . write ( ' int main() {} ' )
args = [ ' --cppcheck-build-dir= {} ' . format ( build_dir ) , ' -j2 ' , test_file ]
out_lines = [
' Checking {} ... ' . format ( test_file )
]
assert_cppcheck ( args , ec_exp = 0 , err_exp = [ ] , out_exp = out_lines )