* 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