aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command.h58
-rw-r--r--src/config.c16
-rw-r--r--src/main.c35
-rw-r--r--src/main.h2
-rw-r--r--src/wine.c10
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));
}
diff --git a/src/main.c b/src/main.c
index 3fd282a..d6dd008 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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)
{
diff --git a/src/main.h b/src/main.h
index 28bec99..c786179 100644
--- a/src/main.h
+++ b/src/main.h
@@ -3,6 +3,8 @@
#include "command.h"
+#define WINE_PREFIX "wine-"
+
COMMAND(main, env);
COMMAND(main, version);
COMMAND(main, help);
diff --git a/src/wine.c b/src/wine.c
index 65cbd34..3f1e5c4 100644
--- a/src/wine.c
+++ b/src/wine.c
@@ -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;
}