From 1c941e71e78d696faf17401eb91365d8ef521382 Mon Sep 17 00:00:00 2001 From: Joshua Potter Date: Thu, 23 Nov 2023 08:07:22 -0700 Subject: [PATCH] Get the CWD on launch. --- include/config.h | 18 ++++++++++++------ main.c | 16 ++++++++++------ src/config.c | 23 ++++++++--------------- test/test_config.h | 39 ++++++++++++++++++++------------------- 4 files changed, 50 insertions(+), 46 deletions(-) diff --git a/include/config.h b/include/config.h index 6c03777..3d4c3c0 100644 --- a/include/config.h +++ b/include/config.h @@ -2,22 +2,28 @@ #define _SPEC_CONFIG_H struct Config { - // The root directory housing our specs. This string is nonempty. + // The directory the `spec` command was run from. + // OWNERSHIP: Does not own this pointer. + const char *cwd; + // The root directory housing our specs. + // OWNERSHIP: Does not own this pointer. const char *root_dir; - // The name of the spec we want to load. This string is nonempty. + // The name of the spec we want to load. + // OWNERSHIP: Does not own this pointer. const char *target; }; enum ConfigError { + // Indicates the $CWD could not be retrieved. + CE_ENV_CWD_INVALID = 1, // Indicates the `$SPEC_ROOT_DIR` environment variable is empty. - ENV_SPEC_ROOT_DIR_MISSING = 1, - // Indicates the `$SPEC_ROOT_DIR` environment variable is not set. - ENV_SPEC_ROOT_DIR_EMPTY, + CE_ENV_SPEC_ROOT_DIR_INVALID, // Indicates the target argument is invalid. - INVALID_TARGET, + CE_TARGET_INVALID, }; enum ConfigError config_load( + const char *cwd, const char *root_dir, const char *target, struct Config **config diff --git a/main.c b/main.c index fc53e15..1730755 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,6 @@ #include #include +#include #include "config.h" #include "dyn_array.h" @@ -14,21 +15,24 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); } + const char *cwd = getcwd(0, 0); const char *root_dir = getenv(ENV_SPEC_ROOT_DIR); + const char *target = argv[1]; struct Config *config = 0; - switch (config_load(root_dir, argv[1], &config)) { - case ENV_SPEC_ROOT_DIR_MISSING: + switch (config_load(cwd, root_dir, target, &config)) { + case CE_ENV_CWD_INVALID: + fprintf(stderr, "Could not retrieve the $CWD value."); + exit(EXIT_FAILURE); + case CE_ENV_SPEC_ROOT_DIR_INVALID: fprintf(stderr, "Must specify $SPEC_ROOT_DIR environment variable."); exit(EXIT_FAILURE); - case ENV_SPEC_ROOT_DIR_EMPTY: - fprintf(stderr, "$SPEC_ROOT_DIR environment variable should not be empty."); - exit(EXIT_FAILURE); - case INVALID_TARGET: + case CE_TARGET_INVALID: fprintf(stderr, "Target spec `%s` is invalid.", argv[1]); exit(EXIT_FAILURE); } config_free(config); + free((void *)cwd); return EXIT_SUCCESS; } diff --git a/src/config.c b/src/config.c index be4c4bc..2d4d11a 100644 --- a/src/config.c +++ b/src/config.c @@ -4,31 +4,25 @@ #include "config.h" enum ConfigError config_load( + const char *cwd, const char *root_dir, const char *target, struct Config **config ) { - if (root_dir == 0) { - return ENV_SPEC_ROOT_DIR_MISSING; + if (cwd == 0) { + return CE_ENV_CWD_INVALID; } - if (root_dir[0] == 0) { - return ENV_SPEC_ROOT_DIR_EMPTY; + if (root_dir == 0) { + return CE_ENV_SPEC_ROOT_DIR_INVALID; } if (target == 0) { - return INVALID_TARGET; - } - - size_t target_len = strlen(target); - if (target_len == 0) { - return INVALID_TARGET; + return CE_TARGET_INVALID; } *config = malloc(sizeof(struct Config)); + (*config)->cwd = cwd; (*config)->root_dir = root_dir; - - char *copy_target = calloc(1, target_len + 1); - strcpy(copy_target, target); - (*config)->target = copy_target; + (*config)->target = target; return 0; } @@ -37,6 +31,5 @@ void config_free(struct Config *config) { if (!config) { return; } - free((void *)config->target); free(config); } diff --git a/test/test_config.h b/test/test_config.h index 2e8436f..bf7acef 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -4,39 +4,40 @@ #include "config.h" #include "sput.h" +static const char *SAMPLE_CWD = "/home/jrpotter/Documents/spec"; +static const char *SAMPLE_ROOT_DIR = "/usr/local/share/specs"; +static const char *SAMPLE_TARGET = "example-target"; + +static void test_config_load_cwd_invalid() { + struct Config *config = 0; + enum ConfigError retval = + config_load(0, SAMPLE_ROOT_DIR, SAMPLE_TARGET, &config); + sput_fail_unless(retval == CE_ENV_CWD_INVALID, "target == 0"); +} + static void test_config_load_root_dir_invalid() { struct Config *config = 0; - - enum ConfigError retval = 0; - - retval = config_load(0, "target", &config); - sput_fail_unless(retval == ENV_SPEC_ROOT_DIR_MISSING, "root_dir == 0"); - - retval = config_load("", "target", &config); - sput_fail_unless(retval == ENV_SPEC_ROOT_DIR_EMPTY, "root_dir == \"\""); + enum ConfigError retval = config_load(SAMPLE_CWD, 0, SAMPLE_TARGET, &config); + sput_fail_unless(retval == CE_ENV_SPEC_ROOT_DIR_INVALID, "root_dir == 0"); } static void test_config_load_target_invalid() { struct Config *config = 0; - enum ConfigError retval = 0; - - retval = config_load("/usr/local/share/specs", 0, &config); - sput_fail_unless(retval == INVALID_TARGET, "target == 0"); - - retval = config_load("/usr/local/share/specs", "", &config); - sput_fail_unless(retval == INVALID_TARGET, "target == \"\""); + enum ConfigError retval = + config_load(SAMPLE_CWD, SAMPLE_ROOT_DIR, 0, &config); + sput_fail_unless(retval == CE_TARGET_INVALID, "target == 0"); } static void test_config_load_success() { struct Config *config = 0; enum ConfigError retval = - config_load("/usr/local/share/specs", "target", &config); + config_load(SAMPLE_CWD, SAMPLE_ROOT_DIR, SAMPLE_TARGET, &config); sput_fail_unless(retval == 0, "config_load() success"); - sput_fail_unless(strcmp(config->root_dir, "/usr/local/share/specs") == 0, + sput_fail_unless(strcmp(config->root_dir, SAMPLE_ROOT_DIR) == 0, "config_load() root_dir"); - sput_fail_unless(strcmp(config->target, "target") == 0, - "config_load(0 target"); + sput_fail_unless(strcmp(config->target, SAMPLE_TARGET) == 0, + "config_load() target"); config_free(config); }