Merge branch 'ah/doc-pretty-color-auto-prefix' into maint
[git] / alias.c
1 #include "cache.h"
2
3 struct config_alias_data {
4         const char *alias;
5         char *v;
6 };
7
8 static int config_alias_cb(const char *key, const char *value, void *d)
9 {
10         struct config_alias_data *data = d;
11         const char *p;
12
13         if (skip_prefix(key, "alias.", &p) && !strcmp(p, data->alias))
14                 return git_config_string((const char **)&data->v, key, value);
15
16         return 0;
17 }
18
19 char *alias_lookup(const char *alias)
20 {
21         struct config_alias_data data = { alias, NULL };
22
23         read_early_config(config_alias_cb, &data);
24
25         return data.v;
26 }
27
28 #define SPLIT_CMDLINE_BAD_ENDING 1
29 #define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
30 static const char *split_cmdline_errors[] = {
31         "cmdline ends with \\",
32         "unclosed quote"
33 };
34
35 int split_cmdline(char *cmdline, const char ***argv)
36 {
37         int src, dst, count = 0, size = 16;
38         char quoted = 0;
39
40         ALLOC_ARRAY(*argv, size);
41
42         /* split alias_string */
43         (*argv)[count++] = cmdline;
44         for (src = dst = 0; cmdline[src];) {
45                 char c = cmdline[src];
46                 if (!quoted && isspace(c)) {
47                         cmdline[dst++] = 0;
48                         while (cmdline[++src]
49                                         && isspace(cmdline[src]))
50                                 ; /* skip */
51                         ALLOC_GROW(*argv, count + 1, size);
52                         (*argv)[count++] = cmdline + dst;
53                 } else if (!quoted && (c == '\'' || c == '"')) {
54                         quoted = c;
55                         src++;
56                 } else if (c == quoted) {
57                         quoted = 0;
58                         src++;
59                 } else {
60                         if (c == '\\' && quoted != '\'') {
61                                 src++;
62                                 c = cmdline[src];
63                                 if (!c) {
64                                         free(*argv);
65                                         *argv = NULL;
66                                         return -SPLIT_CMDLINE_BAD_ENDING;
67                                 }
68                         }
69                         cmdline[dst++] = c;
70                         src++;
71                 }
72         }
73
74         cmdline[dst] = 0;
75
76         if (quoted) {
77                 free(*argv);
78                 *argv = NULL;
79                 return -SPLIT_CMDLINE_UNCLOSED_QUOTE;
80         }
81
82         ALLOC_GROW(*argv, count + 1, size);
83         (*argv)[count] = NULL;
84
85         return count;
86 }
87
88 const char *split_cmdline_strerror(int split_cmdline_errno)
89 {
90         return split_cmdline_errors[-split_cmdline_errno - 1];
91 }