| 
									
										
										
										
											2020-02-03 14:45:33 +01:00
										 |  |  | #! /usr/bin/env python3 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-01 07:51:16 -04:00
										 |  |  | # Invoke sparse based on the contents of compile_commands.json, | 
					
						
							|  |  |  | # also working around several deficiencies in cgcc's command line | 
					
						
							|  |  |  | # parsing | 
					
						
							| 
									
										
										
										
											2020-02-03 14:45:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import json | 
					
						
							|  |  |  | import subprocess | 
					
						
							| 
									
										
										
										
											2020-09-01 07:51:16 -04:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2020-02-03 14:45:33 +01:00
										 |  |  | import sys | 
					
						
							|  |  |  | import shlex | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-01 07:51:16 -04:00
										 |  |  | def cmdline_for_sparse(sparse, cmdline): | 
					
						
							|  |  |  |     # Do not include the C compiler executable | 
					
						
							|  |  |  |     skip = True | 
					
						
							|  |  |  |     arg = False | 
					
						
							|  |  |  |     out = sparse + ['-no-compile'] | 
					
						
							|  |  |  |     for x in cmdline: | 
					
						
							|  |  |  |         if arg: | 
					
						
							|  |  |  |             out.append(x) | 
					
						
							|  |  |  |             arg = False | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if skip: | 
					
						
							|  |  |  |             skip = False | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         # prevent sparse from treating output files as inputs | 
					
						
							|  |  |  |         if x == '-MF' or x == '-MQ' or x == '-o': | 
					
						
							|  |  |  |             skip = True | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         # cgcc ignores -no-compile if it sees -M or -MM? | 
					
						
							|  |  |  |         if x.startswith('-M'): | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         # sparse does not understand these! | 
					
						
							|  |  |  |         if x == '-iquote' or x == '-isystem': | 
					
						
							|  |  |  |             x = '-I' | 
					
						
							|  |  |  |         if x == '-I': | 
					
						
							|  |  |  |             arg = True | 
					
						
							|  |  |  |         out.append(x) | 
					
						
							|  |  |  |     return out | 
					
						
							| 
									
										
										
										
											2020-02-03 14:45:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-01 07:51:16 -04:00
										 |  |  | root_path = os.getenv('MESON_BUILD_ROOT') | 
					
						
							|  |  |  | def build_path(s): | 
					
						
							|  |  |  |     return s if not root_path else os.path.join(root_path, s) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ccjson_path = build_path(sys.argv[1]) | 
					
						
							|  |  |  | with open(ccjson_path, 'r') as fd: | 
					
						
							| 
									
										
										
										
											2020-02-03 14:45:33 +01:00
										 |  |  |     compile_commands = json.load(fd) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-01 07:51:16 -04:00
										 |  |  | sparse = sys.argv[2:] | 
					
						
							|  |  |  | sparse_env = os.environ.copy() | 
					
						
							| 
									
										
										
										
											2020-02-03 14:45:33 +01:00
										 |  |  | for cmd in compile_commands: | 
					
						
							| 
									
										
										
										
											2020-09-01 07:51:16 -04:00
										 |  |  |     cmdline = shlex.split(cmd['command']) | 
					
						
							|  |  |  |     cmd = cmdline_for_sparse(sparse, cmdline) | 
					
						
							|  |  |  |     print('REAL_CC=%s' % shlex.quote(cmdline[0]), | 
					
						
							|  |  |  |           ' '.join((shlex.quote(x) for x in cmd))) | 
					
						
							|  |  |  |     sparse_env['REAL_CC'] = cmdline[0] | 
					
						
							|  |  |  |     r = subprocess.run(cmd, env=sparse_env, cwd=root_path) | 
					
						
							| 
									
										
										
										
											2020-02-03 14:45:33 +01:00
										 |  |  |     if r.returncode != 0: | 
					
						
							|  |  |  |         sys.exit(r.returncode) |