Page MenuHomeFreeBSD

D30160.diff
No OneTemporary

D30160.diff

diff --git a/usr.bin/patch/common.h b/usr.bin/patch/common.h
--- a/usr.bin/patch/common.h
+++ b/usr.bin/patch/common.h
@@ -84,6 +84,7 @@
extern int debug;
#endif
+extern bool search;
extern bool force;
extern bool batch;
extern bool verbose;
diff --git a/usr.bin/patch/patch.1 b/usr.bin/patch/patch.1
--- a/usr.bin/patch/patch.1
+++ b/usr.bin/patch/patch.1
@@ -21,7 +21,7 @@
.\"
.\" $OpenBSD: patch.1,v 1.27 2014/04/15 06:26:54 jmc Exp $
.\" $FreeBSD$
-.Dd November 3, 2019
+.Dd May 10, 2021
.Dt PATCH 1
.Os
.Sh NAME
@@ -39,6 +39,7 @@
.Op Fl o Ar out-file
.Op Fl p Ar strip-count
.Op Fl r Ar rej-name
+.Op Fl S
.Op Fl V Cm t | nil | never | none
.Op Fl x Ar number
.Op Fl z Ar backup-ext
@@ -281,6 +282,16 @@
Makes
.Nm
do its work silently, unless an error occurs.
+.It Fl S , Fl Fl search
+Tells
+.Nm
+to search the current directory for a maching file by
+.Xr basename 1 ,
+if the file in the patch doesn't exist.
+To change the searching directory use the
+.Fl d
+option.
+When searching for a file, the first match is selected, if any.
.It Fl t , Fl Fl batch
Similar to
.Fl f ,
diff --git a/usr.bin/patch/patch.c b/usr.bin/patch/patch.c
--- a/usr.bin/patch/patch.c
+++ b/usr.bin/patch/patch.c
@@ -75,6 +75,7 @@
int debug = 0;
#endif
+bool search = false;
bool force = false;
bool batch = false;
bool verbose = true;
@@ -519,7 +520,7 @@
static void
get_some_switches(void)
{
- const char *options = "b::B:cCd:D:eEfF:i:lnNo:p:r:RstuvV:x:z:";
+ const char *options = "b::B:cCd:D:eEfF:i:lnNo:p:r:RsStuvV:x:z:";
static struct option longopts[] = {
{"backup", no_argument, 0, 'b'},
{"batch", no_argument, 0, 't'},
@@ -543,6 +544,7 @@
{"remove-empty-files", no_argument, 0, 'E'},
{"reverse", no_argument, 0, 'R'},
{"silent", no_argument, 0, 's'},
+ {"search", no_argument, 0, 'S'},
{"strip", required_argument, 0, 'p'},
{"suffix", required_argument, 0, 'z'},
{"unified", no_argument, 0, 'u'},
@@ -642,6 +644,9 @@
case 's':
verbose = false;
break;
+ case 'S':
+ search = true;
+ break;
case 't':
batch = true;
break;
@@ -691,7 +696,7 @@
"usage: patch [-bCcEeflNnRstuv] [-B backup-prefix] [-D symbol] [-d directory]\n"
" [-F max-fuzz] [-i patchfile] [-o out-file] [-p strip-count]\n"
" [-r rej-name] [-V t | nil | never | none] [-x number]\n"
-" [-z backup-ext] [--posix] [origfile [patchfile]]\n"
+" [-z backup-ext] [--posix] [-S] [origfile [patchfile]]\n"
" patch <patchfile\n");
my_exit(EXIT_FAILURE);
}
diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c
--- a/usr.bin/patch/pch.c
+++ b/usr.bin/patch/pch.c
@@ -208,17 +208,50 @@
p_indent == 1 ? "" : "s");
skip_to(p_start, p_sline);
while (filearg[0] == NULL) {
+ if (search) {
+ char *presult;
+ int temp = 0;
+
+ presult = find_file(".", ".", basename(bestguess), &temp);
+ if (presult != NULL) {
+ say("Found file at new location: %s\n", presult);
+ free(bestguess);
+ bestguess = presult;
+ filearg[0] = fetchname(bestguess, &exists, 0);
+ return true;
+ }
+ }
if (force || batch) {
say("No file to patch. Skipping...\n");
filearg[0] = xstrdup(bestguess);
skip_rest_of_patch = true;
return true;
}
- ask("File to patch: ");
+ ask("File to patch (enter '/' to search): ");
if (*buf != '\n') {
- free(bestguess);
- bestguess = xstrdup(buf);
- filearg[0] = fetchname(buf, &exists, 0);
+ if (strcmp(buf, "/") == 0) {
+ for (int match = 0;; match++) {
+ char *presult;
+ int temp;
+
+ temp = match;
+ presult = find_file(".", ".", basename(bestguess), &temp);
+ if (presult == NULL)
+ break;
+ ask("Select this file, %s [y]: ", presult);
+ if (*buf != 'n') {
+ free(bestguess);
+ bestguess = presult;
+ filearg[0] = fetchname(bestguess, &exists, 0);
+ break;
+ }
+ free(presult);
+ }
+ } else {
+ free(bestguess);
+ bestguess = xstrdup(buf);
+ filearg[0] = fetchname(buf, &exists, 0);
+ }
}
/*
* fetchname can now return buf = NULL, exists = true, to
diff --git a/usr.bin/patch/util.h b/usr.bin/patch/util.h
--- a/usr.bin/patch/util.h
+++ b/usr.bin/patch/util.h
@@ -46,6 +46,7 @@
void makedirs(const char *, bool);
void version(void);
void my_exit(int) __attribute__((noreturn));
+char * find_file(const char *, const char *, const char *, int *);
/* in mkpath.c */
extern int mkpath(char *);
diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c
--- a/usr.bin/patch/util.c
+++ b/usr.bin/patch/util.c
@@ -41,6 +41,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <dirent.h>
#include "common.h"
#include "util.h"
@@ -422,3 +423,82 @@
unlink(TMPPATNAME);
exit(status);
}
+
+/*
+ * Search for file recursivly.
+ */
+char *
+find_file(const char *bname, const char *dname, const char *fname, int *pmatch)
+{
+#if __BSD_VISIBLE == 0
+ struct stat filestat;
+ char *stmp;
+#endif
+ struct dirent *dp;
+ char *retval;
+ char *ddir;
+ DIR *dirp;
+ int len;
+
+ if (strcmp(bname, ".") == 0 && strcmp(dname, ".") == 0) {
+ if (asprintf(&ddir, ".") < 0)
+ return (NULL);
+ } else {
+ if (asprintf(&ddir, "%s/%s", bname, dname) < 0)
+ return (NULL);
+ }
+
+ dirp = opendir(ddir);
+ retval = NULL;
+
+ if (dirp == NULL) {
+ free(ddir);
+ return (NULL);
+ }
+
+ len = strlen(fname);
+ while ((dp = readdir(dirp)) != NULL) {
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+#if __BSD_VISIBLE == 0
+ if (asprintf(&stmp, "%s/%s", ddir, dp->d_name) < 0)
+ continue;
+ stat(stmp, &filestat);
+ free(stmp);
+
+ if (S_ISDIR(filestat.st_mode))
+ goto found_directory;
+ else if (S_ISREG(filestat.st_mode))
+ goto found_regular_file;
+ else
+ continue;
+#else
+ switch (dp->d_type) {
+ case DT_DIR:
+ goto found_directory;
+ case DT_REG:
+ goto found_regular_file;
+ default:
+ continue;
+ }
+#endif
+found_directory:
+ retval = find_file(ddir, dp->d_name, fname, pmatch);
+ if (retval != NULL)
+ goto done;
+ continue;
+found_regular_file:
+ if (dp->d_namlen == len &&
+ strcmp(dp->d_name, fname) == 0 &&
+ (*pmatch)-- == 0) {
+ if (asprintf(&retval, "%s/%s", ddir, fname) < 0)
+ retval = NULL;
+ goto done;
+ }
+ }
+done:
+ closedir(dirp);
+ free(ddir);
+ return (retval);
+}

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 18, 2:56 PM (2 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15867304
Default Alt Text
D30160.diff (6 KB)

Event Timeline