config: enable user to specify path to configuration file

This commit is contained in:
Daniel Eklöf 2019-12-17 19:08:43 +01:00
parent d15631e3de
commit caa76bcdea
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 65 additions and 35 deletions

View file

@ -463,7 +463,7 @@ get_server_socket_path(void)
}
bool
config_load(struct config *conf)
config_load(struct config *conf, const char *conf_path)
{
bool ret = false;
@ -513,28 +513,35 @@ config_load(struct config *conf)
.server_socket_path = get_server_socket_path(),
};
char *path = get_config_path();
if (path == NULL) {
/* Default conf */
LOG_WARN("no configuration found, using defaults");
ret = true;
goto out;
char *default_path = NULL;
if (conf_path == NULL) {
if ((default_path = get_config_path()) == NULL) {
/* Default conf */
LOG_WARN("no configuration found, using defaults");
ret = true;
goto out;
}
conf_path = default_path;
}
LOG_DBG("loading configuration from %s", path);
assert(conf_path != NULL);
LOG_INFO("loading configuration from %s", conf_path);
FILE *f = fopen(path, "r");
FILE *f = fopen(conf_path, "r");
if (f == NULL) {
LOG_ERR("%s: failed to open", path);
LOG_ERR("%s: failed to open", conf_path);
goto out;
}
ret = parse_config_file(f, conf, path);
ret = parse_config_file(f, conf, conf_path);
fclose(f);
if (ret && tll_length(conf->fonts) == 0)
tll_push_back(conf->fonts, strdup("monospace"));
out:
tll_push_back(conf->fonts, strdup("monospace"));
free(path);
free(default_path);
return ret;
}

View file

@ -38,5 +38,5 @@ struct config {
char *server_socket_path;
};
bool config_load(struct config *conf);
bool config_load(struct config *conf, const char *path);
void config_free(struct config conf);

65
main.c
View file

@ -38,7 +38,8 @@ print_usage(const char *prog_name)
printf("Usage: %s [OPTIONS]... -- command\n", prog_name);
printf("\n");
printf("Options:\n");
printf(" -f,--font=FONT comma separated list of fonts in fontconfig format (monospace)\n"
printf(" -c,--config=PATH load configuration from PATH (XDG_CONFIG_HOME/footrc)\n"
" -f,--font=FONT comma separated list of fonts in fontconfig format (monospace)\n"
" -t,--term=TERM value to set the environment variable TERM to (foot)\n"
" -g,--geometry=WIDTHxHEIGHT set initial width and height\n"
" -s,--server[=PATH] run as a server (use 'footclient' to start terminals).\n"
@ -68,13 +69,10 @@ main(int argc, char *const *argv)
* don't pass this on to programs launched by us */
unsetenv("DESKTOP_STARTUP_ID");
struct config conf = {NULL};
if (!config_load(&conf))
return ret;
const char *const prog_name = argv[0];
static const struct option longopts[] = {
{"config", required_argument, 0, 'c'},
{"term", required_argument, 0, 't'},
{"font", required_argument, 0, 'f'},
{"geometry", required_argument, 0, 'g'},
@ -84,21 +82,30 @@ main(int argc, char *const *argv)
{NULL, no_argument, 0, 0},
};
const char *conf_path = NULL;
const char *conf_term = NULL;
tll(char *) conf_fonts = tll_init();
int conf_width = -1;
int conf_height = -1;
bool as_server = false;
const char *conf_server_socket_path = NULL;
while (true) {
int c = getopt_long(argc, argv, ":t:f:g:s::vh", longopts, NULL);
int c = getopt_long(argc, argv, ":c:tf:g:s::vh", longopts, NULL);
if (c == -1)
break;
switch (c) {
case 'c':
conf_path = optarg;
break;
case 't':
free(conf.term);
conf.term = strdup(optarg);
conf_term = optarg;
break;
case 'f':
tll_free_and_free(conf.fonts, free);
tll_free_and_free(conf_fonts, free);
for (char *font = strtok(optarg, ","); font != NULL; font = strtok(NULL, ",")) {
/* Strip leading spaces */
@ -115,7 +122,7 @@ main(int argc, char *const *argv)
if (strlen(font) == 0)
continue;
tll_push_back(conf.fonts, strdup(font));
tll_push_back(conf_fonts, strdup(font));
}
break;
@ -123,41 +130,34 @@ main(int argc, char *const *argv)
unsigned width, height;
if (sscanf(optarg, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
fprintf(stderr, "error: invalid geometry: %s\n", optarg);
config_free(conf);
return EXIT_FAILURE;
}
conf.width = width;
conf.height = height;
conf_width = width;
conf_height = height;
break;
}
case 's':
as_server = true;
if (optarg != NULL) {
free(conf.server_socket_path);
conf.server_socket_path = strdup(optarg);
}
if (optarg != NULL)
conf_server_socket_path = optarg;
break;
case 'v':
printf("foot version %s\n", FOOT_VERSION);
config_free(conf);
return EXIT_SUCCESS;
case 'h':
print_usage(prog_name);
config_free(conf);
return EXIT_SUCCESS;
case ':':
fprintf(stderr, "error: -%c: missing required argument\n", optopt);
config_free(conf);
return EXIT_FAILURE;
case '?':
fprintf(stderr, "error: -%c: invalid option\n", optopt);
config_free(conf);
return EXIT_FAILURE;
}
}
@ -169,6 +169,29 @@ main(int argc, char *const *argv)
setlocale(LC_ALL, "");
struct config conf = {NULL};
if (!config_load(&conf, conf_path))
return ret;
if (conf_term != NULL) {
free(conf.term);
conf.term = strdup(conf_term);
}
if (tll_length(conf_fonts) > 0) {
tll_free_and_free(conf.fonts, free);
tll_foreach(conf_fonts, it)
tll_push_back(conf.fonts, it->item);
tll_free(conf_fonts);
}
if (conf_width > 0)
conf.width = conf_width;
if (conf_height > 0)
conf.height = conf_height;
if (conf_server_socket_path != NULL) {
free(conf.server_socket_path);
conf.server_socket_path = strdup(conf_server_socket_path);
}
struct fdm *fdm = NULL;
struct wayland *wayl = NULL;
struct terminal *term = NULL;