diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command.h | 58 | ||||
-rw-r--r-- | src/config.c | 16 | ||||
-rw-r--r-- | src/main.c | 35 | ||||
-rw-r--r-- | src/main.h | 2 | ||||
-rw-r--r-- | src/wine.c | 10 |
5 files changed, 82 insertions, 39 deletions
diff --git a/src/command.h b/src/command.h index f4cd9fe..0a8f412 100644 --- a/src/command.h +++ b/src/command.h @@ -43,6 +43,36 @@ /* + * the body is split up so we can construct our own group function for + * e.g. ARGV0 parsing + */ +#define COMMAND_GROUP_BODY(GROUP) \ + if (argc > 1) \ + { \ + for (unsigned long i = 0; i < ARRAY_LEN(GROUP##_commands); ++i) \ + if (!strcmp(GROUP##_commands[i].name, argv[1])) return GROUP##_commands[i].func(argc-1, argv+1); \ + \ + for (int j = 1; j < argc; ++j) \ + { \ + if (argv[j][0] != '-') continue; \ + \ + for (unsigned long i = 0; i < ARRAY_LEN(GROUP##_flags); ++i) \ + { \ + if ((GROUP##_flags[i].variant & ONE && argv[j][1] == GROUP##_flags[i].name[0]) || \ + (GROUP##_flags[i].variant & TWO && argv[j][1] == '-' \ + && !strcmp(GROUP##_flags[i].name, argv[j]+2))) \ + { \ + return GROUP##_flags[i].func(0, NULL); \ + } \ + } \ + } \ + \ + fprintf(stderr, NAME ": '%s' is not a command or flag\n", argv[1]); \ + return 0; \ + } \ + return GROUP##_help(argc-1, argv+1); + +/* * the main command group function is only suppose to find given command * by the name and then invoke it. * @@ -54,30 +84,8 @@ #define COMMAND_GROUP_FUNC(GROUP) \ COMMAND_GROUP(GROUP) \ { \ - if (argc > 1) \ - { \ - for (unsigned long i = 0; i < ARRAY_LEN(GROUP##_commands); ++i) \ - if (!strcmp(GROUP##_commands[i].name, argv[1])) return GROUP##_commands[i].func(argc-1, argv+1); \ - \ - for (int j = 1; j < argc; ++j) \ - { \ - if (argv[j][0] != '-') continue; \ - \ - for (unsigned long i = 0; i < ARRAY_LEN(GROUP##_flags); ++i) \ - { \ - if ((GROUP##_flags[i].variant & ONE && argv[j][1] == GROUP##_flags[i].name[0]) || \ - (GROUP##_flags[i].variant & TWO && argv[j][1] == '-' \ - && !strcmp(GROUP##_flags[i].name, argv[j]+2))) \ - { \ - return GROUP##_flags[i].func(0, NULL); \ - } \ - } \ - } \ - \ - fprintf(stderr, NAME ": '%s' is not a command or flag\n", argv[1]); \ - return 0; \ - } \ - return GROUP##_help(argc-1, argv+1); \ - } + COMMAND_GROUP_BODY(GROUP) \ + } \ + #endif diff --git a/src/config.c b/src/config.c index ebaff3e..02889b0 100644 --- a/src/config.c +++ b/src/config.c @@ -7,12 +7,6 @@ #include "config.h" #include "common.h" -#ifdef _WIN32 -#define HOMEVAR "USERPROFILE" -#else -#define HOMEVAR "HOME" -#endif - static void getXDGDir(const char* envvar, const char* homeext, char* config, const size_t size) { char* xdg_var = getenv(envvar); @@ -23,8 +17,16 @@ static void getXDGDir(const char* envvar, const char* homeext, char* config, con } else { - char* home = getenv(HOMEVAR); + char* home = getenv("HOME"); if (!home) home = ""; + if (!home) + { +#ifdef _WIN32 + home = getenv("USERPROFILE"); + if (!home) +#endif + home = ""; + } strncpy(config, home, size); strncat(config, homeext, size - strlen(config)); } @@ -1,6 +1,7 @@ #include <stdio.h> #include <string.h> #include <limits.h> +#include <libgen.h> #include "main.h" #include "wine.h" @@ -9,6 +10,11 @@ #include "common.h" #include "config.h" +// if something fails +// we need to free the new argv +char** nargv; +static void free_nargv() { free(nargv); } + static const struct Command main_commands[] = { #ifndef _WIN32 { .name = "wine", .func = wine, .description = "manage wine versions" }, @@ -23,7 +29,34 @@ static const struct Flag main_flags[] = { { .name = "version", .variant = BOTH, .func = main_version, .description = "prints the program version"} }; -COMMAND_GROUP_FUNC(main) +COMMAND_GROUP(main) +{ +#ifndef _WIN32 + char* arg0 = basename(argv[0]); + if (!strncmp(WINE_PREFIX, arg0, strlen(WINE_PREFIX))) + { + int nargc = argc + 3; + nargv = malloc((size_t)(nargc+1) * sizeof(char*)); + + nargv[0] = argv[0]; + nargv[1] = "wine"; + nargv[2] = "run"; + nargv[3] = arg0 + strlen(WINE_PREFIX); + for (int i = 1; i < argc; ++i) nargv[3+i] = argv[i]; + nargv[nargc] = NULL; + + argc = nargc; + argv = nargv; + + /* we cannot free nargv before the body parsed it + * and we cannot free it after because the body + * returns, so call this at exit to free the leak + */ + atexit(free_nargv); + } +#endif + COMMAND_GROUP_BODY(main) +} COMMAND(main, env) { @@ -3,6 +3,8 @@ #include "command.h" +#define WINE_PREFIX "wine-" + COMMAND(main, env); COMMAND(main, version); COMMAND(main, help); @@ -70,7 +70,7 @@ COMMAND(wine, download) getWineDir(winedir, sizeof(winedir)); makeDir(winedir); - + fprintf(stderr, "Downloading %s...\n", name); archive = downloadToRam(json_object_get_string(temp), 1); @@ -248,7 +248,7 @@ COMMAND(wine, run) } fprintf(stderr, "Specify a what wine version to run.\nUse '" NAME " wine list-installed' to list available versions\n"); - + return 0; } @@ -282,7 +282,7 @@ COMMAND(wine, installed) printf("%s\n", ent->d_name); } closedir(dir); - } + } return 0; } @@ -362,10 +362,9 @@ COMMAND(wine, env) } else { - printf("set PATH %s $PATH\n", winepath); + printf("set PATH %s $PATH\n", winepath); } } - //printf("PATH=\"%s\"\n# Run this code in your Terminal\n# by running eval '%s'", newpath, argv[0]); } else { @@ -378,7 +377,6 @@ COMMAND(wine, env) fprintf(stderr, "Specify a what wine version to run.\nUse '" NAME " wine list-installed' to list available versions\n"); } - return 0; } |