alias.con commit t3404: todo list with commented-out commands only aborts (d078c39)
   1#include "cache.h"
   2#include "alias.h"
   3#include "config.h"
   4#include "string-list.h"
   5
   6struct config_alias_data {
   7        const char *alias;
   8        char *v;
   9        struct string_list *list;
  10};
  11
  12static int config_alias_cb(const char *key, const char *value, void *d)
  13{
  14        struct config_alias_data *data = d;
  15        const char *p;
  16
  17        if (!skip_prefix(key, "alias.", &p))
  18                return 0;
  19
  20        if (data->alias) {
  21                if (!strcasecmp(p, data->alias))
  22                        return git_config_string((const char **)&data->v,
  23                                                 key, value);
  24        } else if (data->list) {
  25                string_list_append(data->list, p);
  26        }
  27
  28        return 0;
  29}
  30
  31char *alias_lookup(const char *alias)
  32{
  33        struct config_alias_data data = { alias, NULL };
  34
  35        read_early_config(config_alias_cb, &data);
  36
  37        return data.v;
  38}
  39
  40void list_aliases(struct string_list *list)
  41{
  42        struct config_alias_data data = { NULL, NULL, list };
  43
  44        read_early_config(config_alias_cb, &data);
  45}
  46
  47#define SPLIT_CMDLINE_BAD_ENDING 1
  48#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
  49static const char *split_cmdline_errors[] = {
  50        "cmdline ends with \\",
  51        "unclosed quote"
  52};
  53
  54int split_cmdline(char *cmdline, const char ***argv)
  55{
  56        int src, dst, count = 0, size = 16;
  57        char quoted = 0;
  58
  59        ALLOC_ARRAY(*argv, size);
  60
  61        /* split alias_string */
  62        (*argv)[count++] = cmdline;
  63        for (src = dst = 0; cmdline[src];) {
  64                char c = cmdline[src];
  65                if (!quoted && isspace(c)) {
  66                        cmdline[dst++] = 0;
  67                        while (cmdline[++src]
  68                                        && isspace(cmdline[src]))
  69                                ; /* skip */
  70                        ALLOC_GROW(*argv, count + 1, size);
  71                        (*argv)[count++] = cmdline + dst;
  72                } else if (!quoted && (c == '\'' || c == '"')) {
  73                        quoted = c;
  74                        src++;
  75                } else if (c == quoted) {
  76                        quoted = 0;
  77                        src++;
  78                } else {
  79                        if (c == '\\' && quoted != '\'') {
  80                                src++;
  81                                c = cmdline[src];
  82                                if (!c) {
  83                                        FREE_AND_NULL(*argv);
  84                                        return -SPLIT_CMDLINE_BAD_ENDING;
  85                                }
  86                        }
  87                        cmdline[dst++] = c;
  88                        src++;
  89                }
  90        }
  91
  92        cmdline[dst] = 0;
  93
  94        if (quoted) {
  95                FREE_AND_NULL(*argv);
  96                return -SPLIT_CMDLINE_UNCLOSED_QUOTE;
  97        }
  98
  99        ALLOC_GROW(*argv, count + 1, size);
 100        (*argv)[count] = NULL;
 101
 102        return count;
 103}
 104
 105const char *split_cmdline_strerror(int split_cmdline_errno)
 106{
 107        return split_cmdline_errors[-split_cmdline_errno - 1];
 108}