test-path-utils.con commit Merge branch 'pw/completion-stash' (ebcdd63)
   1#include "cache.h"
   2#include "string-list.h"
   3
   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 */
   9static 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        free(item->string);
  25        item->string = xstrdup(buf);
  26        return 1;
  27}
  28
  29static void normalize_argv_string(const char **var, const char *input)
  30{
  31        if (!strcmp(input, "<null>"))
  32                *var = NULL;
  33        else if (!strcmp(input, "<empty>"))
  34                *var = "";
  35        else
  36                *var = input;
  37
  38        if (*var && (**var == '<' || **var == '('))
  39                die("Bad value: %s\n", input);
  40}
  41
  42int main(int argc, char **argv)
  43{
  44        if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
  45                char *buf = xmalloc(PATH_MAX + 1);
  46                int rv = normalize_path_copy(buf, argv[2]);
  47                if (rv)
  48                        buf = "++failed++";
  49                puts(buf);
  50                return 0;
  51        }
  52
  53        if (argc >= 2 && !strcmp(argv[1], "real_path")) {
  54                while (argc > 2) {
  55                        puts(real_path(argv[2]));
  56                        argc--;
  57                        argv++;
  58                }
  59                return 0;
  60        }
  61
  62        if (argc >= 2 && !strcmp(argv[1], "absolute_path")) {
  63                while (argc > 2) {
  64                        puts(absolute_path(argv[2]));
  65                        argc--;
  66                        argv++;
  67                }
  68                return 0;
  69        }
  70
  71        if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) {
  72                int len;
  73                struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
  74                char *path = xstrdup(argv[2]);
  75
  76                /*
  77                 * We have to normalize the arguments because under
  78                 * Windows, bash mangles arguments that look like
  79                 * absolute POSIX paths or colon-separate lists of
  80                 * absolute POSIX paths into DOS paths (e.g.,
  81                 * "/foo:/foo/bar" might be converted to
  82                 * "D:\Src\msysgit\foo;D:\Src\msysgit\foo\bar"),
  83                 * whereas longest_ancestor_length() requires paths
  84                 * that use forward slashes.
  85                 */
  86                if (normalize_path_copy(path, path))
  87                        die("Path \"%s\" could not be normalized", argv[2]);
  88                string_list_split(&ceiling_dirs, argv[3], PATH_SEP, -1);
  89                filter_string_list(&ceiling_dirs, 0,
  90                                   normalize_ceiling_entry, NULL);
  91                len = longest_ancestor_length(path, &ceiling_dirs);
  92                string_list_clear(&ceiling_dirs, 0);
  93                free(path);
  94                printf("%d\n", len);
  95                return 0;
  96        }
  97
  98        if (argc >= 4 && !strcmp(argv[1], "prefix_path")) {
  99                char *prefix = argv[2];
 100                int prefix_len = strlen(prefix);
 101                int nongit_ok;
 102                setup_git_directory_gently(&nongit_ok);
 103                while (argc > 3) {
 104                        puts(prefix_path(prefix, prefix_len, argv[3]));
 105                        argc--;
 106                        argv++;
 107                }
 108                return 0;
 109        }
 110
 111        if (argc == 4 && !strcmp(argv[1], "strip_path_suffix")) {
 112                char *prefix = strip_path_suffix(argv[2], argv[3]);
 113                printf("%s\n", prefix ? prefix : "(null)");
 114                return 0;
 115        }
 116
 117        if (argc == 3 && !strcmp(argv[1], "print_path")) {
 118                puts(argv[2]);
 119                return 0;
 120        }
 121
 122        if (argc == 4 && !strcmp(argv[1], "relative_path")) {
 123                struct strbuf sb = STRBUF_INIT;
 124                const char *in, *prefix, *rel;
 125                normalize_argv_string(&in, argv[2]);
 126                normalize_argv_string(&prefix, argv[3]);
 127                rel = relative_path(in, prefix, &sb);
 128                if (!rel)
 129                        puts("(null)");
 130                else
 131                        puts(strlen(rel) > 0 ? rel : "(empty)");
 132                strbuf_release(&sb);
 133                return 0;
 134        }
 135
 136        fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
 137                argv[1] ? argv[1] : "(there was none)");
 138        return 1;
 139}