1#!/usr/bin/python 2 3# Copyright (C) 2006-2017 Erik de Castro Lopo <erikd@mega-nerd.com> 4# 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions are 9# met: 10# 11# * Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# * Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in 15# the documentation and/or other materials provided with the 16# distribution. 17# * Neither the author nor the names of any contributors may be used 18# to endorse or promote products derived from this software without 19# specific prior written permission. 20# 21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 25# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 33 34# This parses C code using regexes (yes, thats horrible) and makes sure 35# that calling conventions to the function psf_binheader_writef are 36# correct. 37 38 39 40import re, string, sys 41 42_whitespace_re = re.compile ("\s+", re.MULTILINE) 43 44def find_binheader_writefs (data): 45 lst = re.findall ('psf_binheader_writef\s*\(\s*[a-zA-Z_]+\s*,\s*\"[^;]+;', data, re.MULTILINE) 46 return [_whitespace_re.sub (" ", x) for x in lst] 47 48def find_format_string (s): 49 fmt = re.search ('"([^"]+)"', s) 50 if not fmt: 51 print ("Bad format in :\n\n\t%s\n\n" % s) 52 sys.exit (1) 53 fmt = fmt.groups () 54 if len (fmt) != 1: 55 print ("Bad format in :\n\n\t%s\n\n" % s) 56 sys.exit (1) 57 return _whitespace_re.sub ("", fmt [0]) 58 59def get_param_list (data): 60 dlist = re.search ("\((.+)\)\s*;", data) 61 dlist = dlist.groups ()[0] 62 dlist = dlist.split(",") 63 dlist = [x.strip() for x in dlist] 64 return dlist [2:] 65 66def handle_file (fname): 67 errors = 0 68 data = open (fname, "r").read () 69 70 # return errors 71 72 writefs = find_binheader_writefs (data) 73 for item in writefs: 74 fmt = find_format_string (item) 75 params = get_param_list (item) 76 param_index = 0 77 78 # print item 79 80 for ch in fmt: 81 if ch in 'Eet ': 82 continue 83 84 if ch == 'b': 85 if params [param_index][:4] == "BHWv" and params [param_index + 1][:4] == "BHWz": 86 param_index += 2 87 continue 88 89 if "BHW" + ch == params [param_index][:4]: 90 param_index += 1 91 continue 92 93 if errors == 0: sys.stdout.write ("\n") 94 print ("\n%s: error for format specifier '%c' (index %d) in:\n %s\n" % (fname, ch, param_index, item)) 95 errors += 1 96 # Break out of 'for ch in fmt' loop 97 break 98 99 return errors 100 101#=============================================================================== 102 103if len (sys.argv) > 1: 104 sys.stdout.write ("\n binheader_writef_check : ") 105 sys.stdout.flush () 106 errors = 0 107 for fname in sys.argv [1:]: 108 errors += handle_file (fname) 109 if errors > 0: 110 print ("\nErrors : %d\n" % errors) 111 sys.exit (1) 112 113print ("ok\n") 114 115