diff options
Diffstat (limited to 'alias.c')
-rw-r--r-- | alias.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/alias.c b/alias.c new file mode 100644 index 0000000000..a11229db9e --- /dev/null +++ b/alias.c @@ -0,0 +1,77 @@ +#include "cache.h" + +char *alias_lookup(const char *alias) +{ + char *v = NULL; + struct strbuf key = STRBUF_INIT; + strbuf_addf(&key, "alias.%s", alias); + if (git_config_key_is_valid(key.buf)) + git_config_get_string(key.buf, &v); + strbuf_release(&key); + return v; +} + +#define SPLIT_CMDLINE_BAD_ENDING 1 +#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2 +static const char *split_cmdline_errors[] = { + "cmdline ends with \\", + "unclosed quote" +}; + +int split_cmdline(char *cmdline, const char ***argv) +{ + int src, dst, count = 0, size = 16; + char quoted = 0; + + *argv = xmalloc(sizeof(**argv) * size); + + /* split alias_string */ + (*argv)[count++] = cmdline; + for (src = dst = 0; cmdline[src];) { + char c = cmdline[src]; + if (!quoted && isspace(c)) { + cmdline[dst++] = 0; + while (cmdline[++src] + && isspace(cmdline[src])) + ; /* skip */ + ALLOC_GROW(*argv, count + 1, size); + (*argv)[count++] = cmdline + dst; + } else if (!quoted && (c == '\'' || c == '"')) { + quoted = c; + src++; + } else if (c == quoted) { + quoted = 0; + src++; + } else { + if (c == '\\' && quoted != '\'') { + src++; + c = cmdline[src]; + if (!c) { + free(*argv); + *argv = NULL; + return -SPLIT_CMDLINE_BAD_ENDING; + } + } + cmdline[dst++] = c; + src++; + } + } + + cmdline[dst] = 0; + + if (quoted) { + free(*argv); + *argv = NULL; + return -SPLIT_CMDLINE_UNCLOSED_QUOTE; + } + + ALLOC_GROW(*argv, count + 1, size); + (*argv)[count] = NULL; + + return count; +} + +const char *split_cmdline_strerror(int split_cmdline_errno) +{ + return split_cmdline_errors[-split_cmdline_errno - 1]; +} |