summaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
Diffstat (limited to 'editors')
-rw-r--r--editors/diff.c27
-rw-r--r--editors/vi.c20
2 files changed, 35 insertions, 12 deletions
diff --git a/editors/diff.c b/editors/diff.c
index 07594e8..a3ca2b6 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -121,6 +121,7 @@ typedef struct FILE_and_pos_t {
struct globals {
smallint exit_status;
int opt_U_context;
+ const char *other_dir;
char *label[2];
struct stat stb[2];
};
@@ -760,9 +761,11 @@ static int FAST_FUNC add_to_dirlist(const char *filename,
void *userdata, int depth UNUSED_PARAM)
{
struct dlist *const l = userdata;
+ const char *file = filename + l->len;
+ while (*file == '/')
+ file++;
l->dl = xrealloc_vector(l->dl, 6, l->e);
- /* + 1 skips "/" after dirname */
- l->dl[l->e] = xstrdup(filename + l->len + 1);
+ l->dl[l->e] = xstrdup(file);
l->e++;
return TRUE;
}
@@ -778,6 +781,25 @@ static int FAST_FUNC skip_dir(const char *filename,
add_to_dirlist(filename, sb, userdata, depth);
return SKIP;
}
+ if (!(option_mask32 & FLAG(N))) {
+ /* -r without -N: no need to recurse into dirs
+ * which do not exist on the "other side".
+ * Testcase: diff -r /tmp /
+ * (it would recurse deep into /proc without this code) */
+ struct dlist *const l = userdata;
+ filename += l->len;
+ if (filename[0]) {
+ struct stat osb;
+ char *othername = concat_path_file(G.other_dir, filename);
+ int r = stat(othername, &osb);
+ free(othername);
+ if (r != 0 || !S_ISDIR(osb.st_mode)) {
+ /* other dir doesn't have similarly named
+ * directory, don't recurse */
+ return SKIP;
+ }
+ }
+ }
return TRUE;
}
@@ -791,6 +813,7 @@ static void diffdir(char *p[2], const char *s_start)
/*list[i].s = list[i].e = 0; - memset did it */
/*list[i].dl = NULL; */
+ G.other_dir = p[1 - i];
/* We need to trim root directory prefix.
* Using list.len to specify its length,
* add_to_dirlist will remove it. */
diff --git a/editors/vi.c b/editors/vi.c
index 0f412c3..73e095c 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -504,20 +504,17 @@ static int init_text_buffer(char *fn)
}
#if ENABLE_FEATURE_VI_WIN_RESIZE
-static void query_screen_dimensions(void)
+static int query_screen_dimensions(void)
{
-# if ENABLE_FEATURE_VI_ASK_TERMINAL
- if (!G.get_rowcol_error)
- G.get_rowcol_error =
-# endif
- get_terminal_width_height(STDIN_FILENO, &columns, &rows);
+ int err = get_terminal_width_height(STDIN_FILENO, &columns, &rows);
if (rows > MAX_SCR_ROWS)
rows = MAX_SCR_ROWS;
if (columns > MAX_SCR_COLS)
columns = MAX_SCR_COLS;
+ return err;
}
#else
-# define query_screen_dimensions() ((void)0)
+# define query_screen_dimensions() (0)
#endif
static void edit_file(char *fn)
@@ -536,7 +533,7 @@ static void edit_file(char *fn)
rows = 24;
columns = 80;
size = 0;
- query_screen_dimensions();
+ IF_FEATURE_VI_ASK_TERMINAL(G.get_rowcol_error =) query_screen_dimensions();
#if ENABLE_FEATURE_VI_ASK_TERMINAL
if (G.get_rowcol_error /* TODO? && no input on stdin */) {
uint64_t k;
@@ -546,9 +543,12 @@ static void edit_file(char *fn)
if ((int32_t)k == KEYCODE_CURSOR_POS) {
uint32_t rc = (k >> 32);
columns = (rc & 0x7fff);
+ if (columns > MAX_SCR_COLS)
+ columns = MAX_SCR_COLS;
rows = ((rc >> 16) & 0x7fff);
+ if (rows > MAX_SCR_ROWS)
+ rows = MAX_SCR_ROWS;
}
- query_screen_dimensions();
}
#endif
new_screen(rows, columns); // get memory for virtual screen
@@ -2797,7 +2797,7 @@ static void refresh(int full_screen)
int li, changed;
char *tp, *sp; // pointer into text[] and screen[]
- if (ENABLE_FEATURE_VI_WIN_RESIZE) {
+ if (ENABLE_FEATURE_VI_WIN_RESIZE IF_FEATURE_VI_ASK_TERMINAL(&& !G.get_rowcol_error) ) {
unsigned c = columns, r = rows;
query_screen_dimensions();
full_screen |= (c - columns) | (r - rows);