[beast: 4/19] BSE: bsetool: add simple argument parser
- From: Tim Janik <timj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [beast: 4/19] BSE: bsetool: add simple argument parser
- Date: Sun, 13 Sep 2015 20:26:26 +0000 (UTC)
commit 06dab3dd43e9b51b07f8516707b5c09b6c24c272
Author: Tim Janik <timj gnu org>
Date: Mon Sep 7 01:31:28 2015 +0200
BSE: bsetool: add simple argument parser
bse/Makefile.am | 2 +-
bse/bsetool.cc | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 137 insertions(+), 3 deletions(-)
---
diff --git a/bse/Makefile.am b/bse/Makefile.am
index 8460b59..065c21b 100644
--- a/bse/Makefile.am
+++ b/bse/Makefile.am
@@ -364,7 +364,7 @@ bseinfo_LDADD = $(progs_LDADD)
# == bsetool ==
noinst_PROGRAMS += bsetool
bsetool_SOURCES = bsetool.cc
-bsetool_LDADD = libbse.la
+bsetool_LDADD = libbse.la $(RAPICORN_LIBS)
# == Tests ==
EXTRA_DIST += oldidl.idl
diff --git a/bse/bsetool.cc b/bse/bsetool.cc
index a57fcb1..157070e 100644
--- a/bse/bsetool.cc
+++ b/bse/bsetool.cc
@@ -1,15 +1,149 @@
// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include <bse/bsemain.hh>
+#include <bse/bseserver.hh>
#include <sys/resource.h>
+#include <unordered_map>
#include <unistd.h>
#include <stdio.h>
+using namespace Bse;
+
+struct ArgDescription {
+ const char *arg_name, *value_name, *arg_blurb;
+ String value;
+};
+
+class ArgParser {
+ const size_t n_args_;
+ ArgDescription *const args_;
+ std::unordered_map<String, ArgDescription*> names_;
+ void parse_args (const size_t N, const ArgDescription *adescs);
+public:
+ template<size_t N>
+ explicit ArgParser (ArgDescription (&adescs) [N]) : n_args_ (N), args_ (adescs) {}
+ String parse_args (const uint argc, char *const argv[]); // returns error message
+ String operator[] (const String &arg_name) const;
+};
+
+String
+ArgParser::operator[] (const String &arg_name) const
+{
+ auto it = names_.find (arg_name);
+ if (it == names_.end())
+ return "";
+ ArgDescription *adesc = it->second;
+ return adesc->value;
+}
+
+String
+ArgParser::parse_args (const uint argc, char *const argv[])
+{
+ std::unordered_map<String, String> aliases;
+ std::vector<String> fixed; // fixed arguments, like <OBLIGATION> or [OPTIONAL]
+ size_t need_obligatory = 0;
+ // fill names_ from args_
+ for (size_t i = 0; i < n_args_; i++)
+ {
+ StringVector names = string_split (args_[i].arg_name, ",");
+ for (size_t j = 0; j < names.size(); j++)
+ {
+ String name = string_canonify (names[j], string_set_a2z() + string_set_A2Z() + "0123456789_-", "");
+ while (name[0] == '-')
+ name = name.substr (1);
+ if (name.empty())
+ continue;
+ if (j == 0)
+ {
+ names_[name] = &args_[i];
+ if (names[j][0] == '<')
+ {
+ need_obligatory++;
+ fixed.push_back (name);
+ }
+ else if (names[j][0] == '[')
+ fixed.push_back (name);
+ }
+ else // found an alias after ','
+ names_[name] = &args_[i];
+ }
+ }
+ // parse and assign command line arguments
+ bool seen_dashdash = false;
+ size_t fixed_index = 0;
+ for (size_t i = 0; i < argc; i++)
+ if (!argv[i])
+ continue;
+ else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0)
+ seen_dashdash = true;
+ else if (!seen_dashdash && argv[i][0] == '-')
+ {
+ const char *arg = argv[i] + 1 + (argv[i][1] == '-');
+ const char *eq = strchr (arg, '=');
+ String arg_name = !eq ? arg : String (arg, eq - arg);
+ auto it = names_.find (arg_name);
+ if (it == names_.end())
+ return string_format ("invalid argument: %s", argv[i]);
+ ArgDescription *adesc = it->second;
+ if (adesc->value_name && adesc->value_name[0])
+ {
+ if (eq)
+ adesc->value = eq + 1;
+ else
+ {
+ if (i + 1 >= argc)
+ return string_format ("incomplete argument: %s", argv[i]); // argument lacks value
assignment
+ i++;
+ adesc->value = argv[i];
+ }
+ }
+ else
+ adesc->value = "1"; // value means 'option is present'
+ }
+ else // non-option arguments
+ {
+ if (fixed_index >= fixed.size())
+ return string_format ("invalid extra argument: %s", argv[i]);
+ ArgDescription *adesc = names_[fixed[fixed_index]];
+ adesc->value = argv[i];
+ fixed_index++;
+ }
+ if (fixed_index < need_obligatory)
+ return string_format ("missing mandatory argument <%s>", fixed[fixed_index]);
+ return ""; // success
+}
+
+static ArgDescription bsetool_options[] = {
+ { "--bse-no-load", "", "Prevent automated plugin and script registration", "" },
+};
+
int
main (int argc, char *argv[])
{
+ printout ("bsetool!\n");
bse_init_inprocess (&argc, argv, "bsetool"); // Bse::cstrings_to_vector (NULL)
// now that the BSE thread runs, drop scheduling priorities if we have any
setpriority (PRIO_PROCESS, getpid(), 0);
- printf ("bsetool!\n");
- return 0;
+ // pre-command option argument parsing
+ size_t option_argc = 1; // skip argv[0]
+ while (option_argc < argc && argv[option_argc][0] == '-')
+ option_argc++;
+ ArgParser toolap (bsetool_options);
+ String error = toolap.parse_args (option_argc - 1, argv + 1); // skip argv[0]
+ if (!error.empty())
+ {
+ printerr ("%s: %s\n", argv[0], error);
+ return 127;
+ }
+ // load BSE plugins, scripts, ladspa plugins, etc
+ if (!string_to_bool (toolap["bse-no-load"]))
+ {
+ BSE_SERVER.register_core_plugins();
+ while (g_main_context_pending (bse_main_context))
+ {
+ printout (".");
+ g_main_context_iteration (bse_main_context, false);
+ }
+ printout ("\n");
+ }
+ return 0; // success
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]