File src/fops_cpmv.c changed (mode: 100644) (index 5b56e719c..88aaa8922) |
... |
... |
set_cpmv_bg_descr(bg_op_t *bg_op, bg_args_t *args, size_t i) |
628 |
628 |
/* Start with the source path. */ |
/* Start with the source path. */ |
629 |
629 |
const char *descr = src; |
const char *descr = src; |
630 |
630 |
|
|
|
631 |
|
/* Try shorten the path using tilde and use that if it worked. */ |
|
632 |
|
char *tilde_src = make_tilde_path(src); |
|
633 |
|
if(tilde_src != NULL) |
|
634 |
|
{ |
|
635 |
|
descr = tilde_src; |
|
636 |
|
} |
|
637 |
|
|
631 |
638 |
/* In case there are multiple files to process, prepend current position. */ |
/* In case there are multiple files to process, prepend current position. */ |
632 |
639 |
char *stats = NULL; |
char *stats = NULL; |
633 |
640 |
if(args->sel_list_len > 1) |
if(args->sel_list_len > 1) |
|
... |
... |
set_cpmv_bg_descr(bg_op_t *bg_op, bg_args_t *args, size_t i) |
643 |
650 |
|
|
644 |
651 |
bg_op_set_descr(bg_op, descr); |
bg_op_set_descr(bg_op, descr); |
645 |
652 |
|
|
|
653 |
|
free(tilde_src); |
646 |
654 |
free(stats); |
free(stats); |
647 |
655 |
} |
} |
648 |
656 |
|
|
File src/utils/path.c changed (mode: 100644) (index 5eb8bef64..bf73357c3) |
32 |
32 |
#include <stddef.h> /* NULL size_t */ |
#include <stddef.h> /* NULL size_t */ |
33 |
33 |
#include <stdio.h> /* snprintf() */ |
#include <stdio.h> /* snprintf() */ |
34 |
34 |
#include <stdlib.h> /* free() */ |
#include <stdlib.h> /* free() */ |
35 |
|
#include <string.h> /* memset() strcat() strcmp() strdup() strncmp() strncat() |
|
36 |
|
strchr() strcpy() strlen() strpbrk() strrchr() */ |
|
|
35 |
|
#include <string.h> /* memset() strcat() strcmp() strdup() strncmp() strchr() |
|
36 |
|
strcpy() strlen() strpbrk() strrchr() */ |
37 |
37 |
|
|
38 |
38 |
#include "../cfg/config.h" |
#include "../cfg/config.h" |
39 |
39 |
#include "../compat/fs_limits.h" |
#include "../compat/fs_limits.h" |
|
45 |
45 |
#include "utils.h" |
#include "utils.h" |
46 |
46 |
|
|
47 |
47 |
static int skip_dotdir_if_any(const char *path[], int has_parent); |
static int skip_dotdir_if_any(const char *path[], int has_parent); |
|
48 |
|
static const char * find_home_tail(const char path[]); |
48 |
49 |
static char * try_replace_tilde(const char path[]); |
static char * try_replace_tilde(const char path[]); |
49 |
50 |
static char * find_ext_dot(const char path[]); |
static char * find_ext_dot(const char path[]); |
50 |
51 |
|
|
|
... |
... |
char * |
369 |
370 |
replace_home_part_strict(const char path[]) |
replace_home_part_strict(const char path[]) |
370 |
371 |
{ |
{ |
371 |
372 |
static char buf[PATH_MAX + 1]; |
static char buf[PATH_MAX + 1]; |
372 |
|
size_t len; |
|
373 |
373 |
|
|
374 |
|
len = strlen(cfg.home_dir) - 1; |
|
375 |
|
if(strnoscmp(path, cfg.home_dir, len) == 0 && |
|
376 |
|
(path[len] == '\0' || path[len] == '/')) |
|
|
374 |
|
const char *home_tail = find_home_tail(path); |
|
375 |
|
if(home_tail == NULL) |
377 |
376 |
{ |
{ |
378 |
|
strncat(strcpy(buf, "~"), path + len, sizeof(buf) - strlen(buf) - 1); |
|
|
377 |
|
copy_str(buf, sizeof(buf), path); |
379 |
378 |
} |
} |
380 |
379 |
else |
else |
381 |
380 |
{ |
{ |
382 |
|
copy_str(buf, sizeof(buf), path); |
|
|
381 |
|
buf[0] = '~'; |
|
382 |
|
buf[1] = '/'; |
|
383 |
|
copy_str(buf + 2, sizeof(buf) - 2, home_tail); |
383 |
384 |
} |
} |
384 |
385 |
|
|
385 |
386 |
return buf; |
return buf; |
386 |
387 |
} |
} |
387 |
388 |
|
|
|
389 |
|
char * |
|
390 |
|
make_tilde_path(const char path[]) |
|
391 |
|
{ |
|
392 |
|
const char *home_tail = find_home_tail(path); |
|
393 |
|
if(home_tail == NULL) |
|
394 |
|
{ |
|
395 |
|
return strdup(path); |
|
396 |
|
} |
|
397 |
|
|
|
398 |
|
return format_str("~/%s", home_tail); |
|
399 |
|
} |
|
400 |
|
|
|
401 |
|
/* Finds part of the path which follows home directory and any number of slashes |
|
402 |
|
* after it. Returns pointer to the part or NULL if it's not present. */ |
|
403 |
|
static const char * |
|
404 |
|
find_home_tail(const char path[]) |
|
405 |
|
{ |
|
406 |
|
const size_t len = strlen(cfg.home_dir) - 1; |
|
407 |
|
|
|
408 |
|
/* Not using path_starts_with() because cfg.home_dir always ends with a slash |
|
409 |
|
* and this way we can avoid repeating strlen(). */ |
|
410 |
|
if(strnoscmp(path, cfg.home_dir, len) == 0 && |
|
411 |
|
(path[len] == '\0' || path[len] == '/')) |
|
412 |
|
{ |
|
413 |
|
return skip_char(path + len, '/'); |
|
414 |
|
} |
|
415 |
|
|
|
416 |
|
return NULL; |
|
417 |
|
} |
|
418 |
|
|
388 |
419 |
char * |
char * |
389 |
420 |
expand_tilde(const char path[]) |
expand_tilde(const char path[]) |
390 |
421 |
{ |
{ |
File src/utils/path.h changed (mode: 100644) (index 879d0cb83..2bf2d8b02) |
... |
... |
char * replace_home_part(const char path[]); |
57 |
57 |
/* Same as replace_home_part(), but doesn't perform trailing slash trimming. */ |
/* Same as replace_home_part(), but doesn't perform trailing slash trimming. */ |
58 |
58 |
char * replace_home_part_strict(const char path[]); |
char * replace_home_part_strict(const char path[]); |
59 |
59 |
|
|
|
60 |
|
/* Same as replace_home_part_strict(), but always returns a newly allocated |
|
61 |
|
* string if memory allocation was successful. */ |
|
62 |
|
char * make_tilde_path(const char path[]); |
|
63 |
|
|
60 |
64 |
/* Expands tilde in the front of the path. Does nothing for paths without |
/* Expands tilde in the front of the path. Does nothing for paths without |
61 |
65 |
* tilde. Returns newly allocated string without tilde. */ |
* tilde. Returns newly allocated string without tilde. */ |
62 |
66 |
char * expand_tilde(const char path[]); |
char * expand_tilde(const char path[]); |
File tests/fileops/cpmv_files.c changed (mode: 100644) (index 9a5466a2c..50e4f79be) |
... |
... |
TEST(can_skip_existing_files) |
502 |
502 |
|
|
503 |
503 |
TEST(bg_jog_has_correct_title) |
TEST(bg_jog_has_correct_title) |
504 |
504 |
{ |
{ |
|
505 |
|
/* To test the use of ~. */ |
|
506 |
|
make_abs_path(cfg.home_dir, sizeof(cfg.home_dir), SANDBOX_PATH, "/", |
|
507 |
|
saved_cwd); |
|
508 |
|
|
505 |
509 |
make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), SANDBOX_PATH, "dir", |
make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), SANDBOX_PATH, "dir", |
506 |
510 |
saved_cwd); |
saved_cwd); |
507 |
511 |
|
|
|
... |
... |
TEST(bg_jog_has_correct_title) |
516 |
520 |
lwin.dir_entry[1].origin = &lwin.curr_dir[0]; |
lwin.dir_entry[1].origin = &lwin.curr_dir[0]; |
517 |
521 |
lwin.dir_entry[1].marked = 1; |
lwin.dir_entry[1].marked = 1; |
518 |
522 |
|
|
519 |
|
char last_src_file[PATH_MAX + 1]; |
|
520 |
|
make_abs_path(last_src_file, sizeof(last_src_file), SANDBOX_PATH, "dir/file2", |
|
521 |
|
saved_cwd); |
|
522 |
|
|
|
523 |
|
char descr[PATH_MAX + 1]; |
|
524 |
|
snprintf(descr, sizeof(descr), "2/2 %s", last_src_file); |
|
525 |
|
|
|
526 |
523 |
wait_for_all_bg(); |
wait_for_all_bg(); |
527 |
524 |
(void)fops_cpmv_bg(&lwin, NULL, 0, CMLO_COPY, CMLF_SKIP); |
(void)fops_cpmv_bg(&lwin, NULL, 0, CMLO_COPY, CMLF_SKIP); |
528 |
525 |
wait_for_bg(); |
wait_for_bg(); |
529 |
|
assert_string_equal(descr, bg_jobs->bg_op.descr); |
|
|
526 |
|
assert_string_equal("2/2 ~/dir/file2", bg_jobs->bg_op.descr); |
530 |
527 |
|
|
531 |
528 |
remove_file("file"); |
remove_file("file"); |
532 |
529 |
remove_file("file2"); |
remove_file("file2"); |
533 |
530 |
remove_file("dir/file"); |
remove_file("dir/file"); |
534 |
531 |
remove_file("dir/file2"); |
remove_file("dir/file2"); |
535 |
532 |
remove_dir("dir"); |
remove_dir("dir"); |
|
533 |
|
|
|
534 |
|
cfg.home_dir[0] = '\0'; |
536 |
535 |
} |
} |
537 |
536 |
|
|
538 |
537 |
TEST(broken_link_behaves_like_a_regular_file_on_conflict, IF(not_windows)) |
TEST(broken_link_behaves_like_a_regular_file_on_conflict, IF(not_windows)) |