Split "rel-path-from-abs-paths" into function
This commit is contained in:
parent
6376be2840
commit
b09948d245
4 changed files with 73 additions and 40 deletions
|
@ -83,6 +83,7 @@ add_executable(test_simplearchiver
|
||||||
src/test.c
|
src/test.c
|
||||||
src/parser.c
|
src/parser.c
|
||||||
src/helpers.c
|
src/helpers.c
|
||||||
|
src/archiver.c
|
||||||
src/algorithms/linear_congruential_gen.c
|
src/algorithms/linear_congruential_gen.c
|
||||||
src/data_structures/linked_list.c
|
src/data_structures/linked_list.c
|
||||||
src/data_structures/hash_map.c
|
src/data_structures/hash_map.c
|
||||||
|
|
|
@ -767,46 +767,8 @@ int write_files_fn(void *data, void *ud) {
|
||||||
// fprintf(stderr, "DEBUG: abs_path: %s\nDEBUG: link_abs_path: %s\n",
|
// fprintf(stderr, "DEBUG: abs_path: %s\nDEBUG: link_abs_path: %s\n",
|
||||||
// (char*)abs_path, (char*)link_abs_path);
|
// (char*)abs_path, (char*)link_abs_path);
|
||||||
|
|
||||||
// Compare paths to get relative path.
|
rel_path =
|
||||||
// Get first non-common char.
|
simple_archiver_filenames_to_relative_path(link_abs_path, abs_path);
|
||||||
size_t idx;
|
|
||||||
size_t last_slash;
|
|
||||||
for (idx = 0, last_slash = 0;
|
|
||||||
idx < strlen(abs_path) && idx < strlen(link_abs_path); ++idx) {
|
|
||||||
if (((const char *)abs_path)[idx] !=
|
|
||||||
((const char *)link_abs_path)[idx]) {
|
|
||||||
break;
|
|
||||||
} else if (((const char *)abs_path)[idx] == '/') {
|
|
||||||
last_slash = idx + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Get substrings of both paths.
|
|
||||||
char *link_substr = (char *)link_abs_path + last_slash;
|
|
||||||
char *dest_substr = (char *)abs_path + last_slash;
|
|
||||||
rel_path = malloc(strlen(dest_substr) + 1);
|
|
||||||
strncpy(rel_path, dest_substr, strlen(dest_substr) + 1);
|
|
||||||
// fprintf(stderr, "DEBUG: link_substr: %s\nDEBUG: dest_substr: %s\n",
|
|
||||||
// link_substr, dest_substr);
|
|
||||||
|
|
||||||
// Generate the relative path.
|
|
||||||
int_fast8_t has_slash = 0;
|
|
||||||
idx = 0;
|
|
||||||
do {
|
|
||||||
for (; link_substr[idx] != '/' && link_substr[idx] != 0; ++idx);
|
|
||||||
if (link_substr[idx] == 0) {
|
|
||||||
has_slash = 0;
|
|
||||||
} else {
|
|
||||||
has_slash = 1;
|
|
||||||
char *new_rel_path = malloc(strlen(rel_path) + 1 + 3);
|
|
||||||
new_rel_path[0] = '.';
|
|
||||||
new_rel_path[1] = '.';
|
|
||||||
new_rel_path[2] = '/';
|
|
||||||
strncpy(new_rel_path + 3, rel_path, strlen(rel_path) + 1);
|
|
||||||
free(rel_path);
|
|
||||||
rel_path = new_rel_path;
|
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
} while (has_slash);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3015,3 +2977,53 @@ int simple_archiver_de_compress(int pipe_fd_in[2], int pipe_fd_out[2],
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *simple_archiver_filenames_to_relative_path(const char *from_abs,
|
||||||
|
const char *to_abs) {
|
||||||
|
if (!from_abs || !to_abs) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get first non-common char and last slash before it.
|
||||||
|
uint_fast32_t idx;
|
||||||
|
uint_fast32_t last_slash;
|
||||||
|
for (idx = 0, last_slash = 0; idx < strlen(from_abs) && idx < strlen(to_abs);
|
||||||
|
++idx) {
|
||||||
|
if (((const char *)to_abs)[idx] != ((const char *)from_abs)[idx]) {
|
||||||
|
break;
|
||||||
|
} else if (((const char *)to_abs)[idx] == '/') {
|
||||||
|
last_slash = idx + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get substrings of both paths.
|
||||||
|
char *link_substr = (char *)from_abs + last_slash;
|
||||||
|
char *dest_substr = (char *)to_abs + last_slash;
|
||||||
|
char *rel_path = malloc(strlen(dest_substr) + 1);
|
||||||
|
strncpy(rel_path, dest_substr, strlen(dest_substr) + 1);
|
||||||
|
|
||||||
|
// fprintf(stderr, "DEBUG: link_substr \"%s\", dest_substr \"%s\"\n",
|
||||||
|
// link_substr, dest_substr);
|
||||||
|
|
||||||
|
// Get the relative path finally.
|
||||||
|
int_fast8_t has_slash = 0;
|
||||||
|
idx = 0;
|
||||||
|
do {
|
||||||
|
for (; link_substr[idx] != '/' && link_substr[idx] != 0; ++idx);
|
||||||
|
if (link_substr[idx] == 0) {
|
||||||
|
has_slash = 0;
|
||||||
|
} else {
|
||||||
|
has_slash = 1;
|
||||||
|
char *new_rel_path = malloc(strlen(rel_path) + 1 + 3);
|
||||||
|
new_rel_path[0] = '.';
|
||||||
|
new_rel_path[1] = '.';
|
||||||
|
new_rel_path[2] = '/';
|
||||||
|
strncpy(new_rel_path + 3, rel_path, strlen(rel_path) + 1);
|
||||||
|
free(rel_path);
|
||||||
|
rel_path = new_rel_path;
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
} while (has_slash);
|
||||||
|
|
||||||
|
return rel_path;
|
||||||
|
}
|
||||||
|
|
|
@ -88,4 +88,8 @@ int simple_archiver_parse_archive_version_1(FILE *in_f, int_fast8_t do_extract,
|
||||||
int simple_archiver_de_compress(int pipe_fd_in[2], int pipe_fd_out[2],
|
int simple_archiver_de_compress(int pipe_fd_in[2], int pipe_fd_out[2],
|
||||||
const char *cmd, void *pid_out);
|
const char *cmd, void *pid_out);
|
||||||
|
|
||||||
|
/// If returns non-NULL, must be free'd.
|
||||||
|
char *simple_archiver_filenames_to_relative_path(const char *from_abs,
|
||||||
|
const char *to_abs);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
16
src/test.c
16
src/test.c
|
@ -23,6 +23,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// Local includes.
|
// Local includes.
|
||||||
|
#include "archiver.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "parser_internal.h"
|
#include "parser_internal.h"
|
||||||
|
|
||||||
|
@ -241,6 +242,21 @@ int main(void) {
|
||||||
free(out);
|
free(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test archiver.
|
||||||
|
{
|
||||||
|
__attribute__((
|
||||||
|
cleanup(simple_archiver_helper_cleanup_c_string))) char *rel_path =
|
||||||
|
simple_archiver_filenames_to_relative_path(
|
||||||
|
"/one/two/three/four/five", "/one/two/branch/other/path");
|
||||||
|
CHECK_STREQ(rel_path, "../../branch/other/path");
|
||||||
|
simple_archiver_helper_cleanup_c_string(&rel_path);
|
||||||
|
|
||||||
|
rel_path = simple_archiver_filenames_to_relative_path(
|
||||||
|
"/one/two/three/four/five", "/one/two/three/other/dir/");
|
||||||
|
CHECK_STREQ(rel_path, "../other/dir/");
|
||||||
|
simple_archiver_helper_cleanup_c_string(&rel_path);
|
||||||
|
}
|
||||||
|
|
||||||
printf("Checks checked: %u\n", checks_checked);
|
printf("Checks checked: %u\n", checks_checked);
|
||||||
printf("Checks passed: %u\n", checks_passed);
|
printf("Checks passed: %u\n", checks_passed);
|
||||||
return checks_passed == checks_checked ? 0 : 1;
|
return checks_passed == checks_checked ? 0 : 1;
|
||||||
|
|
Loading…
Reference in a new issue