test-path-utils.con commit strbuf: add strbuf_reencode helper (d4241f5)
   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        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
  31static 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
  44int main(int argc, char **argv)
  45{
  46        if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
  47                char *buf = xmalloc(PATH_MAX + 1);
  48                int rv = normalize_path_copy(buf, argv[2]);
  49                if (rv)
  50                        buf = "++failed++";
  51                puts(buf);
  52                return 0;
  53        }
  54
  55        if (argc >= 2 && !strcmp(argv[1], "real_path")) {
  56                while (argc > 2) {
  57                        puts(real_path(argv[2]));
  58                        argc--;
  59                        argv++;
  60                }
  61                return 0;
  62        }
  63
  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
  73        if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) {
  74                int len;
  75                struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
  76                char *path = xstrdup(argv[2]);
  77
  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]);
  90                string_list_split(&ceiling_dirs, argv[3], PATH_SEP, -1);
  91                filter_string_list(&ceiling_dirs, 0,
  92                                   normalize_ceiling_entry, NULL);
  93                len = longest_ancestor_length(path, &ceiling_dirs);
  94                string_list_clear(&ceiling_dirs, 0);
  95                free(path);
  96                printf("%d\n", len);
  97                return 0;
  98        }
  99
 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
 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
 119        if (argc == 3 && !strcmp(argv[1], "print_path")) {
 120                puts(argv[2]);
 121                return 0;
 122        }
 123
 124        if (argc == 4 && !strcmp(argv[1], "relative_path")) {
 125                struct strbuf sb = STRBUF_INIT;
 126                const char *in, *prefix, *rel;
 127                normalize_argv_string(&in, argv[2]);
 128                normalize_argv_string(&prefix, argv[3]);
 129                rel = relative_path(in, prefix, &sb);
 130                if (!rel)
 131                        puts("(null)");
 132                else
 133                        puts(strlen(rel) > 0 ? rel : "(empty)");
 134                strbuf_release(&sb);
 135                return 0;
 136        }
 137
 138        fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
 139                argv[1] ? argv[1] : "(there was none)");
 140        return 1;
 141}