aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2020-09-29 07:48:52 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2020-10-29 08:02:00 +0100
commita662fb822e283e21a67be9f46c0682eee17cf787 (patch)
tree3876b2c3ca1197e0256caf08eabf2440c5d2cc53 /src
parent76c6304ae3994be2822167f3282f7694a6d0214e (diff)
Options: Add support for quotes and escape sequences
Diffstat (limited to 'src')
-rw-r--r--src/liboptions/options.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/src/liboptions/options.c b/src/liboptions/options.c
index 7dd4052..4b8f062 100644
--- a/src/liboptions/options.c
+++ b/src/liboptions/options.c
@@ -71,7 +71,7 @@ int options_config_file(const char *config_file, int (*handle_options)(int short
char params[1024];
int line;
int rc = 1;
- int i, j;
+ int i, j, quote;
option_t *option;
/* open config file */
@@ -118,8 +118,45 @@ int options_config_file(const char *config_file, int (*handle_options)(int short
while (*p) {
/* copy parameter */
j = 0;
- while (*p > ' ')
+ quote = 0;
+ while (*p) {
+ /* escape allows all following characters */
+ if (*p == '\\') {
+ p++;
+ if (*p)
+ param[j++] = *p++;
+ continue;
+ }
+ /* no quote, check for them or break on white space */
+ if (quote == 0) {
+ if (*p == '\'') {
+ quote = 1;
+ p++;
+ continue;
+ }
+ if (*p == '\"') {
+ quote = 2;
+ p++;
+ continue;
+ }
+ if (*p <= ' ')
+ break;
+ }
+ /* single quote, check for unquote */
+ if (quote == 1 && *p == '\'') {
+ quote = 0;
+ p++;
+ continue;
+ }
+ /* double quote, check for unquote */
+ if (quote == 2 && *p == '\"') {
+ quote = 0;
+ p++;
+ continue;
+ }
+ /* copy character */
param[j++] = *p++;
+ }
param[j] = '\0';
argv[i] = strdup(param);
sprintf(strchr(params, '\0'), " '%s'", param);
@@ -148,7 +185,6 @@ int options_config_file(const char *config_file, int (*handle_options)(int short
PDEBUG(DOPTIONS, DEBUG_ERROR, "Given option '%s' in config file '%s' at line %d requires %d parameter(s), use '-h' for help!\n", opt, config_file, line, option->parameter_count);
return -EINVAL;
}
- for (j = 0; j < i; j++)
rc = handle_options(option->short_option, 0, argv);
if (rc <= 0)
goto done;