Merge branch 'pt/pull-tests' into pt/pull-optparse
[git] / alias.c
1 #include "cache.h"
2
3 char *alias_lookup(const char *alias)
4 {
5         char *v = NULL;
6         struct strbuf key = STRBUF_INIT;
7         strbuf_addf(&key, "alias.%s", alias);
8         git_config_get_string(key.buf, &v);
9         strbuf_release(&key);
10         return v;
11 }
12
13 #define SPLIT_CMDLINE_BAD_ENDING 1
14 #define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
15 static const char *split_cmdline_errors[] = {
16         "cmdline ends with \\",
17         "unclosed quote"
18 };
19
20 int split_cmdline(char *cmdline, const char ***argv)
21 {
22         int src, dst, count = 0, size = 16;
23         char quoted = 0;
24
25         *argv = xmalloc(sizeof(**argv) * size);
26
27         /* split alias_string */
28         (*argv)[count++] = cmdline;
29         for (src = dst = 0; cmdline[src];) {
30                 char c = cmdline[src];
31                 if (!quoted && isspace(c)) {
32                         cmdline[dst++] = 0;
33                         while (cmdline[++src]
34                                         && isspace(cmdline[src]))
35                                 ; /* skip */
36                         ALLOC_GROW(*argv, count + 1, size);
37                         (*argv)[count++] = cmdline + dst;
38                 } else if (!quoted && (c == '\'' || c == '"')) {
39                         quoted = c;
40                         src++;
41                 } else if (c == quoted) {
42                         quoted = 0;
43                         src++;
44                 } else {
45                         if (c == '\\' && quoted != '\'') {
46                                 src++;
47                                 c = cmdline[src];
48                                 if (!c) {
49                                         free(*argv);
50                                         *argv = NULL;
51                                         return -SPLIT_CMDLINE_BAD_ENDING;
52                                 }
53                         }
54                         cmdline[dst++] = c;
55                         src++;
56                 }
57         }
58
59         cmdline[dst] = 0;
60
61         if (quoted) {
62                 free(*argv);
63                 *argv = NULL;
64                 return -SPLIT_CMDLINE_UNCLOSED_QUOTE;
65         }
66
67         ALLOC_GROW(*argv, count + 1, size);
68         (*argv)[count] = NULL;
69
70         return count;
71 }
72
73 const char *split_cmdline_strerror(int split_cmdline_errno)
74 {
75         return split_cmdline_errors[-split_cmdline_errno - 1];
76 }