From 7efecf3503162cbcf8fde33db20928db5a0a65e1 Mon Sep 17 00:00:00 2001
From: "James K. Lowden" <jklowden@symas.com>
Date: Tue, 9 Feb 2021 12:06:11 -0500
Subject: [PATCH] support -W additional warning-igore files

---
 cscan | 45 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 38 insertions(+), 7 deletions(-)

diff --git a/cscan b/cscan
index c9ee9bf..36413d7 100755
--- a/cscan
+++ b/cscan
@@ -218,27 +218,54 @@ def cast_pair(node):
                            class_name(node.expr) + ':',
                            string_of(node)) 
 
+def read_ignores( filename ):
+    ignoring = []
+    with open(filename) as f:
+        for input in f:
+            elements = input.split(':') 
+            if len(elements) > 2:
+                output = ':'.join( elements[:2] )
+                ignoring.append(output)
+                #rint(output)
+    return ignoring
+        
 # Visitor for Cast nodes, to report where a cast is used. 
 class CastVisitor(c_ast.NodeVisitor):
+    ncast = 0
+    ignoring = ()
+    def __init__(self, ignoring):
+        self.ignoring = ignoring
     def visit_Cast(self, node):
-        print( cast_pair(node) )
-        
-def show_casts(cpp, filename):        
+        key = '%s:%d' % (node.coord.file, node.coord.line)
+        if not key in self.ignoring:
+            print( cast_pair(node) )
+            self.ncast += 1
+        else:
+            pass # print('%s: (ignored)' % key)
+            
+def show_casts(cpp, filename, ignoring):
     cpp_args = re.split(r'\s{2,}', environ['CSCAN_FLAGS'])
     assert( len(cpp_args) > 1 )
     ast = parse_file(filename, use_cpp=True,
                      cpp_path=cpp, 
                      cpp_args=cpp_args)
 
-    v = CastVisitor()
+    try:
+        ignoring += read_ignores('.cscan-ignore')
+        print( 'ignoring %d approved casts' % len(ignoring) )
+    except Exception as oops:
+        print(oops);
+    
+    v = CastVisitor(ignoring)
     v.visit(ast)
-
+    return v.ncast
 
 if __name__ == "__main__":
     cpp = 'cpp'
+    ignoring = []
     
     try:
-        opts, args = getopt(sys.argv[1:], "E:v")
+        opts, args = getopt(sys.argv[1:], "E:W:v")
     except getopt.GetoptError as err:
         print(err)
         exit(1)
@@ -249,6 +276,8 @@ if __name__ == "__main__":
             cpp = a
         elif o == '-v':
             verbose = True
+        elif o == '-W':
+            ignoring += read_ignores(a)
         else:
             assert False, "unhandled option"
 
@@ -257,7 +286,9 @@ if __name__ == "__main__":
     for filename in sys.argv[narg:]:
         print( 'scanning "%s"' % filename )
         try: 
-            show_casts(cpp, filename)
+            exit_status = show_casts(cpp, filename, ignoring)
+            if exit_status > 0:
+                break
         except CalledProcessError as erc:
             print( '%s in %s' % (erc, getcwd()), file=sys.stderr )
             exit(1)
-- 
GitLab