From: Sumera Priyadarsini <sylphrenadin@gmail.com>
To: julia.lawall@inria.fr
Cc: cocci@systeme.lip6.fr
Subject: [Cocci] [PATCH 1/2] parsing_cocci: Add feature to check only modified files
Date: Wed, 26 May 2021 16:22:37 +0530 [thread overview]
Message-ID: <9094fbf80de08736f12e8a0306a2c4885db77d50.1622024972.git.sylphrenadin@gmail.com> (raw)
In-Reply-To: <cover.1622024972.git.sylphrenadin@gmail.com>
This patch adds an option "use-patchdiff" to allow for
applying a semantic patch to only those files in a directory
where code additions have been made.
Usage: spatch -D <mode> --sp-file <cocci script> --use-patchdiff <target
directory>
Example: spatch -D report --sp-file for_each_child.cocci --use-patchdiff drivers/gpu
Signed-off-by: Sumera Priyadarsini <sylphrenadin@gmail.com>
---
Makefile | 2 +-
enter.ml | 17 +++--
globals/flag.ml | 2 +-
globals/flag.mli | 2 +-
ocaml/coccilib.mli | 1 +
parsing_cocci/get_constants2.ml | 1 +
parsing_cocci/patch_diff.ml | 118 ++++++++++++++++++++++++++++++++
parsing_cocci/patch_diff.mli | 9 +++
8 files changed, 143 insertions(+), 9 deletions(-)
create mode 100755 parsing_cocci/patch_diff.ml
create mode 100644 parsing_cocci/patch_diff.mli
diff --git a/Makefile b/Makefile
index f8d3424c0..455e92395 100644
--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,7 @@ SOURCES_parsing_cocci := \
parse_printf.ml parse_aux.ml cleanup_rules.ml disjdistr.ml \
parser_cocci_menhir.mly lexer_cocci.mll \
lexer_cli.mll lexer_script.mll \
- cocci_grep.ml dpll.ml get_constants2.ml id_utils.ml git_grep.ml \
+ cocci_grep.ml dpll.ml get_constants2.ml id_utils.ml git_grep.ml patch_diff.ml \
adjacency.ml commas_on_lists.ml re_constraints.ml parse_cocci.ml \
command_line.ml cocci_args.ml
SOURCES_parsing_c := \
diff --git a/enter.ml b/enter.ml
index 9643df782..587071aa8 100644
--- a/enter.ml
+++ b/enter.ml
@@ -18,9 +18,7 @@ module Inc = Includes
* globals/config.ml, mainly a standard.h and standard.iso file *)
let cocci_file = ref ""
-
let opt_c_files = ref []
-
let output_file = ref "" (* resulting code *)
let tmp_dir = ref "" (* temporary files for parallelism *)
let aux_file_suffix =
@@ -283,7 +281,6 @@ let print_version () =
let short_options = [
"--sp-file", Arg.Set_string cocci_file,
" <file> the semantic patch file";
-
"--opt-c",
Arg.String (fun filename ->
if Sys.file_exists filename
@@ -370,6 +367,9 @@ let short_options = [
"--use-coccigrep",
Arg.Unit (function _ -> Flag.scanner := Flag.CocciGrep),
" find relevant files using cocci grep";
+ "--use-patchdiff",
+ Arg.Unit (function _ -> Flag.scanner := Flag.PatchDiff),
+ " process files in the diff for a directory";
"--patch",
Arg.String (function s -> Flag.patch := Some (Cocci.normalize_path s)),
(" <dir> path name with respect to which a patch should be created\n"^
@@ -940,13 +940,18 @@ let idutils_filter (_,_,_,query) dir =
Some
(files +>
List.filter
- (fun file -> List.mem (Common.filesuffix file) suffixes))
+ (fun file -> List.mem (Common.filesuffix file) suffixes))
+
+let patchdiff_filter _ dir =
+ let struc = Patch_diff.getpatchdiff dir in
+ Some (List.map (function x -> x.Patch_diff.file_name) struc)
let scanner_to_interpreter = function
Flag.Glimpse -> glimpse_filter
| Flag.IdUtils -> idutils_filter
| Flag.CocciGrep -> coccigrep_filter
| Flag.GitGrep -> gitgrep_filter
+ | Flag.PatchDiff -> patchdiff_filter
| _ -> failwith "impossible"
(*****************************************************************************)
@@ -1079,7 +1084,7 @@ let rec main_action xs =
" or multiple files")
| _, false, _, _, _ -> [List.map (fun x -> (x,None)) (x::xs)]
| _, true, "",
- (Flag.Glimpse|Flag.IdUtils|Flag.CocciGrep|Flag.GitGrep),
+ (Flag.Glimpse|Flag.IdUtils|Flag.CocciGrep|Flag.GitGrep|Flag.PatchDiff),
[] ->
let interpreter = scanner_to_interpreter !Flag.scanner in
let files =
@@ -1088,7 +1093,7 @@ let rec main_action xs =
| Some files -> files in
files +> List.map (fun x -> [(x,None)])
| _, true, s,
- (Flag.Glimpse|Flag.IdUtils|Flag.CocciGrep|Flag.GitGrep), _
+ (Flag.Glimpse|Flag.IdUtils|Flag.CocciGrep|Flag.GitGrep|Flag.PatchDiff), _
when s <> "" ->
failwith "--use-xxx filters do not work with --kbuild"
(* normal *)
diff --git a/globals/flag.ml b/globals/flag.ml
index e1d01cb4c..dffe6cd80 100644
--- a/globals/flag.ml
+++ b/globals/flag.ml
@@ -16,7 +16,7 @@ let track_iso_usage = ref false
let worth_trying_opt = ref true
-type scanner = IdUtils | Glimpse | CocciGrep | GitGrep | NoScanner
+type scanner = IdUtils | Glimpse | CocciGrep | GitGrep | PatchDiff | NoScanner
let scanner = ref NoScanner
let pyoutput = ref "coccilib.output.Console"
diff --git a/globals/flag.mli b/globals/flag.mli
index dadc7b6fc..0e8a3b063 100644
--- a/globals/flag.mli
+++ b/globals/flag.mli
@@ -4,7 +4,7 @@ val show_transinfo : bool ref
val show_trying : bool ref
val track_iso_usage : bool ref
val worth_trying_opt : bool ref
-type scanner = IdUtils | Glimpse | CocciGrep | GitGrep | NoScanner
+type scanner = IdUtils | Glimpse | CocciGrep | GitGrep | PatchDiff | NoScanner
val scanner : scanner ref
val pyoutput : string ref
val ocamlc : string ref
diff --git a/ocaml/coccilib.mli b/ocaml/coccilib.mli
index 3759e7787..41f89ccde 100644
--- a/ocaml/coccilib.mli
+++ b/ocaml/coccilib.mli
@@ -1372,6 +1372,7 @@ module Flag :
| Glimpse
| CocciGrep
| GitGrep
+ | PatchDiff
| NoScanner
val scanner : scanner ref
val pyoutput : string ref
diff --git a/parsing_cocci/get_constants2.ml b/parsing_cocci/get_constants2.ml
index 0f18aa037..2a02c2b6c 100644
--- a/parsing_cocci/get_constants2.ml
+++ b/parsing_cocci/get_constants2.ml
@@ -866,5 +866,6 @@ let get_constants rules neg_pos_vars virt =
| Flag.IdUtils ->
(grep,None,coccigrep,interpret_idutils res)
| Flag.CocciGrep | Flag.GitGrep -> (grep,None,coccigrep,None)
+ | Flag.PatchDiff -> (None, None, None, None)
end
else (None,None,None,None)
diff --git a/parsing_cocci/patch_diff.ml b/parsing_cocci/patch_diff.ml
new file mode 100755
index 000000000..a117349ab
--- /dev/null
+++ b/parsing_cocci/patch_diff.ml
@@ -0,0 +1,118 @@
+open Printf
+open Str
+
+(*Read file contents*)
+let read_whole_file filename =
+ let ch = open_in filename in
+ let s = really_input_string ch (in_channel_length ch) in
+ close_in ch;
+ s
+
+(*Breakdown split_result_list type to primtive type*)
+let rec decompose_list (l: Str.split_result list) =
+ match l with
+ | [] -> []
+ | Text hd :: tl -> decompose_list tl
+ | Delim hd :: tl -> hd :: decompose_list tl
+;;
+
+(*Fetch output for bash commands*)
+let read_bash_help command =
+ let ic = Unix.open_process_in command in
+ let all_input = ref [] in
+ try
+ while true do
+ all_input := input_line ic :: !all_input
+ done;
+ !all_input
+ with
+ End_of_file -> close_in ic;
+ List.rev !all_input;;
+
+let get_root fpath =
+ let current_dir = List.hd (read_bash_help "pwd") in
+ let command_get_root = "cd " ^ fpath ^ " && git rev-parse --show-toplevel" in
+ let root = List.hd (read_bash_help command_get_root) in
+ let command_return = "cd " ^ current_dir in
+ let ic = Unix.open_process_in command_return in
+ close_in ic;
+ root
+
+ let extract_numbers line =
+ let sep = String.split_on_char ',' line in
+ match sep with
+ | [l] -> (int_of_string l, int_of_string l)
+ | [f ; e] -> (int_of_string f, int_of_string e)
+ | _ -> failwith "no line numbers found, sorry"
+;;
+
+let fetch_file_name line =
+ let pat_filename = Str.regexp "\\(+++ b\\)/\\(.+\\)\\.[a-z]+" in
+ let s = Str.full_split pat_filename line in
+ decompose_list s
+;;
+
+let fetch_line_number line =
+ let pat_line_num = Str.regexp "\\(\\+\\([0-9]+,[0-9]+\\)\\)" in
+ let s = Str.full_split pat_line_num line in
+ let fa = List.hd (decompose_list s) in
+ let (b, e) = extract_numbers fa in
+ (b, (b + e)) (*start of diff, end of diff *)
+;;
+
+type diff_info =
+{
+ file_name: string;
+ line_no: (int * int) list;
+}
+
+type patch_info = No_info | File_info of string list | Line_info of (int * int)
+
+(*check line and extract file name or file number*)
+let extract_info line =
+ if Str.string_match (Str.regexp_string "+++") line 0 then
+ File_info (fetch_file_name line)
+ else if Str.string_match (Str.regexp_string "@@ ") line 0 then
+ Line_info (fetch_line_number line)
+ else
+ No_info
+
+let rec reorg_helper new_list = function
+[] -> (List.rev new_list, [])
+| No_info :: tl -> reorg_helper new_list tl
+| File_info file_list :: tl -> (List.rev new_list, File_info file_list :: tl)
+| Line_info line_list :: tl -> reorg_helper (line_list :: new_list) tl
+;;
+
+let rec reorg fpath toproot = function
+[] -> []
+| No_info :: tl -> reorg fpath toproot tl
+| File_info [file] :: tl ->
+ let lines, rest = reorg_helper [] tl in
+ {
+ file_name = Str.replace_first (Str.regexp "+++ b") toproot file;
+ line_no = lines;
+ } :: reorg fpath toproot rest
+| File_info file_list :: tl ->
+ let lines, rest = reorg_helper [] tl in
+ reorg fpath toproot rest
+| Line_info line_list :: tl -> failwith "bad case"
+
+let rec mlines lines =
+ match lines with
+ | [] -> []
+ | hd :: tl -> extract_info hd :: mlines tl
+
+let final_info dir =
+ let git_root = get_root dir in
+ let git_read_command = "cd " ^ git_root ^ " && git diff " ^ dir ^ " | egrep '^+++|^@'" in
+ let list_diff = reorg dir git_root (mlines (read_bash_help git_read_command)) in
+ list_diff;;
+
+let rec print_tuple_list l =
+ match l with
+ | [] -> ()
+ | (a,b) :: tl -> printf "\n%d, %d" a b; print_tuple_list tl
+
+let getpatchdiff dir = final_info dir
+
diff --git a/parsing_cocci/patch_diff.mli b/parsing_cocci/patch_diff.mli
new file mode 100644
index 000000000..b059509ef
--- /dev/null
+++ b/parsing_cocci/patch_diff.mli
@@ -0,0 +1,9 @@
+
+
+type diff_info =
+{
+ file_name: string;
+ line_no: (int * int) list;
+}
+
+val getpatchdiff : string -> diff_info list
--
2.31.1
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci
next prev parent reply other threads:[~2021-05-26 10:53 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-26 10:51 [Cocci] [PATCH 0/2] Add "use-patchdiff" option Sumera Priyadarsini
2021-05-26 10:52 ` Sumera Priyadarsini [this message]
2021-05-26 10:53 ` [Cocci] [PATCH 2/2] docs: manual: Add option description in spatch_options Sumera Priyadarsini
2021-05-26 16:43 ` [Cocci] [PATCH 0/2] Add "use-patchdiff" option Markus Elfring
2021-07-01 18:42 ` Sumera Priyadarsini
2021-07-01 18:50 ` Julia Lawall
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9094fbf80de08736f12e8a0306a2c4885db77d50.1622024972.git.sylphrenadin@gmail.com \
--to=sylphrenadin@gmail.com \
--cc=cocci@systeme.lip6.fr \
--cc=julia.lawall@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).