[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/4] Introduce guess strip (-pg) option
From: |
Vladimir D. Seleznev |
Subject: |
[PATCH 1/4] Introduce guess strip (-pg) option |
Date: |
Sat, 11 Jan 2020 18:17:30 +0300 |
* src/common.h: Add guess_strip flag variable.
* src/patch.c: Make '-p' and '--strip' commandline option understand 'g'
argument.
* src/util.c (strip_leading_slashes): Eliminate the longest existent
pathname to patch.
New option make the patch utility try to eliminate the longest existent
pathname to patch.
---
src/common.h | 1 +
src/patch.c | 9 ++++++++-
src/util.c | 19 +++++++++++++++++++
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/src/common.h b/src/common.h
index 53c5e3282..986f57c7a 100644
--- a/src/common.h
+++ b/src/common.h
@@ -113,6 +113,7 @@ XTERN bool reverse;
XTERN enum { DEFAULT_VERBOSITY, SILENT, VERBOSE } verbosity;
XTERN bool skip_rest_of_patch;
XTERN int strippath;
+XTERN bool guess_strip;
XTERN bool canonicalize_ws;
XTERN int patch_get;
XTERN bool set_time;
diff --git a/src/patch.c b/src/patch.c
index 917437095..9d1a92143 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -135,6 +135,7 @@ main (int argc, char **argv)
buf = xmalloc (bufsize);
strippath = -1;
+ guess_strip = false;
val = getenv ("QUOTING_STYLE");
{
@@ -970,7 +971,13 @@ get_some_switches (void)
outfile = xstrdup (optarg);
break;
case 'p':
- strippath = numeric_string (optarg, false, "strip count");
+ if (!strcmp(optarg, "g")) {
+ guess_strip = true;
+ strippath = -1;
+ } else {
+ strippath = numeric_string (optarg, false, "strip count");
+ guess_strip = false;
+ }
break;
case 'r':
rejname = xstrdup (optarg);
diff --git a/src/util.c b/src/util.c
index 392eff19d..15a374dcf 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1422,18 +1422,37 @@ fail:
/* Strip up to STRIP_LEADING leading slashes.
If STRIP_LEADING is negative, strip all leading slashes.
+ If GUESS_STRIP is true, try to guess how many leading slashes
+ should be stripped.
Returns a pointer into NAME on success, and NULL otherwise.
*/
static bool
strip_leading_slashes (char *name, int strip_leading)
{
int s = strip_leading;
+ int gs = 0;
char *p, *n;
for (p = n = name; *p; p++)
{
if (ISSLASH (*p))
{
+ if (guess_strip && strip_leading == -1)
+ {
+ struct stat st;
+ /* If "n" is an existent file and is not a directory,
+ we successfully guessed strip. */
+ if (safe_stat (n, &st) == 0 && !(st.st_mode & S_IFDIR))
+ {
+ /* We guessed the strip value. As this value should
+ be the same for each files being patched, assign
+ global strippath to this value. */
+ strippath = gs;
+ break;
+ }
+ gs++;
+ }
+
while (ISSLASH (p[1]))
p++;
if (strip_leading < 0 || --s >= 0)
--
2.24.1