From: fennecdjay Date: Wed, 13 Mar 2019 00:18:34 +0000 (+0100) Subject: :art: Drop getopt X-Git-Tag: nightly~2742 X-Git-Url: http://10.11.0.4:5575/?a=commitdiff_plain;h=b93373c8a5ec5b7678d5fb104028372eb570d207;p=gwion.git :art: Drop getopt also remove long option support --- diff --git a/include/arg.h b/include/arg.h index c442a0c4..d2703e4c 100644 --- a/include/arg.h +++ b/include/arg.h @@ -7,6 +7,7 @@ typedef struct Arg_ { struct Vector_ add; struct Vector_ lib; struct Vector_ mod; + struct Vector_ config; struct SoundInfo_ *si; m_bool loop; } Arg; diff --git a/include/driver.h b/include/driver.h index 5a2ea549..2dc2956c 100644 --- a/include/driver.h +++ b/include/driver.h @@ -1,13 +1,13 @@ #ifndef __DRIVER #define __DRIVER -typedef m_bool (*f_drvini)(VM*, struct BBQ_*); -typedef void (*f_drvrun)(VM*, struct BBQ_*); -typedef void (*f_drvdel)(VM*, struct BBQ_*); +typedef m_bool (*f_drvini)(struct VM_*, struct BBQ_*); +typedef void (*f_drvrun)(struct VM_*, struct BBQ_*); +typedef void (*f_drvdel)(struct VM_*, struct BBQ_*); -#define DRVINI(a) ANN m_bool a(VM *vm __attribute__((unused)), struct BBQ_* di __attribute__((unused))) -#define DRVRUN(a) ANN void a(VM *vm __attribute__((unused)), struct BBQ_* di __attribute__((unused))) -#define DRVDEL(a) ANN void a(VM *vm __attribute__((unused)), struct BBQ_* di __attribute__((unused))) +#define DRVINI(a) ANN m_bool a(struct VM_ *vm __attribute__((unused)), struct BBQ_* di __attribute__((unused))) +#define DRVRUN(a) ANN void a(struct VM_ *vm __attribute__((unused)), struct BBQ_* di __attribute__((unused))) +#define DRVDEL(a) ANN void a(struct VM_ *vm __attribute__((unused)), struct BBQ_* di __attribute__((unused))) typedef struct DriverData_ { void* data; diff --git a/src/arg.c b/src/arg.c index d3aea336..a30226a0 100644 --- a/src/arg.c +++ b/src/arg.c @@ -1,15 +1,26 @@ -#include +#include #include "gwion_util.h" #include "oo.h" #include "vm.h" #include "driver.h" #include "arg.h" #include "sound.h" +#define GWIONRC ".gwionrc" + +ANN static inline void config_end(const Vector config) { + for(m_uint i = 0; i < vector_size(config); ++i) { + const Vector v = (Vector)vector_at(config, i); + for(m_uint i = 1; i < vector_size(v); ++i) + xfree((m_str)vector_at(v, i)); + free_vector(v); + } +} ANN static void arg_init(Arg* arg) { vector_init(&arg->add); vector_init(&arg->lib); vector_init(&arg->mod); + vector_init(&arg->config); vector_add(&arg->lib, (vtype)GWPLUG_DIR); } @@ -17,78 +28,118 @@ ANN void arg_release(Arg* arg) { vector_release(&arg->add); vector_release(&arg->lib); vector_release(&arg->mod); + config_end(&arg->config); + vector_release(&arg->config); } -static const struct option long_option[] = { - { "plugdir", 0, NULL, 'p' }, - { "driver", 1, NULL, 'd' }, - { "sr", 1, NULL, 's' }, - { "in", 1, NULL, 'i' }, - { "out", 1, NULL, 'o' }, - { "loop", 1, NULL, 'l' }, - { "help", 0, NULL, 'h' }, - { "config", 0, NULL, 'c' }, - { "module", 0, NULL, 'm' }, - { NULL, 0, NULL, 0 } -}; - static const char usage[] = "usage: Gwion \n" -"\toption can be any of:\n" -"GLOBAL options: : description\n" -"\t--help, -h\t : this help\n" -"\t--plugdir, -P\t : add a plugin directory\n" -"\t--driver -d\t : set the driver\n" -"\t--module -m\t : module setting\n" -"\t--sr -s\t : set samplerate\n" +"\t-h\t : this help\n" +"\t-c\t : load config\n" +"\t-k\t : show compilation flags\n" +"\t-s\t : set samplerate\n" +"\t-i\t : set input channel number\n" +"\t-o\t : set output channel number\n" +"\t-d\t : set driver (and arguments)\n" +"\t-m\t : load module (and arguments)\n" +"\t-p\t : add a plugin directory\n" ; -ANN static inline void arg_add(Arg *arg) { - while(optind < arg->argc) - vector_add(&arg->add, (vtype)arg->argv[optind++]); +ANN static void config_parse(Arg* arg, const m_str name); +#define get_arg(a) (a[i][2] == '\0' ? arg->argv[++i] : a[i] + 2) +#define ARG2INT(a) strtol(get_arg(a), NULL, 10) +ANN void _arg_parse(Arg* arg) { + for(int i = 1; i < arg->argc; ++i) { + if(arg->argv[i][0] == '-') { + switch(arg->argv[i][1]) { + case 'h': + gw_err(usage); + break; + case 'k': + gw_err("CFLAGS: %s\nLDFLAGS: %s\n", CFLAGS, LDFLAGS); + break; + case 'c': + config_parse(arg, get_arg(arg->argv)); + break; + case 'p': + vector_add(&arg->lib, (vtype)get_arg(arg->argv)); + break; + case 'm': + vector_add(&arg->mod, (vtype)get_arg(arg->argv)); + break; + case 'l': + arg->loop = (m_bool)ARG2INT(arg->argv) > 0 ? 1 : -1; + break; + case 'i': + arg->si->in = (uint8_t)ARG2INT(arg->argv); + break; + case 'o': + arg->si->out = (uint8_t)ARG2INT(arg->argv); + break; + case 's': + arg->si->sr = (uint32_t)ARG2INT(arg->argv); + break; + case 'd': + arg->si->arg = get_arg(arg->argv); + break; + } + } else + vector_add(&arg->add, (vtype)arg->argv[i]); + } +} + +ANN static void split_line(const m_str line, const Vector v) { + m_str d = strdup(line), c = d; + while(d) { + const m_str str = strsep(&d, " "); + const size_t sz = strlen(str); + const m_bool arg = (str[sz-1] == '\n'); + vector_add(v, (vtype)strndup(str, arg ? sz - 1 : sz)); + } + free(d); + free(c); } -ANN static void arg_drvr(struct SoundInfo_ *si, const int i) { - switch(i) { - case 'i': - si->in = (m_uint)strtol(optarg, NULL, 10); - break; - case 'o': - si->out = (m_uint)strtol(optarg, NULL, 10); - break; - case 's': - si->sr = (uint)strtol(optarg, NULL, 10); - break; - case 'd': - si->arg = optarg; - break; +ANN static Vector get_config(const m_str name) { + char *line = NULL; + size_t len = 0; + ssize_t nread; + FILE *f = fopen(name, "r"); + CHECK_OO(f) + const Vector v = new_vector(); + vector_add(v, (vtype)name); + while((nread = getline(&line, &len, f)) != -1) { + if(line[0] != '#') + split_line(line, v); } + free(line); + fclose(f); + return v; } -ANN void arg_parse(Arg* arg) { - int i, idx; - arg_init(arg); - while((i = getopt_long(arg->argc, arg->argv, "hl:i:o:s:d:m:p:c", - long_option, &idx)) != -1) { - switch(i) { - case 'h': - gw_err(usage); - break; - case 'c': - gw_err("CFLAGS: %s\nLDFLAGS: %s\n", CFLAGS, LDFLAGS); - break; - case 'l': - arg->loop = strtol(optarg, NULL, 10) > 0 ? 1 : -1; - break; - case 'p': - vector_add(&arg->lib, (vtype)optarg); - break; - case 'm': - vector_add(&arg->mod, (vtype)optarg); - break; - default: - arg_drvr(arg->si, i); - } +ANN static void config_parse(Arg* arg, const m_str name) { + const Vector v = get_config(name); + if(v) { + int argc = arg->argc; + char** argv = arg->argv; + arg->argc = vector_size(v); + arg->argv = (m_str*)(v->ptr + OFFSET); + _arg_parse(arg); + arg->argc = argc; + arg->argv = argv; + vector_add(&arg->config, (vtype)v); } - arg_add(arg); +} + +ANN static void config_default(Arg* arg) { + char* home = getenv("HOME"); + char c[strlen(home) + strlen(GWIONRC) + 2]; + sprintf(c, "%s/%s", home, GWIONRC); + config_parse(arg, c); +} + +ANN void arg_parse(Arg* a) { + arg_init(a); + config_default(a); + _arg_parse(a); } diff --git a/tests/sh/opt.sh b/tests/sh/opt.sh index c2a77331..478a8ecf 100644 --- a/tests/sh/opt.sh +++ b/tests/sh/opt.sh @@ -1,5 +1,5 @@ #!/bin/bash -# [test] #17 +# [test] #11 n=0 [ "$1" ] && n="$1" [ "$n" -eq 0 ] && n=1 @@ -22,38 +22,26 @@ rm "file" # help n=$((n+1)) run "$n" "help (short)" "-?" "file" -n=$((n+1)) -run "$n" "help (long)" "--help" "file" # host n=$((n+1)) run "$n" "host invalid (short)" "-h non_existant_host" "file" -n=$((n+1)) -run "$n" "host invalid (long)" "--host non_existant_host " "file" # help n=$((n+1)) run "$n" "help (short)" "-?" "file" -n=$((n+1)) -run "$n" "help (long)" "--help" "file" # in channels n=$((n+1)) run "$n" "in channels (short)" "-i 2" "file" -n=$((n+1)) -run "$n" "in channels (long)" "--in 2" "file" # out channels n=$((n+1)) run "$n" "out channels (short)" "-o 2" "file" -n=$((n+1)) -run "$n" "out channels (long)" "--out 2" "file" # samplerate n=$((n+1)) run "$n" "samplerate (short)" "-s 44100" "file" -n=$((n+1)) -run "$n" "samplerate (long)" "--sr 44100" "file" # wrong file n=$((n+1)) @@ -65,4 +53,4 @@ run "$n" "plugin directory" "-p non_existant_dir" "file" # config n=$((n+1)) -run "$n" "config" "-c" "file" +run "$n" "config" "-k" "file"