From a3eda1d6cd6d68a59fa874670e99f87ce901a409 Mon Sep 17 00:00:00 2001 From: meep-eep Date: Tue, 23 Nov 2004 00:25:46 +0000 Subject: [PATCH] Make user config dir configurable on the command line (bug #645). Also, the environment variables UQM_CONFIG_DIR, UQM_SAVE_DIR, UQM_MELEE_DIR, are checked for default values. This may not be a good idea permanently, but it was the easiest way to make it possible to have UQM_SAVE_DIR and UQM_MELEE_DIR depend on UQM_CONFIG_DIR. It will probably change with the new resource system. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1421 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/config_unix.h.in | 12 +++---- sc2/src/msvc++/config.h | 12 +++---- sc2/src/options.c | 62 ++++++++++++++++++++++++-------- sc2/src/options.h | 2 +- sc2/src/sc2code/libs/file/dirs.c | 48 ++++++++++++++++++++++--- sc2/src/starcon2.c | 11 ++++-- 6 files changed, 114 insertions(+), 33 deletions(-) diff --git a/sc2/src/config_unix.h.in b/sc2/src/config_unix.h.in index 3c7adb642..5dde0cd29 100644 --- a/sc2/src/config_unix.h.in +++ b/sc2/src/config_unix.h.in @@ -14,15 +14,15 @@ /* Directory where game data will be stored */ #define USERDIR "~/.uqm/" -/* Directory where supermelee teams will be stored */ -#define MELEEDIR USERDIR "teams/" - -/* Directory where save games will be stored */ -#define SAVEDIR USERDIR "save/" - /* Directory where config files will be stored */ #define CONFIGDIR USERDIR +/* Directory where supermelee teams will be stored */ +#define MELEEDIR "${UQM_CONFIG_DIR}/teams/" + +/* Directory where save games will be stored */ +#define SAVEDIR "${UQM_CONFIG_DIR}/save/" + /* Defined if words are stored with the most significant byte first */ @WORDS_BIGENDIAN@ diff --git a/sc2/src/msvc++/config.h b/sc2/src/msvc++/config.h index 8ed3a3342..5e03f7082 100644 --- a/sc2/src/msvc++/config.h +++ b/sc2/src/msvc++/config.h @@ -15,15 +15,15 @@ //#define USERDIR "../userdata/" #define USERDIR "%APPDATA%/uqm/" -/* Directory where supermelee teams will be stored */ -#define MELEEDIR USERDIR "teams/" - -/* Directory where save games will be stored */ -#define SAVEDIR USERDIR "save/" - /* Directory where config files will be stored */ #define CONFIGDIR USERDIR +/* Directory where supermelee teams will be stored */ +#define MELEEDIR "%UQM_CONFIG_DIR%/teams/" + +/* Directory where save games will be stored */ +#define SAVEDIR "%UQM_CONFIG_DIR%/save/" + /* Define if words are stored with the most significant byte first */ #undef WORDS_BIGENDIAN diff --git a/sc2/src/options.c b/sc2/src/options.c index 5373070d0..a17ebf73d 100644 --- a/sc2/src/options.c +++ b/sc2/src/options.c @@ -143,25 +143,38 @@ prepareContentDir (const char *contentDirName, const char **addons) } void -prepareConfigDir (void) { +prepareConfigDir (const char *configDirName) { char buf[PATH_MAX]; static uio_AutoMount *autoMount[] = { NULL }; uio_MountHandle *contentHandle; - if (expandPath (buf, PATH_MAX - 13, CONFIGDIR, EP_ALL_SYSTEM) == -1) - { - // Doesn't have to be fatal, but might mess up things when saving - // config files. - fprintf (stderr, "Fatal error: Invalid path to config files.\n"); - exit (EXIT_FAILURE); + if (configDirName == NULL) { + configDirName = getenv("UQM_CONFIG_DIR"); + + if (configDirName == NULL) + configDirName = CONFIGDIR; + + if (expandPath (buf, PATH_MAX - 13, configDirName, EP_ALL_SYSTEM) + == -1) + { + // Doesn't have to be fatal, but might mess up things when saving + // config files. + fprintf (stderr, "Fatal error: Invalid path to config files.\n"); + exit (EXIT_FAILURE); + } + configDirName = buf; } + // Set the environment variable UQM_CONFIG_DIR so UQM_MELEE_DIR + // and UQM_SAVE_DIR can refer to it. + setenv("UQM_CONFIG_DIR", configDirName, 1); + // Create the path upto the config dir, if not already existing. - if (mkdirhier (buf) == -1) + if (mkdirhier (configDirName) == -1) exit (EXIT_FAILURE); contentHandle = uio_mountDir (repository, "/", - uio_FSTYPE_STDIO, NULL, NULL, buf, autoMount, + uio_FSTYPE_STDIO, NULL, NULL, configDirName, autoMount, uio_MOUNT_TOP, NULL); if (contentHandle == NULL) { fprintf (stderr, "Fatal error: Could not mount config dir: %s\n", @@ -180,7 +193,13 @@ prepareConfigDir (void) { void prepareSaveDir (void) { char buf[PATH_MAX]; - if (expandPath (buf, PATH_MAX - 13, SAVEDIR, EP_ALL_SYSTEM) == -1) + const char *saveDirName; + + saveDirName = getenv("UQM_SAVE_DIR"); + if (saveDirName == NULL) + saveDirName = SAVEDIR; + + if (expandPath (buf, PATH_MAX - 13, saveDirName, EP_ALL_SYSTEM) == -1) { // Doesn't have to be fatal, but might mess up things when saving // config files. @@ -188,14 +207,19 @@ prepareSaveDir (void) { exit (EXIT_FAILURE); } + saveDirName = buf; + setenv("UQM_SAVE_DIR", saveDirName, 1); + // Create the path upto the save dir, if not already existing. - if (mkdirhier (buf) == -1) + if (mkdirhier (saveDirName) == -1) exit (EXIT_FAILURE); #ifdef DEBUG - fprintf(stderr, "Saved games are kept in %s.\n", buf); + fprintf(stderr, "Saved games are kept in %s.\n", saveDirName); #endif saveDir = uio_openDirRelative (configDir, "save", 0); + // TODO: this doesn't work if the save dir is not + // "save" in the config dir. if (saveDir == NULL) { fprintf (stderr, "Fatal error: Could not open save dir: %s\n", strerror (errno)); @@ -206,8 +230,13 @@ prepareSaveDir (void) { void prepareMeleeDir (void) { char buf[PATH_MAX]; + const char *meleeDirName; - if (expandPath (buf, PATH_MAX - 13, MELEEDIR, EP_ALL_SYSTEM) == -1) + meleeDirName = getenv("UQM_MELEE_DIR"); + if (meleeDirName == NULL) + meleeDirName = MELEEDIR; + + if (expandPath (buf, PATH_MAX - 13, meleeDirName, EP_ALL_SYSTEM) == -1) { // Doesn't have to be fatal, but might mess up things when saving // config files. @@ -215,11 +244,16 @@ prepareMeleeDir (void) { exit (EXIT_FAILURE); } + meleeDirName = buf; + setenv("UQM_MELEE_DIR", meleeDirName, 1); + // Create the path upto the save dir, if not already existing. - if (mkdirhier (buf) == -1) + if (mkdirhier (meleeDirName) == -1) exit (EXIT_FAILURE); meleeDir = uio_openDirRelative (configDir, "teams", 0); + // TODO: this doesn't work if the save dir is not + // "teams" in the config dir. if (meleeDir == NULL) { fprintf (stderr, "Fatal error: Could not open melee teams dir: %s\n", strerror (errno)); diff --git a/sc2/src/options.h b/sc2/src/options.h index 755e7fd9c..f9aeb885a 100644 --- a/sc2/src/options.h +++ b/sc2/src/options.h @@ -45,7 +45,7 @@ extern uio_DirHandle *saveDir; extern uio_DirHandle *meleeDir; void prepareContentDir (const char *contentDirName, const char **addons); -void prepareConfigDir(void); +void prepareConfigDir(const char *configDirName); void prepareMeleeDir(void); void prepareSaveDir(void); diff --git a/sc2/src/sc2code/libs/file/dirs.c b/sc2/src/sc2code/libs/file/dirs.c index 671017525..b5f85b764 100644 --- a/sc2/src/sc2code/libs/file/dirs.c +++ b/sc2/src/sc2code/libs/file/dirs.c @@ -296,12 +296,52 @@ expandPath (char *dest, size_t len, const char *src, int what) break; } #endif -#if 0 +#ifndef WIN32 case '$': - /* Environment variable substitution for Unix */ - // not implemented - // Should accept both $BLA_123 and ${BLA} + { + const char *end; + char *envName; + size_t envNameLen; + const char *envVar; + size_t envVarLen; + + src++; + if (*src == '{') + { + src++; + end = strchr(src, '}'); + if (end == NULL) + { + errno = EINVAL; + return -1; + } + envNameLen = end - src; + end++; // Skip the '}' + } + else + { + end = src; + while ((*end >= 'A' && *end <= 'Z') || + (*end >= 'a' && *end <= 'z') || + (*end >= '0' && *end <= '9') || + *end == '_') + end++; + envNameLen = end - src; + } + + envName = HMalloc (envNameLen + 1); + memcpy (envName, src, envNameLen + 1); + envName[envNameLen] = '\0'; + envVar = getenv (envName); + HFree (envName); + + envVarLen = strlen (envVar); + CHECKLEN (buf, envVarLen); + memcpy (bufptr, envVar, envVarLen); + bufptr += envVarLen; + src = end; break; + } #endif default: CHECKLEN(buf, 1); diff --git a/sc2/src/starcon2.c b/sc2/src/starcon2.c index 59597ded8..3dc410384 100644 --- a/sc2/src/starcon2.c +++ b/sc2/src/starcon2.c @@ -57,6 +57,7 @@ struct options_struct { int width; int height; int bpp; + const char *configDir; const char *contentDir; const char **addons; int numAddons; @@ -105,6 +106,7 @@ main (int argc, char *argv[]) /* .width = */ 640, /* .height = */ 480, /* .bpp = */ 16, + /* .configDir = */ NULL, /* .contentDir = */ NULL, /* .addons = */ NULL, /* .numAddons = */ 0, @@ -192,7 +194,7 @@ main (int argc, char *argv[]) initIO(); prepareContentDir (options.contentDir, options.addons); HFree ((void *) options.addons); - prepareConfigDir (); + prepareConfigDir (options.configDir); prepareMeleeDir (); prepareSaveDir (); initTempDir(); @@ -241,7 +243,7 @@ enum ADDON_OPT }; -static const char *optString = "+r:d:foc:b:spn:?hM:S:T:m:q:ug:l:"; +static const char *optString = "+r:d:foc:b:spC:n:?hM:S:T:m:q:ug:l:"; static struct option longOptions[] = { {"res", 1, NULL, 'r'}, @@ -252,6 +254,7 @@ static struct option longOptions[] = {"meleescale", 1, NULL, 'b'}, {"scanlines", 0, NULL, 's'}, {"fps", 0, NULL, 'p'}, + {"configdir", 1, NULL, 'C'}, {"contentdir", 1, NULL, 'n'}, {"help", 0, NULL, 'h'}, {"musicvol", 1, NULL, 'M'}, @@ -325,6 +328,9 @@ parseOptions(int argc, char *argv[], struct options_struct *options) break; switch (c) { + case 'C': + options->configDir = optarg; + break; case 'r': { int width, height; @@ -647,6 +653,7 @@ usage (FILE *out) fprintf (out, " -p, --fps (default off)\n"); fprintf (out, " -g, --gamma=CORRECTIONVALUE (default 1.0, which " "causes no change)\n"); + fprintf (out, " -C, --configdir=CONFIGDIR\n"); fprintf (out, " -n, --contentdir=CONTENTDIR\n"); fprintf (out, " -M, --musicvol=VOLUME (0-100, default 100)\n"); fprintf (out, " -S, --sfxvol=VOLUME (0-100, default 100)\n");