alias.con commit Merge gitk changes from Paul Mackerras at git://ozlabs.org/~paulus/gitk (b476064)
   1#include "cache.h"
   2
   3static const char *alias_key;
   4static char *alias_val;
   5
   6static int alias_lookup_cb(const char *k, const char *v, void *cb)
   7{
   8        if (!prefixcmp(k, "alias.") && !strcmp(k+6, alias_key)) {
   9                if (!v)
  10                        return config_error_nonbool(k);
  11                alias_val = xstrdup(v);
  12                return 0;
  13        }
  14        return 0;
  15}
  16
  17char *alias_lookup(const char *alias)
  18{
  19        alias_key = alias;
  20        alias_val = NULL;
  21        git_config(alias_lookup_cb, NULL);
  22        return alias_val;
  23}
  24
  25#define SPLIT_CMDLINE_BAD_ENDING 1
  26#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
  27static const char *split_cmdline_errors[] = {
  28        "cmdline ends with \\",
  29        "unclosed quote"
  30};
  31
  32int split_cmdline(char *cmdline, const char ***argv)
  33{
  34        int src, dst, count = 0, size = 16;
  35        char quoted = 0;
  36
  37        *argv = xmalloc(sizeof(char *) * size);
  38
  39        /* split alias_string */
  40        (*argv)[count++] = cmdline;
  41        for (src = dst = 0; cmdline[src];) {
  42                char c = cmdline[src];
  43                if (!quoted && isspace(c)) {
  44                        cmdline[dst++] = 0;
  45                        while (cmdline[++src]
  46                                        && isspace(cmdline[src]))
  47                                ; /* skip */
  48                        ALLOC_GROW(*argv, count+1, size);
  49                        (*argv)[count++] = cmdline + dst;
  50                } else if (!quoted && (c == '\'' || c == '"')) {
  51                        quoted = c;
  52                        src++;
  53                } else if (c == quoted) {
  54                        quoted = 0;
  55                        src++;
  56                } else {
  57                        if (c == '\\' && quoted != '\'') {
  58                                src++;
  59                                c = cmdline[src];
  60                                if (!c) {
  61                                        free(*argv);
  62                                        *argv = NULL;
  63                                        return -SPLIT_CMDLINE_BAD_ENDING;
  64                                }
  65                        }
  66                        cmdline[dst++] = c;
  67                        src++;
  68                }
  69        }
  70
  71        cmdline[dst] = 0;
  72
  73        if (quoted) {
  74                free(*argv);
  75                *argv = NULL;
  76                return -SPLIT_CMDLINE_UNCLOSED_QUOTE;
  77        }
  78
  79        ALLOC_GROW(*argv, count+1, size);
  80        (*argv)[count] = NULL;
  81
  82        return count;
  83}
  84
  85const char *split_cmdline_strerror(int split_cmdline_errno) {
  86        return split_cmdline_errors[-split_cmdline_errno-1];
  87}