David Reiss | ae299be | 2008-05-19 23:48:54 -0700 | [diff] [blame] | 1 | #include "cache.h" |
Michael Haggerty | 31171d9 | 2012-10-28 17:16:24 +0100 | [diff] [blame] | 2 | #include "string-list.h" |
David Reiss | ae299be | 2008-05-19 23:48:54 -0700 | [diff] [blame] | 3 | |
Michael Haggerty | 9e2326c | 2012-10-28 17:16:25 +0100 | [diff] [blame] | 4 | /* |
| 5 | * A "string_list_each_func_t" function that normalizes an entry from |
| 6 | * GIT_CEILING_DIRECTORIES. If the path is unusable for some reason, |
| 7 | * die with an explanation. |
| 8 | */ |
| 9 | static int normalize_ceiling_entry(struct string_list_item *item, void *unused) |
| 10 | { |
| 11 | const char *ceil = item->string; |
| 12 | int len = strlen(ceil); |
| 13 | char buf[PATH_MAX+1]; |
| 14 | |
| 15 | if (len == 0) |
| 16 | die("Empty path is not supported"); |
| 17 | if (len > PATH_MAX) |
| 18 | die("Path \"%s\" is too long", ceil); |
| 19 | if (!is_absolute_path(ceil)) |
| 20 | die("Path \"%s\" is not absolute", ceil); |
| 21 | if (normalize_path_copy(buf, ceil) < 0) |
| 22 | die("Path \"%s\" could not be normalized", ceil); |
| 23 | len = strlen(buf); |
| 24 | if (len > 1 && buf[len-1] == '/') |
| 25 | die("Normalized path \"%s\" ended with slash", buf); |
| 26 | free(item->string); |
| 27 | item->string = xstrdup(buf); |
| 28 | return 1; |
| 29 | } |
| 30 | |
Jiang Xin | 203439b | 2013-06-25 23:53:42 +0800 | [diff] [blame] | 31 | static void normalize_argv_string(const char **var, const char *input) |
| 32 | { |
| 33 | if (!strcmp(input, "<null>")) |
| 34 | *var = NULL; |
| 35 | else if (!strcmp(input, "<empty>")) |
| 36 | *var = ""; |
| 37 | else |
| 38 | *var = input; |
| 39 | |
| 40 | if (*var && (**var == '<' || **var == '(')) |
| 41 | die("Bad value: %s\n", input); |
| 42 | } |
| 43 | |
David Reiss | ae299be | 2008-05-19 23:48:54 -0700 | [diff] [blame] | 44 | int main(int argc, char **argv) |
| 45 | { |
Johannes Sixt | f42302b | 2009-02-07 16:08:30 +0100 | [diff] [blame] | 46 | if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) { |
Johannes Schindelin | b8469ad | 2009-01-28 00:07:36 +0100 | [diff] [blame] | 47 | char *buf = xmalloc(PATH_MAX + 1); |
Johannes Sixt | f42302b | 2009-02-07 16:08:30 +0100 | [diff] [blame] | 48 | int rv = normalize_path_copy(buf, argv[2]); |
| 49 | if (rv) |
| 50 | buf = "++failed++"; |
David Reiss | ae299be | 2008-05-19 23:48:54 -0700 | [diff] [blame] | 51 | puts(buf); |
Johannes Sixt | 2cd85c4 | 2009-02-07 16:08:27 +0100 | [diff] [blame] | 52 | return 0; |
David Reiss | ae299be | 2008-05-19 23:48:54 -0700 | [diff] [blame] | 53 | } |
| 54 | |
Carlos Martín Nieto | e2a57aa | 2011-03-17 12:26:46 +0100 | [diff] [blame] | 55 | if (argc >= 2 && !strcmp(argv[1], "real_path")) { |
David Reiss | d553e73 | 2008-05-19 23:49:00 -0700 | [diff] [blame] | 56 | while (argc > 2) { |
Carlos Martín Nieto | e2a57aa | 2011-03-17 12:26:46 +0100 | [diff] [blame] | 57 | puts(real_path(argv[2])); |
David Reiss | d553e73 | 2008-05-19 23:49:00 -0700 | [diff] [blame] | 58 | argc--; |
| 59 | argv++; |
| 60 | } |
Johannes Sixt | 2cd85c4 | 2009-02-07 16:08:27 +0100 | [diff] [blame] | 61 | return 0; |
David Reiss | d553e73 | 2008-05-19 23:49:00 -0700 | [diff] [blame] | 62 | } |
| 63 | |
Michael Haggerty | 87a246e | 2011-08-04 06:47:47 +0200 | [diff] [blame] | 64 | if (argc >= 2 && !strcmp(argv[1], "absolute_path")) { |
| 65 | while (argc > 2) { |
| 66 | puts(absolute_path(argv[2])); |
| 67 | argc--; |
| 68 | argv++; |
| 69 | } |
| 70 | return 0; |
| 71 | } |
| 72 | |
David Reiss | 0454dd9 | 2008-05-19 23:49:26 -0700 | [diff] [blame] | 73 | if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) { |
Michael Haggerty | 31171d9 | 2012-10-28 17:16:24 +0100 | [diff] [blame] | 74 | int len; |
| 75 | struct string_list ceiling_dirs = STRING_LIST_INIT_DUP; |
Michael Haggerty | 9e2326c | 2012-10-28 17:16:25 +0100 | [diff] [blame] | 76 | char *path = xstrdup(argv[2]); |
Michael Haggerty | 31171d9 | 2012-10-28 17:16:24 +0100 | [diff] [blame] | 77 | |
Michael Haggerty | 9e2326c | 2012-10-28 17:16:25 +0100 | [diff] [blame] | 78 | /* |
| 79 | * We have to normalize the arguments because under |
| 80 | * Windows, bash mangles arguments that look like |
| 81 | * absolute POSIX paths or colon-separate lists of |
| 82 | * absolute POSIX paths into DOS paths (e.g., |
| 83 | * "/foo:/foo/bar" might be converted to |
| 84 | * "D:\Src\msysgit\foo;D:\Src\msysgit\foo\bar"), |
| 85 | * whereas longest_ancestor_length() requires paths |
| 86 | * that use forward slashes. |
| 87 | */ |
| 88 | if (normalize_path_copy(path, path)) |
| 89 | die("Path \"%s\" could not be normalized", argv[2]); |
Michael Haggerty | 31171d9 | 2012-10-28 17:16:24 +0100 | [diff] [blame] | 90 | string_list_split(&ceiling_dirs, argv[3], PATH_SEP, -1); |
Michael Haggerty | 9e2326c | 2012-10-28 17:16:25 +0100 | [diff] [blame] | 91 | filter_string_list(&ceiling_dirs, 0, |
| 92 | normalize_ceiling_entry, NULL); |
| 93 | len = longest_ancestor_length(path, &ceiling_dirs); |
Michael Haggerty | 31171d9 | 2012-10-28 17:16:24 +0100 | [diff] [blame] | 94 | string_list_clear(&ceiling_dirs, 0); |
Michael Haggerty | 9e2326c | 2012-10-28 17:16:25 +0100 | [diff] [blame] | 95 | free(path); |
David Reiss | 0454dd9 | 2008-05-19 23:49:26 -0700 | [diff] [blame] | 96 | printf("%d\n", len); |
Johannes Sixt | 2cd85c4 | 2009-02-07 16:08:27 +0100 | [diff] [blame] | 97 | return 0; |
David Reiss | 0454dd9 | 2008-05-19 23:49:26 -0700 | [diff] [blame] | 98 | } |
| 99 | |
Michael Haggerty | 9e81372 | 2011-08-04 06:47:48 +0200 | [diff] [blame] | 100 | if (argc >= 4 && !strcmp(argv[1], "prefix_path")) { |
| 101 | char *prefix = argv[2]; |
| 102 | int prefix_len = strlen(prefix); |
| 103 | int nongit_ok; |
| 104 | setup_git_directory_gently(&nongit_ok); |
| 105 | while (argc > 3) { |
| 106 | puts(prefix_path(prefix, prefix_len, argv[3])); |
| 107 | argc--; |
| 108 | argv++; |
| 109 | } |
| 110 | return 0; |
| 111 | } |
| 112 | |
Johannes Schindelin | 4fcc86b | 2009-02-19 20:10:49 +0100 | [diff] [blame] | 113 | if (argc == 4 && !strcmp(argv[1], "strip_path_suffix")) { |
| 114 | char *prefix = strip_path_suffix(argv[2], argv[3]); |
| 115 | printf("%s\n", prefix ? prefix : "(null)"); |
| 116 | return 0; |
| 117 | } |
| 118 | |
Sebastian Schuberth | 7ffd18f | 2013-10-10 22:49:43 +0200 | [diff] [blame] | 119 | if (argc == 3 && !strcmp(argv[1], "print_path")) { |
Jiang Xin | abd4284 | 2013-06-25 23:53:57 +0800 | [diff] [blame] | 120 | puts(argv[2]); |
| 121 | return 0; |
| 122 | } |
| 123 | |
Jiang Xin | 203439b | 2013-06-25 23:53:42 +0800 | [diff] [blame] | 124 | if (argc == 4 && !strcmp(argv[1], "relative_path")) { |
Jiang Xin | e02ca72 | 2013-06-25 23:53:43 +0800 | [diff] [blame] | 125 | struct strbuf sb = STRBUF_INIT; |
Jiang Xin | 203439b | 2013-06-25 23:53:42 +0800 | [diff] [blame] | 126 | const char *in, *prefix, *rel; |
| 127 | normalize_argv_string(&in, argv[2]); |
| 128 | normalize_argv_string(&prefix, argv[3]); |
Jiang Xin | e02ca72 | 2013-06-25 23:53:43 +0800 | [diff] [blame] | 129 | rel = relative_path(in, prefix, &sb); |
Jiang Xin | 203439b | 2013-06-25 23:53:42 +0800 | [diff] [blame] | 130 | if (!rel) |
| 131 | puts("(null)"); |
| 132 | else |
| 133 | puts(strlen(rel) > 0 ? rel : "(empty)"); |
Jiang Xin | e02ca72 | 2013-06-25 23:53:43 +0800 | [diff] [blame] | 134 | strbuf_release(&sb); |
Jiang Xin | 203439b | 2013-06-25 23:53:42 +0800 | [diff] [blame] | 135 | return 0; |
| 136 | } |
| 137 | |
Johannes Sixt | 2cd85c4 | 2009-02-07 16:08:27 +0100 | [diff] [blame] | 138 | fprintf(stderr, "%s: unknown function name: %s\n", argv[0], |
| 139 | argv[1] ? argv[1] : "(there was none)"); |
| 140 | return 1; |
David Reiss | ae299be | 2008-05-19 23:48:54 -0700 | [diff] [blame] | 141 | } |