pycocci was originally written to set sensible defaults for doing development with Coccinelle with a git tree and to also add parallelism wrapper support. Coccinelle now has a '--jobs' argument which does the same but it works better. This feature is available as of 1.0.0 but will have some fixes which will go in on 1.0.2.
Likewise the 1.0.1 release has --use-gitgrep support which works better than --use-coccigrep. An old feature that has been in place for a long time is --use-glimpse, and since we have that code released now as open source we should provide support for it as its expected we'd get the best results with it. The glimpse code still needs a bit of work, as the public releases doesn't yet build correctly, but nevertheless we should support it as glimpse is now open sourced under the ISC license. Instead of removing the old built-in wrapper for parallelism support lets keep it and instead check the version of coccinelle you have and let pycocci figure out what options you need. Pycocci will also investingate your work area and determine if your path is part of a git tree or not. That is, you can provide a target path say drivers/net/tun.c and pycocci will be smart enough to know that two levels below a .git directory exists. This also works with directories. It does this by recursing each subdirectory and if it finds a .git then checking if the target is part of the git tree. The check in place for this is implemented as gitname(), upon investingating git code setup_git_directory_gently() is the shortest possible path to determine if a path is part of a git tree, and respectively git rev-parse the easiest tool we can use to infer this from a given path. Something similar is not implemented but can be done for glimpse. This is not a priority however as glimpse can't even build yet as-is with the new public release of code. If all index options fail to check out we resort to --use-coccigrep as the last-resort default. Signed-off-by: Luis R. Rodriguez <mcg...@suse.com> --- tools/pycocci | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 12 deletions(-) diff --git a/tools/pycocci b/tools/pycocci index 141f9783d09b..51d89f618add 100755 --- a/tools/pycocci +++ b/tools/pycocci @@ -346,14 +346,57 @@ class ExecutionErrorThread(CoccinelleError): tf.close() os.unlink(fn) -def spatch(cocci_file, outdir, - max_threads, thread_id, temp_dir, ret_q, extra_args=[]): +class ExecutionErrorCocci(CoccinelleError): + def __init__(self, errcode, output, cocci_file, logwrite, print_name): + self.error_code = errcode + logwrite("Failed to apply changes from %s\n" % print_name) + logwrite(output) + +def spatch(cocci_file, outdir, logwrite, num_jobs, print_name, extra_args=[]): + + req = Req(chatty=True) + req.coccinelle('1.0.2') + + if not req.reqs_match(): + sys.exit(1) + + num_cpus = cpu_count() + if num_jobs: + threads = int(num_jobs) + else: + threads = num_cpus + + cmd = ['spatch', + '--sp-file', cocci_file, + '--in-place', + '--recursive-includes', + '--relax-include-path', + '--timeout', '120', + '--dir', outdir ] + + if (threads > 1): + cmd.extend(['--jobs', str(threads)]) + + cmd.extend(extra_args) + + logwrite("%s\n" % " ".join(cmd)) + + sprocess = subprocess.Popen(cmd, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + close_fds=True, universal_newlines=True) + output = sprocess.communicate()[0] + sprocess.wait() + if sprocess.returncode != 0: + raise ExecutionErrorCocci(sprocess.returncode, output, cocci_file, logwrite, print_name) + return output + +def spatch_old(cocci_file, outdir, + max_threads, thread_id, temp_dir, ret_q, extra_args=[]): cmd = ['spatch', '--sp-file', cocci_file, '--in-place', '--recursive-includes', '--relax-include-path', - '--use-coccigrep', '--timeout', '120', '--dir', outdir ] @@ -385,9 +428,9 @@ def threaded_spatch(cocci_file, outdir, logwrite, num_jobs, ret_q = Queue() with tempdir() as t: for num in range(threads): - p = Process(target=spatch, args=(cocci_file, outdir, - threads, num, t, ret_q, - extra_args)) + p = Process(target=spatch_old, args=(cocci_file, outdir, + threads, num, t, ret_q, + extra_args)) jobs.append(p) for p in jobs: p.start() @@ -440,12 +483,42 @@ def _main(): if args.jobs > 0: jobs = args.jobs - output = threaded_spatch(args.cocci_file, - args.target_dir, - logwrite, - jobs, - os.path.basename(args.cocci_file), - extra_args=extra_spatch_args) + has_spatch_1_0_1 = Req(chatty=False) + has_spatch_1_0_1.coccinelle('1.0.1') + + has_spatch_1_0_2 = Req(chatty=False) + has_spatch_1_0_2.coccinelle('1.0.2') + + git_reqs = Req(chatty=False) + git_reqs.require('git') + + glimpse_index = os.path.abspath(os.path.join(args.target_dir, '.glimpse_index')) + git_dir = None + + if git_reqs.reqs_match(): + git_dir = gitname(args.target_dir) + + if os.path.isfile(glimpse_index): + extra_spatch_args.append('--use-glimpse') + elif git_dir: + if has_spatch_1_0_1.reqs_match(): + extra_spatch_args.append('--use-gitgrep') + else: + extra_spatch_args.append('--use-coccigrep') + else: + extra_spatch_args.append('--use-coccigrep') + + if has_spatch_1_0_2.reqs_match(): + output = spatch(args.cocci_file, args.target_dir, logwrite, jobs, + os.path.basename(args.cocci_file), + extra_args=extra_spatch_args) + else: + output = threaded_spatch(args.cocci_file, + args.target_dir, + logwrite, + jobs, + os.path.basename(args.cocci_file), + extra_args=extra_spatch_args) if args.verbose: logwrite(output) return 0 -- 2.3.2.209.gd67f9d5.dirty -- To unsubscribe from this list: send the line "unsubscribe backports" in