]> Nishi Git Mirror - gwion.git/commitdiff
:art: Drop getopt
authorfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 13 Mar 2019 00:18:34 +0000 (01:18 +0100)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 13 Mar 2019 00:18:34 +0000 (01:18 +0100)
also remove long option support

include/arg.h
include/driver.h
src/arg.c
tests/sh/opt.sh

index c442a0c4f6c61108daa0a97d9a9a70f2b72f2969..d2703e4c74b64dd3254d5864246358c837750eae 100644 (file)
@@ -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;
index 5a2ea549e0c4ef808022c3e1df23067c50dbbcea..2dc2956ccd38dc3808717fd5bb37797032d0a3c8 100644 (file)
@@ -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;
index d3aea336db64df4669ba909ac0cba8174c8a2ebf..a30226a0938a1c4cd22d1ab7913294a5a5d2ac15 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -1,15 +1,26 @@
-#include <getopt.h>
+#include <string.h>
 #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 <options>\n"
-"\toption can be any of:\n"
-"GLOBAL options:  <argument>  : description\n"
-"\t--help,      -h\t             : this help\n"
-"\t--plugdir,   -P\t <directory> : add a plugin directory\n"
-"\t--driver     -d\t  <string>   : set the driver\n"
-"\t--module     -m\t  <string>   : module setting\n"
-"\t--sr         -s\t  <number>   : 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  <number>   : set samplerate\n"
+"\t-i\t  <number>   : set input channel number\n"
+"\t-o\t  <number>   : set output channel number\n"
+"\t-d\t  <number>   : set driver (and arguments)\n"
+"\t-m\t  <number>   : load module (and arguments)\n"
+"\t-p\t <directory> : 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);
 }
index c2a773310d6141ba37b675a8c9d978ba5ce3e7c0..478a8ecfa88ba8a2a5a1eb5c387426a7e97ed2ae 100644 (file)
@@ -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"