aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2020-04-21 00:13:51 +0200
committercbdev <cb@cbcdn.com>2020-04-21 00:13:51 +0200
commit918fb606174dcf42553be65e3d2306996c52488f (patch)
tree98d0bc185c5d9cd2c0f3bbe6b0461ebbf1c8f502
parent8773fca1f7d2ffed68b6af4967b537d989a1e5b5 (diff)
downloadmidimonster-918fb606174dcf42553be65e3d2306996c52488f.tar.gz
midimonster-918fb606174dcf42553be65e3d2306996c52488f.tar.bz2
midimonster-918fb606174dcf42553be65e3d2306996c52488f.zip
Implement recursive configuration file parsing (Fixes #59)
-rw-r--r--README.md4
-rw-r--r--config.c25
-rw-r--r--midimonster.c2
3 files changed, 28 insertions, 3 deletions
diff --git a/README.md b/README.md
index 12d87eb..a7ca212 100644
--- a/README.md
+++ b/README.md
@@ -76,6 +76,10 @@ lines of the form `option = value`.
Lines starting with a semicolon are treated as comments and ignored. Inline comments
are not currently supported.
+Configuration files may be included recursively in other configuration files using
+the syntax `[include <file>]`. This will read the referenced configuration file as
+if it were inserted at that point.
+
Example configuration files may be found in [configs/](configs/).
### Backend and instance configuration
diff --git a/config.c b/config.c
index aef4f87..b5e0747 100644
--- a/config.c
+++ b/config.c
@@ -2,6 +2,11 @@
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
+#ifndef _WIN32
+#include <linux/limits.h>
+#endif
+
+#define BACKEND_NAME "core/cfg"
#include "midimonster.h"
#include "config.h"
#include "backend.h"
@@ -349,6 +354,10 @@ static int config_line(char* line){
}
}
}
+ else if(!strncmp(line, "[include ", 9)){
+ line[strlen(line) - 1] = 0;
+ return config_read(line + 9);
+ }
else if(!strcmp(line, "[map]")){
//mapping configuration
parser_state = map;
@@ -493,7 +502,7 @@ int config_read(char* cfg_filepath){
char* line_raw = NULL;
//create heap copy of file name because original might be in readonly memory
- char* source_dir = strdup(cfg_filepath), *source_file = NULL;
+ char* source_dir = strdup(cfg_filepath), *source_file = NULL, original_dir[PATH_MAX * 2] = "";
#ifdef _WIN32
char path_separator = '\\';
#else
@@ -510,6 +519,12 @@ int config_read(char* cfg_filepath){
if(source_file){
*source_file = 0;
source_file++;
+
+ if(!getcwd(original_dir, sizeof(original_dir))){
+ fprintf(stderr, "Failed to read current working directory: %s\n", strerror(errno));
+ goto bail;
+ }
+
if(chdir(source_dir)){
fprintf(stderr, "Failed to change to configuration file directory %s: %s\n", source_dir, strerror(errno));
goto bail;
@@ -519,10 +534,11 @@ int config_read(char* cfg_filepath){
source_file = source_dir;
}
+ fprintf(stderr, "Reading configuration file %s\n", cfg_filepath);
source = fopen(source_file, "r");
if(!source){
- fprintf(stderr, "Failed to open configuration file for reading\n");
+ fprintf(stderr, "Failed to open %s for reading\n", cfg_filepath);
goto bail;
}
@@ -536,6 +552,11 @@ int config_read(char* cfg_filepath){
rv = 0;
bail:
+ //change back to previous directory to allow recursive configuration file parsing
+ if(source_file && source_dir != source_file){
+ chdir(original_dir);
+ }
+
free(source_dir);
if(source){
fclose(source);
diff --git a/midimonster.c b/midimonster.c
index 8100607..1065e5c 100644
--- a/midimonster.c
+++ b/midimonster.c
@@ -482,7 +482,7 @@ int main(int argc, char** argv){
//read config
if(config_read(cfg_file)){
- fprintf(stderr, "Failed to read configuration file %s\n", cfg_file);
+ fprintf(stderr, "Failed to parse master configuration file %s\n", cfg_file);
backends_stop();
routing_cleanup();
fds_free();