Hi, On Sun, 4 Jun 2006, Junio C Hamano wrote: > Johannes Schindelin <Johannes.Schindelin@xxxxxx> writes: > > > For me, short cuts have to be easy to type, so they never > > include digits, and they are never case sensitive, so I do not > > need any fancy config stuff... > > Fair enough, and the spirit is the same as what Pasky suggested > earlier, I think. > > However, I am not sure about some parts of the code. I started > mucking with it myself, but realized it is far easier for me to > just let the original submitter, especially the capable one like > you, do a bit more work ;-). Are you trying to butter me up? If so, it's working ;-) Here is a revised patch which addresses all of your comments (and Pasky's implicit ones) except the move of split_cmdline to somewhere central (I am not sure if that function is really needed elsewhere...): --- git.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 113 insertions(+), 0 deletions(-) diff --git a/git.c b/git.c index bc463c9..db6ac61 100644 --- a/git.c +++ b/git.c @@ -10,6 +10,7 @@ #include <limits.h> #include <stdarg.h> #include "git-compat-util.h" #include "exec_cmd.h" +#include "cache.h" #include "builtin.h" @@ -32,6 +33,115 @@ static void prepend_to_path(const char * setenv("PATH", path, 1); } +static const char *alias_command; +static char *alias_string = NULL; + +static int git_alias_config(const char *var, const char *value) +{ + if (!strncmp(var, "alias.", 6) && !strcmp(var + 6, alias_command)) { + alias_string = strdup(value); + } + return 0; +} + +static int split_cmdline(char *cmdline, const char ***argv) +{ + int src, dst, count = 0, size = 16; + char quoted = 0; + + *argv = malloc(sizeof(char*) * 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 */ + if (count >= size) { + size += 16; + *argv = realloc(*argv, sizeof(char*) * 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 error("cmdline ends with \\"); + } + } + cmdline[dst++] = c; + src++; + } + } + + cmdline[dst] = 0; + + if (quoted) { + free(*argv); + *argv = NULL; + return error("unclosed quote"); + } + + return count; +} + +static int handle_alias(int *argcp, const char ***argv) +{ + int nongit = 0; + const char *subdir; + + subdir = setup_git_directory_gently(&nongit); + if (!nongit) { + int count; + const char** new_argv; + + alias_command = (*argv)[0]; + git_config(git_alias_config); + if (!alias_string) + return 0; + + count = split_cmdline(alias_string, &new_argv); + + if (count < 1) + die("empty alias for %s", alias_command); + + if (!strcmp(alias_command, new_argv[0])) + die("recursive alias: %s", alias_command); + + /* insert after command name */ + if (*argcp > 1) { + new_argv = realloc(new_argv, + sizeof(char*) * (count + *argcp - 1)); + memcpy(new_argv + count, *argv, sizeof(char*) * (*argcp - 1)); + } + + *argv = new_argv; + *argcp += count - 1; + + if (subdir) + chdir(subdir); + + return 1; + } + + if (subdir) + chdir(subdir); + + return 0; +} + const char git_version_string[] = GIT_VERSION; static void handle_internal_command(int argc, const char **argv, char **envp) @@ -121,6 +231,7 @@ int main(int argc, const char **argv, ch if (!strncmp(cmd, "git-", 4)) { cmd += 4; argv[0] = cmd; + handle_alias(&argc, &argv); handle_internal_command(argc, argv, envp); die("cannot handle %s internally", cmd); } @@ -178,6 +289,8 @@ int main(int argc, const char **argv, ch exec_path = git_exec_path(); prepend_to_path(exec_path, strlen(exec_path)); + handle_alias(&argc, &argv); + /* See if it's an internal command */ handle_internal_command(argc, argv, envp); - : send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html