Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/coccinelle')
-rw-r--r--contrib/coccinelle/README40
-rw-r--r--contrib/coccinelle/config_fn_ctx.pending.cocci144
-rw-r--r--contrib/coccinelle/git_config_number.cocci27
3 files changed, 207 insertions, 4 deletions
diff --git a/contrib/coccinelle/README b/contrib/coccinelle/README
index d1daa1f626..055ad0e06a 100644
--- a/contrib/coccinelle/README
+++ b/contrib/coccinelle/README
@@ -1,7 +1,9 @@
-This directory provides examples of Coccinelle (http://coccinelle.lip6.fr/)
-semantic patches that might be useful to developers.
+= coccinelle
-There are two types of semantic patches:
+This directory provides Coccinelle (http://coccinelle.lip6.fr/) semantic patches
+that might be useful to developers.
+
+== Types of semantic patches
* Using the semantic transformation to check for bad patterns in the code;
The target 'make coccicheck' is designed to check for these patterns and
@@ -42,7 +44,7 @@ There are two types of semantic patches:
This allows to expose plans of pending large scale refactorings without
impacting the bad pattern checks.
-Git-specific tips & things to know about how we run "spatch":
+== Git-specific tips & things to know about how we run "spatch":
* The "make coccicheck" will piggy-back on
"COMPUTE_HEADER_DEPENDENCIES". If you've built a given object file
@@ -90,3 +92,33 @@ Git-specific tips & things to know about how we run "spatch":
The absolute times will differ for you, but the relative speedup
from caching should be on that order.
+
+== Authoring and reviewing coccinelle changes
+
+* When a .cocci is made, both the Git changes and .cocci file should be
+ reviewed. When reviewing such a change, do your best to understand the .cocci
+ changes (e.g. by asking the author to explain the change) and be explicit
+ about your understanding of the changes. This helps us decide whether input
+ from coccinelle experts is needed or not. If you aren't sure of the cocci
+ changes, indicate what changes you actively endorse and leave an Acked-by
+ (instead of Reviewed-by).
+
+* Authors should consider that reviewers may not be coccinelle experts, thus the
+ the .cocci changes may not be self-evident. A plain text description of the
+ changes is strongly encouraged, especially when using more esoteric features
+ of the language.
+
+* .cocci rules should target only the problem it is trying to solve; "collateral
+ damage" is not allowed. Reviewers should look out and flag overly-broad rules.
+
+* Consider the cost-benefit ratio of .cocci changes. In particular, consider the
+ effect on the runtime of "make coccicheck", and how often your .cocci check
+ will catch something valuable. As a rule of thumb, rules that can bail early
+ if a file doesn't have a particular token will have a small impact on runtime,
+ and vice-versa.
+
+* .cocci files used for refactoring should be temporarily kept in-tree to aid
+ the refactoring of out-of-tree code (e.g. in-flight topics). Periodically
+ evaluate the cost-benefit ratio to determine when the file should be removed.
+ For example, consider how many out-of-tree users are left and how much this
+ slows down "make coccicheck".
diff --git a/contrib/coccinelle/config_fn_ctx.pending.cocci b/contrib/coccinelle/config_fn_ctx.pending.cocci
new file mode 100644
index 0000000000..6d3d1000a9
--- /dev/null
+++ b/contrib/coccinelle/config_fn_ctx.pending.cocci
@@ -0,0 +1,144 @@
+@ get_fn @
+identifier fn, R;
+@@
+(
+(
+git_config_from_file
+|
+git_config_from_file_with_options
+|
+git_config_from_mem
+|
+git_config_from_blob_oid
+|
+read_early_config
+|
+read_very_early_config
+|
+config_with_options
+|
+git_config
+|
+git_protected_config
+|
+config_from_gitmodules
+)
+ (fn, ...)
+|
+repo_config(R, fn, ...)
+)
+
+@ extends get_fn @
+identifier C1, C2, D;
+@@
+int fn(const char *C1, const char *C2,
++ const struct config_context *ctx,
+ void *D);
+
+@ extends get_fn @
+@@
+int fn(const char *, const char *,
++ const struct config_context *,
+ void *);
+
+@ extends get_fn @
+// Don't change fns that look like callback fns but aren't
+identifier fn2 != tar_filter_config && != git_diff_heuristic_config &&
+ != git_default_submodule_config && != git_color_config &&
+ != bundle_list_update && != parse_object_filter_config;
+identifier C1, C2, D1, D2, S;
+attribute name UNUSED;
+@@
+int fn(const char *C1, const char *C2,
++ const struct config_context *ctx,
+ void *D1) {
+<+...
+(
+fn2(C1, C2
++ , ctx
+, D2);
+|
+if(fn2(C1, C2
++ , ctx
+, D2) < 0) { ... }
+|
+return fn2(C1, C2
++ , ctx
+, D2);
+|
+S = fn2(C1, C2
++ , ctx
+, D2);
+)
+...+>
+ }
+
+@ extends get_fn@
+identifier C1, C2, D;
+attribute name UNUSED;
+@@
+int fn(const char *C1, const char *C2,
++ const struct config_context *ctx UNUSED,
+ void *D) {...}
+
+
+// The previous rules don't catch all callbacks, especially if they're defined
+// in a separate file from the git_config() call. Fix these manually.
+@@
+identifier C1, C2, D;
+attribute name UNUSED;
+@@
+int
+(
+git_ident_config
+|
+urlmatch_collect_fn
+|
+write_one_config
+|
+forbid_remote_url
+|
+credential_config_callback
+)
+ (const char *C1, const char *C2,
++ const struct config_context *ctx UNUSED,
+ void *D) {...}
+
+@@
+identifier C1, C2, D, D2, S, fn2;
+@@
+int
+(
+http_options
+|
+git_status_config
+|
+git_commit_config
+|
+git_default_core_config
+|
+grep_config
+)
+ (const char *C1, const char *C2,
++ const struct config_context *ctx,
+ void *D) {
+<+...
+(
+fn2(C1, C2
++ , ctx
+, D2);
+|
+if(fn2(C1, C2
++ , ctx
+, D2) < 0) { ... }
+|
+return fn2(C1, C2
++ , ctx
+, D2);
+|
+S = fn2(C1, C2
++ , ctx
+, D2);
+)
+...+>
+ }
diff --git a/contrib/coccinelle/git_config_number.cocci b/contrib/coccinelle/git_config_number.cocci
new file mode 100644
index 0000000000..7b57dceefe
--- /dev/null
+++ b/contrib/coccinelle/git_config_number.cocci
@@ -0,0 +1,27 @@
+@@
+identifier C1, C2, C3;
+@@
+(
+(
+git_config_int
+|
+git_config_int64
+|
+git_config_ulong
+|
+git_config_ssize_t
+)
+ (C1, C2
++ , ctx->kvi
+ )
+|
+(
+git_configset_get_value
+|
+git_config_bool_or_int
+)
+ (C1, C2
++ , ctx->kvi
+ , C3
+ )
+)