[beast: 9/10] BSE: pybse: initialize libbse from sys.argv



commit de787ffeb39f5b1722b2ebc0f803eda8bbfb532b
Author: Tim Janik <timj gnu org>
Date:   Wed Jan 27 21:43:54 2016 +0100

    BSE: pybse: initialize libbse from sys.argv
    
    Signed-off-by: Tim Janik <timj gnu org>

 bse/pybse/Bse.pyx      |   10 ++++++-
 bse/pybse/pysupport.hh |   57 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 2 deletions(-)
---
diff --git a/bse/pybse/Bse.pyx b/bse/pybse/Bse.pyx
index 9fc07b5..ffb3295 100644
--- a/bse/pybse/Bse.pyx
+++ b/bse/pybse/Bse.pyx
@@ -4,7 +4,13 @@ include "Aida.pyx"
 # Generated Bse bindings (via PyxxStub.py)
 include "bseidlapi.pyx"
 
-# Provide main Bse singleton
-cdef extern from "bse/bse.hh" namespace "Bse":
+# provide libbse setup functions
+cdef extern from "pysupport.hh" namespace "Bse":
   Bse__Server Bse__init_server_instance   "Bse::init_server_instance" ()
+  bool        Bse__py_init_async          "Bse::py_init_async" () except *
+
+# initialize libbse from sys.argv if init_needed()
+Bse__py_init_async()
+
+# provide main libbse server singleton
 server = Bse__Object__wrap (Bse__init_server_instance())
diff --git a/bse/pybse/pysupport.hh b/bse/pybse/pysupport.hh
new file mode 100644
index 0000000..4027790
--- /dev/null
+++ b/bse/pybse/pysupport.hh
@@ -0,0 +1,57 @@
+// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
+#ifndef __BSE_PYSUPPORT_HH__
+#define __BSE_PYSUPPORT_HH__
+
+#include <bse/bse.hh>
+#include <Python.h>
+
+namespace Bse {
+
+bool py_init_async (const StringVector &args = StringVector());
+
+bool
+py_init_async (const StringVector &args)
+{
+  // avoid double initialization
+  if (!init_needed())
+    return true; // success
+  // convert sys.argv to char **argv;
+  PyObject *pyargv = PySys_GetObject (const_cast<char*> ("argv"));
+  const size_t pyargc = pyargv && PyList_Check (pyargv) ? PyList_Size (pyargv) : 0;
+  for (size_t i = 0; i < pyargc; i++)
+    if (!PyString_Check (PyList_GetItem (pyargv, i)))
+      {
+        pyargv = NULL;
+        break;
+      }
+  if (pyargc && !pyargv)
+    PyErr_Warn (PyExc_Warning, Rapicorn::string_format ("%s: failed to readout sys.argv", __func__).c_str());
+  if (PyErr_Occurred())
+    return false; // indicate exception
+  std::vector<String> sargv;
+  for (size_t i = pyargv ? 0 : pyargc; i < pyargc; i++)
+    printerr("argv[%d]: %s\n", i, PyString_AsString (PyList_GetItem (pyargv, i)));
+  for (size_t i = pyargv ? 0 : pyargc; i < pyargc; i++)
+    sargv.push_back (PyString_AsString (PyList_GetItem (pyargv, i)));
+  if (sargv.size() == 0)
+    sargv.push_back (Rapicorn::program_name());
+  char *cargv[sargv.size() + 1];
+  for (size_t i = 0; i < sargv.size(); i++)
+    cargv[i] = const_cast<char*> (sargv[i].c_str());
+  cargv[sargv.size()] = NULL;
+  // initialize libbse
+  int cargc = sargv.size();
+  cargv[0] = Py_GetProgramName();                       // correct Python's 'fabricated' argv[0]
+  init_async (&cargc, cargv, NULL, args);
+  // propagate argv adjustments back to sys.argv
+  if (cargc < ssize_t (sargv.size()))
+    {
+      cargv[0] = const_cast<char*> (sargv[0].c_str());  // retain Python's 'fabricated' argv[0]
+      PySys_SetArgv (cargc, cargv);
+    }
+  return !PyErr_Occurred();
+}
+
+} // Bse
+
+#endif /* __BSE_PYSUPPORT_HH__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]