c++-gtk-utils
extension.h
Go to the documentation of this file.
1 /* Copyright (C) 2014, 2016 and 2020 Chris Vine
2 
3 The library comprised in this file or of which this file is part is
4 distributed by Chris Vine under the GNU Lesser General Public
5 License as follows:
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public License
9  as published by the Free Software Foundation; either version 2.1 of
10  the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License, version 2.1, for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License, version 2.1, along with this library (see the file LGPL.TXT
19  which came with this source code package in the c++-gtk-utils
20  sub-directory); if not, write to the Free Software Foundation, Inc.,
21  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23 However, it is not intended that the object code of a program whose
24 source code instantiates a template from this file or uses macros or
25 inline functions (of any length) should by reason only of that
26 instantiation or use be subject to the restrictions of use in the GNU
27 Lesser General Public License. With that in mind, the words "and
28 macros, inline functions and instantiations of templates (of any
29 length)" shall be treated as substituted for the words "and small
30 macros and small inline functions (ten lines or less in length)" in
31 the fourth paragraph of section 5 of that licence. This does not
32 affect any other reason why object code may be subject to the
33 restrictions in that licence (nor for the avoidance of doubt does it
34 affect the application of section 2 of that licence to modifications
35 of the source code in this file).
36 
37 NOTE: If you incorporate this header file in your code, you will have
38 to link with libguile. libguile is released under the LGPL version 3
39 or later. By linking with libguile your code will therefore be
40 governed by the LPGL version 3 or later, not the LGPL version 2.1 or
41 later.
42 
43 */
44 
45 #ifndef CGU_EXTENSION_H
46 #define CGU_EXTENSION_H
47 
48 /**
49  * @namespace Cgu::Extension
50  * @brief This namespace provides functions to execute scheme code on the guile VM.
51  *
52  * \#include <c++-gtk-utils/extension.h>
53  *
54  * The Extension::exec() and Extension::exec_shared() functions
55  * provided by this library allow any C++ program to execute files
56  * written in the scheme language on the guile VM as part of the C++
57  * runtime. There are a number of reasons why this might be useful:
58  *
59  * @par
60  * - to enable the dynamic behaviour of the program to be altered
61  * without recompilation
62  *
63  * @par
64  * - to provide a plugin system
65  *
66  * @par
67  * - because some things are easier or quicker to do when done in
68  * a dynamically typed language such as scheme
69  *
70  * @par
71  * - because scheme is a nice language to use and highly
72  * extensible
73  *
74  * @par
75  * - with Extension::exec() and Extension::exec_shared(), it is
76  * trivial to do (see the example below)
77  *
78  * To call Extension::exec() or Extension::exec_shared(), guile-2.0 >=
79  * 2.0.2, guile-2.2 >= 2.1.3 or guile-3.0 >= 3.0.0 is required.
80  *
81  * Usage
82  * -----
83  *
84  * Extension::exec() and Extension::exec_shared() take three
85  * arguments. The first is a preamble string, which sets out any top
86  * level definitions which the script file needs to see. This is
87  * mainly intended for argument passing to the script file, but can
88  * comprise any scheme code. It can also be an empty string. The
89  * second is the name of the scheme script file to be executed, with
90  * path. This file can contain scheme code of arbitrary complexity
91  * and length, and can incorporate guile modules and other scheme
92  * files.
93  *
94  * The third argument is a translator. This is a function or callable
95  * object which takes the value to which the scheme file evaluates (in
96  * C++ terms, its return value) as an opaque SCM guile type (it is
97  * actually a pointer to a struct in the guile VM), and converts it to
98  * a suitable C++ representation using functions provided by libguile.
99  * The return value of the translator function comprises the return
100  * value of Extension::exec() and Extension::exec_shared().
101  *
102  * Translators
103  * -----------
104  *
105  * Preformed translators are provided by this library to translate
106  * from scheme's integers, real numbers and strings to C++ longs,
107  * doubles and strings respectively (namely
108  * Extension::integer_to_long(), Extension::real_to_double() and
109  * Extension::string_to_string()), and from any uniform lists of these
110  * to C++ vectors of the corresponding type
111  * (Extension::list_to_vector_long(),
112  * Extension::list_to_vector_double() and
113  * Extension::list_to_vector_string(). There is also a translator for
114  * void return types (Extension::any_to_void()), where the scheme
115  * script is executed for its side effects, perhaps I/O, where the
116  * return value is ignored and any communication necessary is done by
117  * guile exceptions.
118  *
119  * Any guile exception thrown by the code in the scheme file is
120  * trapped by the preformed translators and will be rethrown as an
121  * Extension::GuileException C++ exception. The preformed translators
122  * should suffice for most purposes, but custom translators can be
123  * provided by the user - see further below.
124  *
125  * Example
126  * -------
127  *
128  * Assume the following code is in a file called 'myip.scm'.
129  *
130  * @code
131  * ;; myip.scm
132  *
133  * ;; the following code assumes a top level definition of 'web-ip' is
134  * ;; passed, giving the URL of an IP address reflector
135  *
136  * (use-modules (ice-9 regex)(web uri)(web client))
137  * (let ([uri (build-uri 'http
138  * #:host web-ip
139  * #:port 80
140  * #:path "/")])
141  * (call-with-values
142  * (lambda () (http-get uri))
143  * (lambda (request body)
144  * (match:substring
145  * (string-match "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"
146  * body)))))
147  * @endcode
148  *
149  * This code requires guile >= 2.0.3, and makes a http request to the
150  * reflector, reads the body of the reply and then does a regex search
151  * on it to obtain the address. Courtesy of the good folks at DynDNS
152  * we can obtain our address with this:
153  *
154  * @code
155  * using namespace Cgu;
156  * std::cout << "IP address is: "
157  * << Extension::exec_shared("(define web-ip \"checkip.dyndns.com\")",
158  * "./myip.scm",
159  * &Extension::string_to_string)
160  * << std::endl;
161  * @endcode
162  *
163  * This is easier than doing the same in C++ using, say, libsoup and
164  * std::regex. However it is unsatisfying where we do not want the
165  * code to block waiting for the reply. There are a number of
166  * possible approaches to this, but one is to provide the result to a
167  * glib main loop asynchronously via a Thread::TaskManager object.
168  * There are two possibilities for this. First, the
169  * Thread::TaskManager::make_task_when_full() method could be used, to
170  * which a fail callback could be passed to execute if guile throws an
171  * exception (say because the url does not resolve). Alternatively,
172  * the scheme code in myip.scm could wrap itself in a guile catch
173  * expression, and hand back a list of two strings, the first string
174  * of which indicates an error condition with description (or an empty
175  * string if there is no error), and the second the result on success,
176  * in which case Thread::TaskManager::make_task_when() or
177  * Thread::TaskManager::make_task_compose() could be called. This
178  * does the second:
179  *
180  * @code
181  * ;; myip.scm
182  *
183  * ;; the following code assumes a top level definition of 'web-ip' is
184  * ;; passed, giving the URL of an IP address reflector
185  *
186  * (use-modules (ice-9 regex)(web uri)(web client))
187  * (let ([uri (build-uri 'http
188  * #:host web-ip
189  * #:port 80
190  * #:path "/")])
191  * (catch
192  * #t
193  * (lambda () ;; the 'try' block
194  * (call-with-values
195  * (lambda () (http-get uri))
196  * (lambda (request body)
197  * (list "" ;; empty string for first element of list - no error
198  * (match:substring
199  * (string-match "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"
200  * body)))))) ;; ip address as a string
201  * (lambda (key . details) ;; the 'catch' block
202  * (list (string-append "Exception in myip.scm: "
203  * (object->string (cons key details))) ;; exception details
204  * "")))) ;; empty string for second element of list - error
205  * @endcode
206  *
207  * @code
208  * using namespace Cgu;
209  * Thread::TaskManager tm{1};
210  * typedef std::vector<std::string> ResType;
211  * auto when = Callback::to_unique(
212  * Callback::lambda<const ResType&>([] (const ResType& res) {
213  * if (!res[0].empty()) {
214  * // display GtkMessageDialog object indicating failure
215  * }
216  * else {
217  * // publish result in res[1] in some GTK widget
218  * }
219  * }
220  * );
221  * tm.make_task_when (
222  * std::move(when),
223  * 0, // supply result to default glib main loop
224  * [] () {
225  * return Extension::exec_shared("(define web-ip \"checkip.dyndns.com\")",
226  * "./myip.scm",
227  * &Extension::list_to_vector_string);
228  * }
229  * );
230  * @endcode
231  *
232  * Extension::exec() and Extension::exec_shared()
233  * ----------------------------------------------
234  *
235  * Extension::exec() isolates the top level definitions of a task,
236  * including definitions in the preamble of a task or imported by
237  * guile's 'use-modules' or 'load' procedures, from the top level
238  * definitions of other tasks started by calls to Extension::exec(),
239  * by calling guile's 'make-fresh-user-module' procedure.
240  * Extension::exec_shared() does not do so: with
241  * Extension::exec_shared(), all scheme tasks executed by calls to
242  * that function will share the same top level. In addition,
243  * Extension::exec() loads the file passed to the function using the
244  * guile 'load' procedure, so that the first time the file is executed
245  * it is compiled into bytecode, whereas Extension::exec_shared()
246  * calls the 'primitive-load' procedure instead, which runs the file
247  * through the guile interpreter without converting it to bytecode.
248  *
249  * The reason for this different behaviour of Extension::exec_shared()
250  * is that, as currently implemented in guile both the
251  * 'make-fresh-user-module' and 'load' procedures leak small amounts
252  * of memory. If a particular program is likely to call
253  * Extension::exec() more than about 5,000 or 10,000 times, it would
254  * be better to use Extension::exec_shared() instead.
255  *
256  * From guile-2.0.2, Extension::exec() and Extension::exec_shared() do
257  * not need to be called only in the main program thread - and in the
258  * above example using a Thread::TaskManager object
259  * Extension::exec_shared() was not. However, one of the consequences
260  * of the behaviour mentioned above is that if
261  * Extension::exec_shared() is to be used instead of
262  * Extension::exec(), either concurrent calls to the function from
263  * different threads should be avoided, or (i) the preambles in calls
264  * to Extension::exec_shared() should be empty and (ii) tasks should
265  * not make clashing top level definitions in some other way,
266  * including by importing clashing definitions using 'use-modules' or
267  * 'load'. The need for Extension::exec_shared() to be called only in
268  * one thread in the example above was the reason why the TaskManager
269  * object in that example was set to have a maximum thread count of 1.
270  * In effect the TaskManager object was a dedicated serial dispatcher
271  * for all scheme tasks.
272  *
273  * The calling by Extension::exec_shared() of 'primitive-load' instead
274  * of 'load' may have some small effect on efficiency. It it best for
275  * the file passed to that function to hand off any complex code to
276  * modules prepared using guile's modules interface (which will be
277  * compiled into bytecode), and which are then loaded using
278  * 'use-modules' the first time Extension::exec_shared() is called, or
279  * by having the first call to Extension::exec_shared() (and only the
280  * first call) import any needed files into the top level using
281  * 'load'.
282  *
283  * Note that some guile global state may be shared between tasks
284  * whether Extension::exec() or Extension::exec_shared() is used. For
285  * example, if the guile 'add-to-load-path' procedure is called to add
286  * a local directory to the search path used by 'use-modules' or
287  * 'load', that will have effect for all other tasks.
288  *
289  * Other thread safety points
290  * --------------------------
291  *
292  * Leaving aside what has been said above, there are a few other
293  * issues to keep in mind if executing scheme code in more than one
294  * thread.
295  *
296  * First, the initialization of guile < 2.0.10 is not thread safe.
297  * One thread needs to have called Extension::exec() or
298  * Extension::exec_shared() once and returned before any other threads
299  * call the function. This can be achieved by the simple expedient of
300  * executing the statement:
301  *
302  * @code
303  * Extension::exec_shared("", "", &Extension::any_to_void);
304  * @endcode
305  *
306  * and waiting for it to return before any tasks are added to a
307  * TaskManager object running more than one thread. This issue is
308  * fixed in guile-2.0.10. However there is a further snag. Certain
309  * aspects of guile module loading are not thread safe. One way
310  * around this is to load all the modules that tasks may use in
311  * advance, by loading the modules in the preamble of the above
312  * statement (or to have that statement execute a file which loads the
313  * modules). If that is done, it should be fine afterwards to run
314  * Extension::exec() (or Extension::exec_shared() if clashing top
315  * level definitions are avoided as mentioned above) on a TaskManager
316  * object running any number of threads, or on a Thread::Future object
317  * or std::async() task. (However, note that if using
318  * Extension::exec() the modules would need to be reloaded in each
319  * task in order to make them visible to the task, but that would be
320  * done safely if they have previously been loaded in another task.)
321  *
322  * If a C++ program is to run guile tasks on a TaskManager object
323  * having a maximum thread count greater than one (or in more than one
324  * thread in some other way), one other point should be noted. When a
325  * scheme file is executed for the first time by a user by being
326  * passed as the second argument of Extension::exec() (or by having
327  * 'load' applied to it in some other way), it will be compiled into
328  * byte code, the byte code will then be cached on the file system for
329  * that and subsequent calls, and the byte code then executed. Bad
330  * things might happen if concurrent calls to Extension::exec(), or to
331  * the 'load' or 'use-modules' procedures, are made in respect of the
332  * same scheme file for the "first" time, if there might be a race as
333  * to which of them is the "first" call in respect of the file: that
334  * is, if it causes two or more threads to try to compile the same
335  * file into byte code concurrently. This is only an issue the first
336  * time a particular user executes a scheme file, and can be avoided
337  * (amongst other ways) by having the C++ program concerned
338  * pre-compile the relevant scheme file before Extension::exec() or
339  * Extension::exec_shared() is first called, by means of the 'guild
340  * compile [filename]' command. The following gives more information
341  * about compilation: <A
342  * HREF="http://www.gnu.org/software/guile/manual/html_node/Compilation.html#Compilation">
343  * Compiling Scheme Code</A>
344  *
345  * Licence
346  * -------
347  *
348  * The c++-gtk-utils library (and this c++-gtk-utils/extension.h
349  * header file) follows glib and GTK+ by being released under the LGPL
350  * version 2.1 or later. libguile is released under the LGPL version
351  * 3 or later. The c++-gtk-utils library object code does not link to
352  * libguile, nor does it incorporate anything in the
353  * c++-gtk-utils/extension.h header. Instead
354  * c++-gtk-utils/extension.h contains all its code as a separate
355  * unlinked header for any program which wants to include it (this is
356  * partly because some of it comprises template functions).
357  *
358  * There are two consequences. If you want to use Extension::exec()
359  * or Extension::exec_shared(), the program which calls it will need
360  * to link itself explicitly with libguile as well as c++-gtk-utils,
361  * and to do that will need to use pkg-config to obtain libguile's
362  * cflags and libs particulars (its pkg-config file is guile-2.0.pc,
363  * guile-2.2.pc or guile-3.0.pc). This library does NOT do that for
364  * you. Secondly, by linking with libguile you will be governed by
365  * the LGPL version 3 or later, instead of the LGPL version 2.1 or
366  * later, with respect to that linking. That's fine (there is nothing
367  * wrong with the LGPL version 3 and this library permits that) but
368  * you should be aware of it. The scheme code in guile's scheme level
369  * modules is also in the main released under the LGPL version 3 or
370  * later ("in the main" because readline.scm, comprised in the
371  * readline module, is released under the GPL version 3 or later).
372  *
373  * Configuration
374  * -------------
375  *
376  * By default, when the c++-gtk-utils library is configured,
377  * configuration will first look for guile-3.0 >= 3.0.0, then if it
378  * does not find that it will look for guile-2.2 >= 2.1.3, then if it
379  * does not find that it will look for guile-2.0 >= 2.0.2, and then if
380  * it finds none it will disable guile support; and the library header
381  * files will then be set up appropriately. guile-3.0, guile-2.2 or
382  * guile-2.0 can be specifically picked with the \--with-guile=3.0,
383  * \--with-guile=2.2 or \--with-guile=2.0 configuration options
384  * respectively. Guile support can be omitted with the
385  * \--with-guile=no option.
386 
387  * However, as mentioned under "Licence" above, any program using
388  * Extension::exec() or Extension::exec_shared() must link itself
389  * explicitly with libguile via either guile-2.0.pc (for guile-2.0),
390  * guile-2.2.pc (for guile-2.2) or guile-3.0.pc (for guile-3.0).
391  * Programs should use whichever of those is the one for which
392  * c++-gtk-utils was configured. If you get link-time messages from a
393  * program about being unable to link to scm_dynwind_block_asyncs(),
394  * then there has been a version mismatch. If you get link-time
395  * messages about being unable to link to Cgu::Extension::init_mutex()
396  * or Cgu::Extension::get_user_module_mutex() then c++-gtk-utils has
397  * not been configured to offer guile support.
398  *
399  * Custom translators
400  * ------------------
401  *
402  * Any function or callable object which translates from an opaque SCM
403  * value to a suitable C++ representation can be passed as the third
404  * argument of Extension::exec() or Extension::exec_shared(). C++
405  * type deduction on template resolution will take care of everything
406  * else. The translator can execute any functions offered by
407  * libguile, because when the translator is run the program is still
408  * in guile mode. The fulsome guile documentation sets out the
409  * libguile functions which are callable in C/C++ code.
410  *
411  * The first call in a custom translator should normally be to the
412  * Extension::rethrow_guile_exception() function. This function tests
413  * whether a guile exception arose in executing the scheme file, and
414  * throws a C++ exception if it did. The preformed translators in
415  * extension.h provide worked examples of how a custom translator
416  * might be written.
417  *
418  * If something done in a custom translator were to raise a guile
419  * exception, the library implementation would handle it and a C++
420  * exception would be generated in its place in Extension::exec() or
421  * Extension::exec_shared(). However, a custom translator should not
422  * allow a guile exception arising from calls to libguile made by it
423  * to exit a C++ scope in which the translator has constructed a local
424  * C++ object which is not trivially destructible: that would give
425  * rise to undefined behaviour, with the likely result that the C++
426  * object's destructor would not be called. One approach to this
427  * (adopted in the preformed translators) is to allocate on free store
428  * all local C++ objects to be constructed in the translator which are
429  * not trivially destructible, and to manage their lifetimes manually
430  * using local C++ try/catch blocks rather than RAII, with dynwind
431  * unwind handlers to release memory were there to be a guile
432  * exception (but note that no C++ exception should transit out of a
433  * scm_dynwind_begin()/scm_dynwind_end() pair). It is also a good
434  * idea to test for any condition which might cause a guile exception
435  * to be raised in the translator in the first place, and throw a C++
436  * exception beforehand. Then the only condition which might cause a
437  * guile exception to occur in the translator is an out-of-memory
438  * condition, which is highly improbable in a translator as the
439  * translator is run after the guile task has completed. Heap
440  * exhaustion in such a case probably spells doom for the program
441  * concerned anyway, if it has other work to do.
442  *
443  * Note also that code in a custom translator should not store guile
444  * SCM objects (which are pointers to guile scheme objects) in memory
445  * blocks allocated by malloc() or the new expression, or they will
446  * not be seen by the garbage collector used by libguile (which is the
447  * gc library) and therefore may be prematurely deallocated. To keep
448  * such items alive in custom translators, SCM variables should be
449  * kept as local variables or parameter names in functions (and so
450  * stored on the stack or in registers, where they will be seen by the
451  * garbage collector), or in memory allocated with scm_gc_malloc(),
452  * where they will also be seen by the garbage collector.
453  *
454  * Scheme
455  * ------
456  * If you want to learn more about scheme, these are useful sources:
457  * <P>
458  * <A HREF="http://www.gnu.org/software/guile/manual/html_node/Hello-Scheme_0021.html"> Chapter 3 of the Guile Manual</A>
459  * (the rest of the manual is also good reading).</P>
460  * <P>
461  * <A HREF="http://www.scheme.com/tspl4/">The Scheme Programming Language, 4th edition</A></P>
462  */
463 
464 #include <string>
465 #include <vector>
466 #include <exception>
467 #include <memory> // for std::unique_ptr
468 #include <type_traits> // for std::remove_reference, std::remove_const and std::result_of
469 #include <limits> // for std::numeric_limits
470 #include <functional> // for std::bind
471 #include <utility> // for std::move
472 #include <new> // for std::bad_alloc
473 
474 #include <stddef.h> // for size_t
475 #include <stdlib.h> // for free()
476 #include <string.h> // for strlen() and strncmp()
477 
478 #include <glib.h>
479 
481 #include <c++-gtk-utils/callback.h>
482 #include <c++-gtk-utils/thread.h>
483 #include <c++-gtk-utils/mutex.h>
485 
486 #include <libguile.h>
487 
488 
489 #ifndef DOXYGEN_PARSING
490 namespace Cgu {
491 
492 namespace Extension {
493 
494 struct FormatArgs {
495  SCM text;
496  SCM rest;
497 };
498 
499 enum VectorDeleteType {Long, Double, String};
500 
501 struct VectorDeleteArgs {
502  VectorDeleteType type;
503  void* vec;
504 };
505 
506 // defined in extension_helper.cpp
507 extern Cgu::Thread::Mutex* get_user_module_mutex();
508 extern bool init_mutex();
509 
510 } // namespace Extension
511 
512 } // namespace Cgu
513 
514 namespace {
515 extern "C" {
516  inline SCM cgu_format_try_handler(void* data) {
517  using Cgu::Extension::FormatArgs;
518  FormatArgs* format_args = static_cast<FormatArgs*>(data);
519  return scm_simple_format(SCM_BOOL_F, format_args->text, format_args->rest);
520  }
521  inline SCM cgu_format_catch_handler(void*, SCM, SCM) {
522  return SCM_BOOL_F;
523  }
524  inline void* cgu_guile_wrapper(void* data) {
525  try {
526  static_cast<Cgu::Callback::Callback*>(data)->dispatch();
527  }
528  // an elipsis catch block is fine as thread cancellation is
529  // blocked. We can only enter this block if assigning to one of
530  // the exception strings in the callback has thrown
531  // std::bad_alloc. For that case we return a non-NULL pointer to
532  // indicate error (the 'data' argument is convenient and
533  // guaranteed to be standard-conforming for this).
534  catch (...) {
535  return data;
536  }
537  return 0;
538  }
539  inline void cgu_delete_vector(void* data) {
540  using Cgu::Extension::VectorDeleteArgs;
541  VectorDeleteArgs* args = static_cast<VectorDeleteArgs*>(data);
542  switch (args->type) {
543  case Cgu::Extension::Long:
544  delete static_cast<std::vector<long>*>(args->vec);
545  break;
546  case Cgu::Extension::Double:
547  delete static_cast<std::vector<double>*>(args->vec);
548  break;
549  case Cgu::Extension::String:
550  delete static_cast<std::vector<std::string>*>(args->vec);
551  break;
552  default:
553  g_critical("Incorrect argument passed to cgu_delete_vector");
554  }
555  delete args;
556  }
557  inline void cgu_unlock_module_mutex(void*) {
558  // this cannot give rise to an allocation or mutex error -
559  // we must have been called init_mutex() first
560  Cgu::Extension::get_user_module_mutex()->unlock();
561  }
562 } // extern "C"
563 } // unnamed namespace
564 #endif // DOXYGEN_PARSING
565 
566 namespace Cgu {
567 
568 namespace Extension {
569 
570 class GuileException: public std::exception {
571  Cgu::GcharSharedHandle message;
572  Cgu::GcharSharedHandle guile_message;
573 public:
574  virtual const char* what() const throw() {return (const char*)message.get();}
575  const char* guile_text() const throw() {return (const char*)guile_message.get();}
576  GuileException(const char* msg):
577  message(g_strdup_printf("Cgu::Extension::GuileException: %s", msg)),
578  guile_message(g_strdup(msg)) {}
579  ~GuileException() throw() {}
580 };
581 
582 class ReturnValueError: public std::exception {
583  Cgu::GcharSharedHandle message;
584  Cgu::GcharSharedHandle err_message;
585 public:
586  virtual const char* what() const throw() {return (const char*)message.get();}
587  const char* err_text() const throw() {return (const char*)err_message.get();}
588  ReturnValueError(const char* msg):
589  message(g_strdup_printf("Cgu::Extension::ReturnValueError: %s", msg)),
590  err_message(g_strdup(msg)) {}
591  ~ReturnValueError() throw() {}
592 };
593 
594 class WrapperError: public std::exception {
595  Cgu::GcharSharedHandle message;
596 public:
597  virtual const char* what() const throw() {return (const char*)message.get();}
598  WrapperError(const char* msg):
599  message(g_strdup_printf("Cgu::Extension::WrapperError: %s", msg)) {}
600  ~WrapperError() throw() {}
601 };
602 
603 #ifndef DOXYGEN_PARSING
604 
605 // this function has been renamed guile_wrapper_cb2 in version 2.0.28
606 // in order to prevent ODR issues and ensure exec_impl() in 2.0.28
607 // calls the correct version of this function
608 template <class Ret, class TransType>
609 void guile_wrapper_cb2(TransType* translator,
610  std::string* loader,
611  Ret* retval,
612  bool* result,
613  std::string* guile_except,
614  std::string* guile_ret_val_err,
615  std::string* gen_err,
616  bool shared) {
617  SCM scm;
618  if (shared) {
619  scm = scm_eval_string_in_module(scm_from_utf8_string(loader->c_str()),
620  scm_c_resolve_module("guile-user"));
621  }
622  else {
623  if (!init_mutex())
624  throw std::bad_alloc(); // this will be caught in cgu_guile_wrapper()
625 
626  scm_dynwind_begin(scm_t_dynwind_flags(0));
627  scm_dynwind_unwind_handler(&cgu_unlock_module_mutex, 0, SCM_F_WIND_EXPLICITLY);
628  get_user_module_mutex()->lock(); // won't throw
629  // neither make-fresh-user-module nor set-module-declarative?! are
630  // part of the publicly documented guile API, but are made
631  // available by ice-9/boot-9.scm. set-module-declarative?! is the
632  // modifier of the declarative? field of the module record type in
633  // guile-3.0. There is no workable way of avoiding their use, but
634  // they should be safe until at least the next API-breaking
635  // version of guile, and probably long after that.
636  SCM new_mod = scm_call_0(scm_c_public_ref("guile", "make-fresh-user-module"));
637 #if SCM_MAJOR_VERSION >= 3
638  scm_call_2(scm_c_public_ref("guile", "set-module-declarative?!"),
639  new_mod, SCM_BOOL_F);
640 #endif
641  scm_dynwind_end();
642 
643  scm = scm_eval_string_in_module(scm_from_utf8_string(loader->c_str()),
644  new_mod);
645  }
646 
647  // have a dynwind context and async block while translator is
648  // executing. This is to cater for the pathological case of the
649  // scheme script having set up a signal handler which might throw a
650  // guile exception, or having chained a series of system asyncs
651  // which are still queued for action, which might otherwise cause
652  // the translator to trigger a guile exception while a non-trivially
653  // destructible object is in the local scope of translator. (Highly
654  // unlikely, but easy to deal with.) This is entirely safe as no
655  // C++ exception arising from the translator can transit across the
656  // dynamic context in this function - see below. So we have (i) no
657  // C++ exception can transit across a guile dynamic context, and
658  // (ii) no guile exception can escape out of a local C++ scope by
659  // virtue of an async executing (it might still escape with a
660  // non-trivially destructible object in existence if a custom
661  // translator has not been written correctly, but there is nothing
662  // we can do about that). Note that some guile installations do not
663  // link scm_dynwind_block_asyncs() correctly - this is tested at
664  // configuration time.
665 #ifndef CGU_GUILE_HAS_BROKEN_LINKING
666  scm_dynwind_begin(scm_t_dynwind_flags(0));
667  scm_dynwind_block_asyncs();
668 #endif
669  // we cannot use std::exception_ptr here to store a C++ exception
670  // object, because std::exception_ptr is not trivially destructible
671  // and a guile exception in 'translator' could jump out of this
672  // scope to its continuation in scm_with_guile()
673  bool badalloc = false;
674  try {
675  *retval = (*translator)(scm);
676  *result = true; // this will detect any guile exception in the
677  // preamble or 'translator' which causes
678  // scm_with_guile() to return prematurely. We
679  // have could have done it instead by reversing
680  // the return values of cgu_guile_wrapper
681  // (non-NULL for success and NULL for failure)
682  // because scm_with_guile() returns NULL if it
683  // exits on an uncaught guile exception, but this
684  // approach enables us to discriminate between a
685  // C++ memory exception in the wrapper and a guile
686  // exception in the preamble or 'translator', at a
687  // minimal cost of one assignment to a bool.
688  }
689  catch (Cgu::Extension::GuileException& e) {
690  try {
691  *guile_except = e.guile_text();
692  }
693  catch (...) {
694  badalloc = true;
695  }
696  }
698  try {
699  *guile_ret_val_err = e.err_text();
700  }
701  catch (...) {
702  badalloc = true;
703  }
704  }
705  catch (std::exception& e) {
706  try {
707  *gen_err = e.what();
708  }
709  catch (...) {
710  badalloc = true;
711  }
712  }
713  catch (...) {
714  try {
715  *gen_err = "C++ exception thrown in guile_wrapper_cb()";
716  }
717  catch (...) {
718  badalloc = true;
719  }
720  }
721 #ifndef CGU_GUILE_HAS_BROKEN_LINKING
722  scm_dynwind_end();
723 #endif
724  if (badalloc) throw std::bad_alloc(); // this will be caught in cgu_guile_wrapper()
725 }
726 
727 template <class Ret, class Translator>
728 Ret exec_impl(const std::string& preamble,
729  const std::string& file,
730  Translator translator,
731  bool shared) {
732 
734 
735  std::string loader;
736  loader += preamble;
737  if (!file.empty()) {
738  if (shared)
739  loader += "((lambda ()";
740  loader += "(catch "
741  "#t"
742  "(lambda ()"
743  "(";
744  if (shared)
745  loader += "primitive-load \"";
746  else
747  loader += "load \"";
748  loader += file;
749  loader += "\"))"
750  "(lambda (key . details)"
751  "(cons \"***cgu-guile-exception***\" (cons key details))))";
752  if (shared)
753  loader += "))";
754  }
755 
756  Ret retval;
757  bool result = false;
758  std::string guile_except;
759  std::string guile_ret_val_err;
760  std::string gen_err;
761 
762  // we construct a Callback::Callback object here to perform type
763  // erasure. Otherwise we would have to pass scm_with_guile() a
764  // function pointer to a function templated on Translator and Ret,
765  // which must have C++ language linkage (§14/4 of C++ standard).
766  // Technically this would give undefined behaviour as
767  // scm_with_guile() expects a function pointer with C language
768  // linkage, although gcc and clang would accept it. The whole of
769  // this callback will be executed in guile mode via
770  // cgu_guile_wrapper(), so it can safely call libguile functions
771  // (provided that a translator does not allow any guile exceptions
772  // to escape a C++ scope with local objects which are not trivially
773  // destructible). It is also safe to pass 'translator', 'retval',
774  // 'loader', 'result' and the exception strings to it by reference,
775  // because scm_with_guile() will block until it has completed
776  // executing. cgu_guile_wrapper() will trap any std::bad_alloc
777  // exception thrown by the string assignments in the catch blocks in
778  // guile_wrapper_cb. guile_wrapper_cb is safe against a jump to an
779  // exit from scm_with_guile() arising from a native guile exception
780  // in translator, because its body has no objects in local scope
781  // requiring destruction.
782  std::unique_ptr<Cgu::Callback::Callback> cb(
783  Cgu::Callback::lambda<>(std::bind(&guile_wrapper_cb2<Ret, Translator>,
784  &translator,
785  &loader,
786  &retval,
787  &result,
788  &guile_except,
789  &guile_ret_val_err,
790  &gen_err,
791  shared))
792  );
793  // cgu_guile_wrapper(), and so scm_with_guile() will return a
794  // non-NULL value if assigning to one of the exception description
795  // strings above threw std::bad_alloc
796  if (scm_with_guile(&cgu_guile_wrapper, cb.get()))
797  throw WrapperError("cgu_guile_wrapper() has trapped std::bad_alloc");
798  if (!guile_except.empty())
799  throw GuileException(guile_except.c_str());
800  if (!guile_ret_val_err.empty())
801  throw ReturnValueError(guile_ret_val_err.c_str());
802  if (!gen_err.empty())
803  throw WrapperError(gen_err.c_str());
804  if (!result)
805  throw WrapperError("the preamble or translator threw a native guile exception");
806  return retval;
807 }
808 
809 #endif // DOXYGEN_PARSING
810 
811 /**
812  * This function is called by Extension::rethrow_guile_exception()
813  * where the scheme code executed by Extension::exec() or
814  * Extension::exec_shared() has exited with a guile exception. It
815  * converts the raw guile exception information represented by the
816  * 'key' and 'args' arguments of a guile catch handler to a more
817  * readable form. It is made available as part of the public
818  * interface so that any custom translators can also use it if they
819  * choose to provide their own catch expressions. This function does
820  * not throw any C++ exceptions. No native guile exception will arise
821  * in this function and so cause guile to jump out of it assuming no
822  * guile out-of-memory condition occurs (and given that this function
823  * is called after a guile extension task has completed, such a
824  * condition is very improbable). It is thread safe, but see the
825  * comments above about the thread safety of Extension::exec() and
826  * Extension::exec_shared().
827  *
828  * @param key An opaque guile SCM object representing a symbol
829  * comprising the 'key' argument of the exception handler of a guile
830  * catch expression.
831  * @param args An opaque guile SCM object representing a list
832  * comprising the 'args' argument of the exception handler of a guile
833  * catch expression.
834  * @return An opaque guile SCM object representing a guile string.
835  *
836  * Since 2.0.22
837  */
838 inline SCM exception_to_string(SCM key, SCM args) {
839  // The args of most exceptions thrown by guile are in the following format:
840  // (car args) - a string comprising the name of the procedure generating the exception
841  // (cadr args) - a string containing text, possibly with format directives (escape sequences)
842  // (caddr args) - a list containing items matching the format directives, or #f if none
843  // (cadddr args) - (not used here) a list of additional objects (eg the errno for some errors),
844  // or #f if none
845  SCM ret = SCM_BOOL_F;
846  int length = scm_to_int(scm_length(args));
847  if (length) {
848  SCM first = scm_car(args);
849  if (scm_is_true(scm_string_p(first))) {
850  // if a single user string, output it
851  if (length == 1) {
852  ret = scm_string_append(scm_list_4(scm_from_utf8_string("Exception "),
853  scm_symbol_to_string(key),
854  scm_from_utf8_string(": "),
855  first));
856  }
857  else { // length > 1
858  SCM second = scm_cadr(args);
859  if (scm_is_true(scm_string_p(second))) {
860  // we should have a standard guile exception string, as above
861  SCM text = scm_string_append(scm_list_n(scm_from_utf8_string("Exception "),
862  scm_symbol_to_string(key),
863  scm_from_utf8_string(" in procedure "),
864  first,
865  scm_from_utf8_string(": "),
866  second,
867  SCM_UNDEFINED));
868  if (length == 2)
869  ret = text;
870  else { // length > 2
871  SCM third = scm_caddr(args);
872  if (scm_is_false(third))
873  ret = text;
874  else if (scm_is_true(scm_list_p(third))) {
875  FormatArgs format_args = {text, third};
876  ret = scm_internal_catch(SCM_BOOL_T,
877  &cgu_format_try_handler,
878  &format_args,
879  &cgu_format_catch_handler,
880  0);
881  }
882  }
883  }
884  }
885  }
886  }
887  // fall back to generic formatting if first or second elements of
888  // args is not a string or simple-format failed above
889  if (scm_is_false(ret)) {
890  // there is no need for a catch block: we know simple-format
891  // cannot raise an exception here
892  ret = scm_simple_format(SCM_BOOL_F,
893  scm_from_utf8_string("Exception ~S: ~S"),
894  scm_list_2(key, args));
895  }
896  return ret;
897 }
898 
899 /**
900  * This function tests whether a guile exception arose in executing a
901  * scheme extension file, and throws Cgu::Extension::GuileException if
902  * it did. It is intended for use by custom translators, as the first
903  * thing the translator does. It is thread safe, but see the comments
904  * above about the thread safety of Extension::exec() and
905  * Extension::exec_shared().
906  *
907  * @param scm An opaque guile SCM object representing the value to
908  * which the extension file passed to Extension::exec() or
909  * Extension::exec_shared() evaluated.
910  * @exception std::bad_alloc This function might throw std::bad_alloc
911  * if memory is exhausted and the system throws in that case.
912  * @exception Cgu::Extension::GuileException This exception will be
913  * thrown if the scheme code executed in the extension file passed to
914  * Extension::exec() or Extension::exec_shared() threw a guile
915  * exception. Cgu::Extension::GuileException::what() will give
916  * particulars of the guile exception thrown, in UTF-8 encoding.
917  * @note No native guile exception will arise in this function and so
918  * cause guile to jump out of it if no guile out-of-memory condition
919  * occurs (given that this function is called after a guile extension
920  * task has completed, such a condition is very improbable).
921  *
922  * Since 2.0.22
923  */
924 inline void rethrow_guile_exception(SCM scm) {
925  // guile exceptions are always presented to this function as a
926  // scheme list
927  if (scm_is_false(scm_list_p(scm))
928  || scm_is_true(scm_null_p(scm))) return;
929  SCM first = scm_car(scm);
930  if (scm_is_true(scm_string_p(first))) {
931  size_t len;
932  const char* text = 0;
933  // nothing in this function should throw a guile exception unless
934  // there is a guile out-of-memory exception (which is extremely
935  // improbable). However, let's cover ourselves in case
936  scm_dynwind_begin(scm_t_dynwind_flags(0));
937  char* car = scm_to_utf8_stringn(first, &len);
938  // there may be a weakness in guile's implementation here: if
939  // calling scm_dynwind_unwind_handler() were to give rise to an
940  // out-of-memory exception before the handler is set up by it,
941  // then we could leak memory allocated from the preceding call to
942  // scm_to_utf8_stringn(). Whether that could happen is not
943  // documented, but because (a) it is so improbable, and (b) once
944  // we are in out-of-memory land we are already in severe trouble
945  // and glib is likely to terminate the program at some point
946  // anyway, it is not worth troubling ourselves over.
947  scm_dynwind_unwind_handler(&free, car, scm_t_wind_flags(0));
948  if (len == strlen("***cgu-guile-exception***")
949  && !strncmp(car, "***cgu-guile-exception***", len)) {
950  SCM str = exception_to_string(scm_cadr(scm), scm_cddr(scm));
951  // we don't need a dynwind handler for 'text' because nothing
952  // after the call to scm_to_utf8_stringn() can cause a guile
953  // exception to be raised
954  text = scm_to_utf8_stringn(str, &len);
955  }
956  // all done - no more guile exceptions are possible in this
957  // function after this so end the dynamic context, take control of
958  // the memory by RAII and if necessary throw a C++ exception
959  scm_dynwind_end();
960  std::unique_ptr<char, Cgu::CFree> up_car(car);
961  std::unique_ptr<const char, Cgu::CFree> up_text(text);
962  // if 'text' is not NULL, 'len' contains its length in bytes
963  if (text) throw GuileException(std::string(text, len).c_str());
964  }
965 }
966 
967 /**
968  * A translator function which can be passed to the third argument of
969  * Extension::exec() or Extension::exec_shared(). It converts from a
970  * homogeneous scheme list of integers to a C++ representation of
971  * std::vector<long>. It is thread safe, but see the comments above
972  * about the thread safety of Extension::exec() and
973  * Extension::exec_shared().
974  *
975  * @param scm An opaque guile SCM object representing the value to
976  * which the extension file passed to Extension::exec() or
977  * Extension::exec_shared() evaluated, where that value is a
978  * homogeneous list of integers.
979  * @return The std::vector<long> representation.
980  * @exception std::bad_alloc This function might throw std::bad_alloc
981  * if memory is exhausted and the system throws in that case, or if
982  * the length of the input list exceeds std::vector::max_size().
983  * @exception Cgu::Extension::GuileException This exception will be
984  * thrown if the scheme code in the extension file passed to
985  * Extension::exec() or Extension::exec_shared() caused a guile
986  * exception to be thrown. Cgu::Extension::GuileException::what()
987  * will give particulars of the guile exception thrown, in UTF-8
988  * encoding.
989  * @exception Cgu::Extension::ReturnValueError This exception will be
990  * thrown if the scheme code in the extension file passed to
991  * Extension::exec() or Extension::exec_shared() does not evaluate to
992  * the type expected by the translator, or it is out of range for a
993  * long.
994  * @note No native guile exception will arise in this function and so
995  * cause guile to jump out of it unless a guile out-of-memory
996  * condition occurs (given that this function is called after a guile
997  * extension task has completed, such a condition is very improbable)
998  * or the length of the input list exceeds SIZE_MAX (the maximum value
999  * of std::size_t). If such an exception were to arise, the
1000  * implementation would handle it and a C++ exception would be
1001  * generated in its place in Extension::exec() or
1002  * Extension::exec_shared().
1003  *
1004  * Since 2.0.22
1005  */
1006 inline std::vector<long> list_to_vector_long(SCM scm) {
1008  if (scm_is_false(scm_list_p(scm)))
1009  throw ReturnValueError("scheme code did not evaluate to a list\n");
1010 
1011  // nothing in this function should throw a guile exception unless
1012  // there is a guile out-of-memory exception (which is extremely
1013  // improbable). However, let's cover ourselves in case.
1014  scm_dynwind_begin(scm_t_dynwind_flags(0));
1015  // we cannot have a std::vector object in a scope where a guile
1016  // exception might be raised because it has a non-trivial
1017  // destructor, nor can we use RAII. Instead allocate on free store
1018  // and manage the memory by hand until we can no longer jump on a
1019  // guile exception. In addition we cannot store a C++ exception
1020  // using std::exception_ptr because std::exception_ptr is not
1021  // trivially destructible.
1022  bool badalloc = false;
1023  const char* rv_error = 0;
1024  std::vector<long>* res = 0;
1025  VectorDeleteArgs* args = 0;
1026  try {
1027  // it doesn't matter if the second allocation fails, as we clean
1028  // up at the end if there is no guile exception, and if both
1029  // allocations succeed and there were to be a subsequent guile
1030  // exception, cgu_delete_vector cleans up
1031  res = new std::vector<long>;
1032  // allocate 'args' on free store, because the continuation in
1033  // which it executes will be up the stack
1034  args = new VectorDeleteArgs{Long, res};
1035  }
1036  catch (...) {
1037  badalloc = true;
1038  }
1039  if (!badalloc) {
1040  // there may be a weakness in guile's implementation here: if
1041  // calling scm_dynwind_unwind_handler() were to give rise to a
1042  // guile out-of-memory exception before the handler is set up by
1043  // it, then we could leak memory allocated from the preceding new
1044  // expressions. Whether that could happen is not documented by
1045  // guile, but because (a) it is so improbable, and (b) once we are
1046  // in out-of-memory land we are already in severe trouble and glib
1047  // is likely to terminate the program at some point anyway, it is
1048  // not worth troubling ourselves over.
1049  scm_dynwind_unwind_handler(&cgu_delete_vector, args, scm_t_wind_flags(0));
1050  // convert the list to a guile vector so we can access its items
1051  // efficiently in a for loop. This conversion is reasonably
1052  // efficient, in the sense that an ordinary guile vector is an
1053  // array of pointers, pointing to the same scheme objects that the
1054  // list refers to
1055  SCM guile_vec = scm_vector(scm);
1056 
1057  // std::vector::size_type is the same as size_t with the standard
1058  // allocators (but if we were to get a silent narrowing conversion
1059  // on calling std::vector::reserve() below, that doesn't matter -
1060  // instead if 'length' is less than SIZE_MAX but greater than the
1061  // maximum value of std::vector::size_type, at some point a call
1062  // to std::vector::push_back() below would throw and be caught,
1063  // and this function would end up rethrowing it as std::bad_alloc.
1064  // If in a particular implementation SIZE_MAX exceeds
1065  // std::vector::max_size(), a std::length_error exception would be
1066  // thrown by reserve() where max_size() is exceeded. On all
1067  // common implementations, max_size() is equal to SIZE_MAX, but
1068  // were such an exception to arise it would be swallowed (see
1069  // below) and then rethrown by this function as std::bad_alloc.
1070  // If 'length' is greater than SIZE_MAX, a guile out-of-range
1071  // exception would be thrown by scm_to_size_t() which would be
1072  // rethrown by Cgu:Extension::exec() or
1073  // Cgu::Exception::exec_shared as a Cgu::Extension::WrapperError
1074  // C++ exception. This is nice to know but in practice such large
1075  // lists would be unusably slow and a memory exception would be
1076  // reached long before std::vector::max_size() or SIZE_MAX are
1077  // exceeded.
1078  size_t length = scm_to_size_t(scm_vector_length(guile_vec));
1079  try {
1080  res->reserve(length);
1081  }
1082  catch (...) {
1083  badalloc = true;
1084  }
1085  for (size_t count = 0;
1086  count < length && !rv_error && !badalloc;
1087  ++count) {
1088  SCM item = scm_vector_ref(guile_vec, scm_from_size_t(count));
1089  if (scm_is_false(scm_integer_p(item)))
1090  rv_error = "scheme code did not evaluate to a homogeneous list of integer\n";
1091  else {
1092  SCM min = scm_from_long(std::numeric_limits<long>::min());
1093  SCM max = scm_from_long(std::numeric_limits<long>::max());
1094  if (scm_is_false(scm_leq_p(item, max)) || scm_is_false(scm_geq_p(item, min)))
1095  rv_error = "scheme code evaluated out of range for long\n";
1096  else {
1097  try {
1098  res->push_back(scm_to_long(item));
1099  }
1100  catch (...) {
1101  badalloc = true;
1102  }
1103  }
1104  }
1105  }
1106  }
1107  // all done - no more guile exceptions are possible in this function
1108  // after this so end the dynamic context, take control of the memory
1109  // by RAII and if necessary throw a C++ exception
1110  scm_dynwind_end();
1111  std::unique_ptr<std::vector<long>> up_res(res);
1112  std::unique_ptr<VectorDeleteArgs> up_args(args);
1113  if (badalloc) throw std::bad_alloc();
1114  if (rv_error) throw ReturnValueError(rv_error);
1115  // neither gcc-4.9 nor clang-3.4 will optimize with RVO or move
1116  // semantics here, so force it by hand
1117  return std::move(*res);
1118 }
1119 
1120 /**
1121  * A translator function which can be passed to the third argument of
1122  * Extension::exec() or Extension::exec_shared(). It converts from a
1123  * homogeneous scheme list of real numbers to a C++ representation of
1124  * std::vector<double>. It is thread safe, but see the comments above
1125  * about the thread safety of Extension::exec() and
1126  * Extension::exec_shared().
1127  *
1128  * @param scm An opaque guile SCM object representing the value to
1129  * which the extension file passed to Extension::exec() or
1130  * Extension::exec_shared() evaluated, where that value is a
1131  * homogeneous list of real numbers.
1132  * @return The std::vector<double> representation.
1133  * @exception std::bad_alloc This function might throw std::bad_alloc
1134  * if memory is exhausted and the system throws in that case, or if
1135  * the length of the input list exceeds std::vector::max_size().
1136  * @exception Cgu::Extension::GuileException This exception will be
1137  * thrown if the scheme code in the extension file passed to
1138  * Extension::exec() or Extension::exec_shared() caused a guile
1139  * exception to be thrown. Cgu::Extension::GuileException::what()
1140  * will give particulars of the guile exception thrown, in UTF-8
1141  * encoding.
1142  * @exception Cgu::Extension::ReturnValueError This exception will be
1143  * thrown if the scheme code in the extension file passed to
1144  * Extension::exec() or Extension::exec_shared() does not evaluate to
1145  * the type expected by the translator, or it is out of range for a
1146  * double.
1147  * @note 1. Prior to version 2.0.25, this translator had a bug which
1148  * caused an out-of-range Cgu::Extension::ReturnValueError to be
1149  * thrown if any of the numbers in the list to which the scheme code
1150  * in the extension file evaluated was 0.0 or a negative number. This
1151  * was fixed in version 2.0.25.
1152  * @note 2. No native guile exception will arise in this function and
1153  * so cause guile to jump out of it unless a guile out-of-memory
1154  * condition occurs (given that this function is called after a guile
1155  * extension task has completed, such a condition is very improbable)
1156  * or the length of the input list exceeds SIZE_MAX (the maximum value
1157  * of std::size_t). If such an exception were to arise, the
1158  * implementation would handle it and a C++ exception would be
1159  * generated in its place in Extension::exec() or
1160  * Extension::exec_shared().
1161  *
1162  * Since 2.0.22
1163  */
1164 inline std::vector<double> list_to_vector_double(SCM scm) {
1166  if (scm_is_false(scm_list_p(scm)))
1167  throw ReturnValueError("scheme code did not evaluate to a list\n");
1168 
1169  // nothing in this function should throw a guile exception unless
1170  // there is a guile out-of-memory exception (which is extremely
1171  // improbable). However, let's cover ourselves in case.
1172  scm_dynwind_begin(scm_t_dynwind_flags(0));
1173  // we cannot have a std::vector object in a scope where a guile
1174  // exception might be raised because it has a non-trivial
1175  // destructor, nor can we use RAII. Instead allocate on free store
1176  // and manage the memory by hand until we can no longer jump on a
1177  // guile exception. In addition we cannot store a C++ exception
1178  // using std::exception_ptr because std::exception_ptr is not
1179  // trivially destructible.
1180  bool badalloc = false;
1181  const char* rv_error = 0;
1182  std::vector<double>* res = 0;
1183  VectorDeleteArgs* args = 0;
1184  try {
1185  // it doesn't matter if the second allocation fails, as we clean
1186  // up at the end if there is no guile exception, and if both
1187  // allocations succeed and there were to be a subsequent guile
1188  // exception, cgu_delete_vector cleans up
1189  res = new std::vector<double>;
1190  // allocate 'args' on free store, because the continuation in
1191  // which it executes will be up the stack
1192  args = new VectorDeleteArgs{Double, res};
1193  }
1194  catch (...) {
1195  badalloc = true;
1196  }
1197  if (!badalloc) {
1198  // there may be a weakness in guile's implementation here: if
1199  // calling scm_dynwind_unwind_handler() were to give rise to a
1200  // guile out-of-memory exception before the handler is set up by
1201  // it, then we could leak memory allocated from the preceding
1202  // new expressions. Whether that could happen is not documented
1203  // by guile, but because (a) it is so improbable, and (b) once
1204  // we are in out-of-memory land we are already in severe trouble
1205  // and glib is likely to terminate the program at some point
1206  // anyway, it is not worth troubling ourselves over.
1207  scm_dynwind_unwind_handler(&cgu_delete_vector, args, scm_t_wind_flags(0));
1208  // convert the list to a guile vector so we can access its items
1209  // efficiently in a for loop. This conversion is reasonably
1210  // efficient, in the sense that an ordinary guile vector is an
1211  // array of pointers, pointing to the same scheme objects that the
1212  // list refers to
1213  SCM guile_vec = scm_vector(scm);
1214 
1215  // std::vector::size_type is the same as size_t with the standard
1216  // allocators (but if we were to get a silent narrowing conversion
1217  // on calling std::vector::reserve() below, that doesn't matter -
1218  // instead if 'length' is less than SIZE_MAX but greater than the
1219  // maximum value of std::vector::size_type, at some point a call
1220  // to std::vector::push_back() below would throw and be caught,
1221  // and this function would end up rethrowing it as std::bad_alloc.
1222  // If in a particular implementation SIZE_MAX exceeds
1223  // std::vector::max_size(), a std::length_error exception would be
1224  // thrown by reserve() where max_size() is exceeded. On all
1225  // common implementations, max_size() is equal to SIZE_MAX, but
1226  // were such an exception to arise it would be swallowed (see
1227  // below) and then rethrown by this function as std::bad_alloc.
1228  // If 'length' is greater than SIZE_MAX, a guile out-of-range
1229  // exception would be thrown by scm_to_size_t() which would be
1230  // rethrown by Cgu:Extension::exec() or
1231  // Cgu::Exception::exec_shared as a Cgu::Extension::WrapperError
1232  // C++ exception. This is nice to know but in practice such large
1233  // lists would be unusably slow and a memory exception would be
1234  // reached long before std::vector::max_size() or SIZE_MAX are
1235  // exceeded.
1236  size_t length = scm_to_size_t(scm_vector_length(guile_vec));
1237  try {
1238  res->reserve(length);
1239  }
1240  catch (...) {
1241  badalloc = true;
1242  }
1243  for (size_t count = 0;
1244  count < length && !rv_error && !badalloc;
1245  ++count) {
1246  SCM item = scm_vector_ref(guile_vec, scm_from_size_t(count));
1247  if (scm_is_false(scm_real_p(item)))
1248  rv_error = "scheme code did not evaluate to a homogeneous list of real numbers\n";
1249  else {
1250  SCM min = scm_from_double(-std::numeric_limits<double>::max());
1251  SCM max = scm_from_double(std::numeric_limits<double>::max());
1252  if (scm_is_false(scm_leq_p(item, max)) || scm_is_false(scm_geq_p(item, min)))
1253  rv_error = "scheme code evaluated out of range for double\n";
1254  else {
1255  try {
1256  res->push_back(scm_to_double(item));
1257  }
1258  catch (...) {
1259  badalloc = true;
1260  }
1261  }
1262  }
1263  }
1264  }
1265  // all done - no more guile exceptions are possible in this function
1266  // after this so end the dynamic context, take control of the memory
1267  // by RAII and if necessary throw a C++ exception
1268  scm_dynwind_end();
1269  std::unique_ptr<std::vector<double>> up_res(res);
1270  std::unique_ptr<VectorDeleteArgs> up_args(args);
1271  if (badalloc) throw std::bad_alloc();
1272  if (rv_error) throw ReturnValueError(rv_error);
1273  // neither gcc-4.9 nor clang-3.4 will optimize with RVO or move
1274  // semantics here, so force it by hand
1275  return std::move(*res);
1276 }
1277 
1278 /**
1279  * A translator function which can be passed to the third argument of
1280  * Extension::exec() or Extension::exec_shared(). It converts from a
1281  * homogeneous scheme list of strings to a C++ representation of
1282  * std::vector<std::string>. It is thread safe, but see the comments
1283  * above about the thread safety of Extension::exec() and
1284  * Extension::exec_shared().
1285  *
1286  * The returned strings will be in UTF-8 encoding.
1287  *
1288  * Note that the first string in the returned list must not be
1289  * "***cgu-guile-exception***": that string is reserved to the
1290  * implementation.
1291  *
1292  * @param scm An opaque guile SCM object representing the value to
1293  * which the extension file passed to Extension::exec() or
1294  * Extension::exec_shared() evaluated, where that value is a
1295  * homogeneous list of strings.
1296  * @return The std::vector<std::string> representation.
1297  * @exception std::bad_alloc This function might throw std::bad_alloc
1298  * if memory is exhausted and the system throws in that case, or if
1299  * the length of the input list exceeds std::vector::max_size().
1300  * @exception Cgu::Extension::GuileException This exception will be
1301  * thrown if the scheme code in the extension file passed to
1302  * Extension::exec() or Extension::exec_shared() caused a guile
1303  * exception to be thrown. Cgu::Extension::GuileException::what()
1304  * will give particulars of the guile exception thrown, in UTF-8
1305  * encoding.
1306  * @exception Cgu::Extension::ReturnValueError This exception will be
1307  * thrown if the scheme code in the extension file passed to
1308  * Extension::exec() or Extension::exec_shared() does not evaluate to
1309  * the type expected by the translator.
1310  * @note No native guile exception will arise in this function and so
1311  * cause guile to jump out of it unless a guile out-of-memory
1312  * condition occurs (given that this function is called after a guile
1313  * extension task has completed, such a condition is very improbable)
1314  * or the length of the input list exceeds SIZE_MAX (the maximum value
1315  * of std::size_t). If such an exception were to arise, the
1316  * implementation would handle it and a C++ exception would be
1317  * generated in its place in Extension::exec() or
1318  * Extension::exec_shared().
1319  *
1320  * Since 2.0.22
1321  */
1322 inline std::vector<std::string> list_to_vector_string(SCM scm) {
1324  if (scm_is_false(scm_list_p(scm)))
1325  throw ReturnValueError("scheme code did not evaluate to a list\n");
1326 
1327  // nothing in this function should throw a guile exception unless
1328  // there is a guile out-of-memory exception (which is extremely
1329  // improbable). However, let's cover ourselves in case.
1330  scm_dynwind_begin(scm_t_dynwind_flags(0));
1331  // we cannot have a std::vector object in a scope where a guile
1332  // exception might be raised because it has a non-trivial
1333  // destructor, nor can we use RAII. Instead allocate on free store
1334  // and manage the memory by hand until we can no longer jump on a
1335  // guile exception. In addition we cannot store a C++ exception
1336  // using std::exception_ptr because std::exception_ptr is not
1337  // trivially destructible.
1338  bool badalloc = false;
1339  const char* rv_error = 0;
1340  std::vector<std::string>* res = 0;
1341  VectorDeleteArgs* args = 0;
1342  try {
1343  // it doesn't matter if the second allocation fails, as we clean
1344  // up at the end if there is no guile exception, and if both
1345  // allocations succeed and there were to be a subsequent guile
1346  // exception, cgu_delete_vector cleans up
1347  res = new std::vector<std::string>;
1348  // allocate 'args' on free store, because the continuation in
1349  // which it executes will be up the stack
1350  args = new VectorDeleteArgs{String, res};
1351  }
1352  catch (...) {
1353  badalloc = true;
1354  }
1355  if (!badalloc) {
1356  // there may be a weakness in guile's implementation here: if
1357  // calling scm_dynwind_unwind_handler() were to give rise to a
1358  // guile out-of-memory exception before the handler is set up by
1359  // it, then we could leak memory allocated from the preceding new
1360  // expressions. Whether that could happen is not documented by
1361  // guile, but because (a) it is so improbable, and (b) once we are
1362  // in out-of-memory land we are already in severe trouble and glib
1363  // is likely to terminate the program at some point anyway, it is
1364  // not worth troubling ourselves over.
1365  scm_dynwind_unwind_handler(&cgu_delete_vector, args, scm_t_wind_flags(0));
1366  // convert the list to a guile vector so we can access its items
1367  // efficiently in a for loop. This conversion is reasonably
1368  // efficient, in the sense that an ordinary guile vector is an
1369  // array of pointers, pointing to the same scheme objects that the
1370  // list refers to
1371  SCM guile_vec = scm_vector(scm);
1372 
1373  // std::vector::size_type is the same as size_t with the standard
1374  // allocators (but if we were to get a silent narrowing conversion
1375  // on calling std::vector::reserve() below, that doesn't matter -
1376  // instead if 'length' is less than SIZE_MAX but greater than the
1377  // maximum value of std::vector::size_type, at some point a call
1378  // to std::vector::emplace_back() below would throw and be caught,
1379  // and this function would end up rethrowing it as std::bad_alloc.
1380  // If in a particular implementation SIZE_MAX exceeds
1381  // std::vector::max_size(), a std::length_error exception would be
1382  // thrown by reserve() where max_size() is exceeded. On all
1383  // common implementations, max_size() is equal to SIZE_MAX, but
1384  // were such an exception to arise it would be swallowed (see
1385  // below) and then rethrown by this function as std::bad_alloc.
1386  // If 'length' is greater than SIZE_MAX, a guile out-of-range
1387  // exception would be thrown by scm_to_size_t() which would be
1388  // rethrown by Cgu:Extension::exec() or
1389  // Cgu::Exception::exec_shared as a Cgu::Extension::WrapperError
1390  // C++ exception. This is nice to know but in practice such large
1391  // lists would be unusably slow and a memory exception would be
1392  // reached long before std::vector::max_size() or SIZE_MAX are
1393  // exceeded.
1394  size_t length = scm_to_size_t(scm_vector_length(guile_vec));
1395  try {
1396  res->reserve(length);
1397  }
1398  catch (...) {
1399  badalloc = true;
1400  }
1401  for (size_t count = 0;
1402  count < length && !rv_error && !badalloc;
1403  ++count) {
1404  SCM item = scm_vector_ref(guile_vec, scm_from_size_t(count));
1405  if (scm_is_false(scm_string_p(item)))
1406  rv_error = "scheme code did not evaluate to a homogeneous list of string\n";
1407  else {
1408  size_t len;
1409  // we don't need a dynwind handler for 'str' because nothing
1410  // after the call to scm_to_utf8_stringn() and before the call
1411  // to free() can cause a guile exception to be raised
1412  char* str = scm_to_utf8_stringn(item, &len);
1413  try {
1414  res->emplace_back(str, len);
1415  }
1416  catch (...) {
1417  badalloc = true;
1418  }
1419  free(str);
1420  }
1421  }
1422  }
1423  // all done - no more guile exceptions are possible in this function
1424  // after this so end the dynamic context, take control of the memory
1425  // by RAII and if necessary throw a C++ exception
1426  scm_dynwind_end();
1427  std::unique_ptr<std::vector<std::string>> up_res(res);
1428  std::unique_ptr<VectorDeleteArgs> up_args(args);
1429  if (badalloc) throw std::bad_alloc();
1430  if (rv_error) throw ReturnValueError(rv_error);
1431  // neither gcc-4.9 nor clang-3.4 will optimize with RVO or move
1432  // semantics here, so force it by hand
1433  return std::move(*res);
1434 }
1435 
1436 /**
1437  * A translator function which can be passed to the third argument of
1438  * Extension::exec() or Extension::exec_shared(). It converts from a
1439  * scheme integer to a C++ representation of long. It is thread safe,
1440  * but see the comments above about the thread safety of
1441  * Extension::exec() and Extension::exec_shared().
1442  *
1443  * @param scm An opaque guile SCM object representing the value to
1444  * which the extension file passed to Extension::exec() or
1445  * Extension::exec_shared() evaluated, where that value is an integer.
1446  * @return The C++ long representation.
1447  * @exception std::bad_alloc This function might throw std::bad_alloc
1448  * if memory is exhausted and the system throws in that case.
1449  * @exception Cgu::Extension::GuileException This exception will be
1450  * thrown if the scheme code in the extension file passed to
1451  * Extension::exec() or Extension::exec_shared() caused a guile
1452  * exception to be thrown. Cgu::Extension::GuileException::what()
1453  * will give particulars of the guile exception thrown, in UTF-8
1454  * encoding.
1455  * @exception Cgu::Extension::ReturnValueError This exception will be
1456  * thrown if the scheme code in the extension file passed to
1457  * Extension::exec() or Extension::exec_shared() does not evaluate to
1458  * the type expected by the translator, or it is out of range for a
1459  * long.
1460  * @note No native guile exception will arise in this function and so
1461  * cause guile to jump out of it if no guile out-of-memory condition
1462  * occurs (given that this function is called after a guile extension
1463  * task has completed, such a condition is very improbable). If such
1464  * an exception were to arise, the implementation would handle it and
1465  * a C++ exception would be generated in its place in
1466  * Extension::exec() or Extension::exec_shared().
1467  *
1468  * Since 2.0.22
1469  */
1470 inline long integer_to_long(SCM scm) {
1472  if (scm_is_false(scm_integer_p(scm)))
1473  throw ReturnValueError("scheme code did not evaluate to an integer\n");
1474  SCM min = scm_from_long(std::numeric_limits<long>::min());
1475  SCM max = scm_from_long(std::numeric_limits<long>::max());
1476  if (scm_is_false(scm_leq_p(scm, max)) || scm_is_false(scm_geq_p(scm, min)))
1477  throw ReturnValueError("scheme code evaluated out of range for long\n");
1478  return scm_to_long(scm);
1479 }
1480 
1481 /**
1482  * A translator function which can be passed to the third argument of
1483  * Extension::exec() or Extension::exec_shared(). It converts from a
1484  * scheme real number to a C++ representation of double. It is thread
1485  * safe, but see the comments above about the thread safety of
1486  * Extension::exec() and Extension::exec_shared().
1487  *
1488  * @param scm An opaque guile SCM object representing the value to
1489  * which the extension file passed to Extension::exec() or
1490  * Extension::exec_shared() evaluated, where that value is a real
1491  * number.
1492  * @return The C++ double representation.
1493  * @exception std::bad_alloc This function might throw std::bad_alloc
1494  * if memory is exhausted and the system throws in that case.
1495  * @exception Cgu::Extension::GuileException This exception will be
1496  * thrown if the scheme code in the extension file passed to
1497  * Extension::exec() or Extension::exec_shared() caused a guile
1498  * exception to be thrown. Cgu::Extension::GuileException::what()
1499  * will give particulars of the guile exception thrown, in UTF-8
1500  * encoding.
1501  * @exception Cgu::Extension::ReturnValueError This exception will be
1502  * thrown if the scheme code in the extension file passed to
1503  * Extension::exec() or Extension::exec_shared() does not evaluate to
1504  * the type expected by the translator, or it is out of range for a
1505  * double.
1506  * @note 1. Prior to version 2.0.25, this translator had a bug which
1507  * caused an out-of-range Cgu::Extension::ReturnValueError to be
1508  * thrown if the scheme code in the extension file evaluated to 0.0 or
1509  * a negative number. This was fixed in version 2.0.25.
1510  * @note 2. No native guile exception will arise in this function and
1511  * so cause guile to jump out of it if no guile out-of-memory
1512  * condition occurs (given that this function is called after a guile
1513  * extension task has completed, such a condition is very improbable).
1514  * If such an exception were to arise, the implementation would handle
1515  * it and a C++ exception would be generated in its place in
1516  * Extension::exec() or Extension::exec_shared().
1517  *
1518  * Since 2.0.22
1519  */
1520 inline double real_to_double(SCM scm) {
1522  if (scm_is_false(scm_real_p(scm)))
1523  throw ReturnValueError("scheme code did not evaluate to a real number\n");
1524  SCM min = scm_from_double(-std::numeric_limits<double>::max());
1525  SCM max = scm_from_double(std::numeric_limits<double>::max());
1526  if (scm_is_false(scm_leq_p(scm, max)) || scm_is_false(scm_geq_p(scm, min)))
1527  throw ReturnValueError("scheme code evaluated out of range for double\n");
1528  return scm_to_double(scm);
1529 }
1530 
1531 /**
1532  * A translator function which can be passed to the third argument of
1533  * Extension::exec() or Extension::exec_shared(). It converts from a
1534  * scheme string to a C++ representation of std::string. It is thread
1535  * safe, but see the comments above about the thread safety of
1536  * Extension::exec() and Extension::exec_shared().
1537  *
1538  * The returned string will be in UTF-8 encoding.
1539  *
1540  * @param scm An opaque guile SCM object representing the value to
1541  * which the extension file passed to Extension::exec() or
1542  * Extension::exec_shared() evaluated, where that value is a string.
1543  * @return The std::string representation.
1544  * @exception std::bad_alloc This function might throw std::bad_alloc
1545  * if memory is exhausted and the system throws in that case.
1546  * @exception Cgu::Extension::GuileException This exception will be
1547  * thrown if the scheme code in the extension file passed to
1548  * Extension::exec() or Extension::exec_shared() caused a guile
1549  * exception to be thrown. Cgu::Extension::GuileException::what()
1550  * will give particulars of the guile exception thrown, in UTF-8
1551  * encoding.
1552  * @exception Cgu::Extension::ReturnValueError This exception will be
1553  * thrown if the scheme code in the extension file passed to
1554  * Extension::exec() or Extension::exec_shared() does not evaluate to
1555  * the type expected by the translator.
1556  * @note No native guile exception will arise in this function and so
1557  * cause guile to jump out of it if no guile out-of-memory condition
1558  * occurs (given that this function is called after a guile extension
1559  * task has completed, such a condition is very improbable). If such
1560  * an exception were to arise, the implementation would handle it and
1561  * a C++ exception would be generated in its place in
1562  * Extension::exec() or Extension::exec_shared().
1563  *
1564  * Since 2.0.22
1565  */
1566 inline std::string string_to_string(SCM scm) {
1568  if (scm_is_false(scm_string_p(scm)))
1569  throw ReturnValueError("scheme code did not evaluate to a string\n");
1570  size_t len;
1571  // it is safe to use unique_ptr here. If scm_to_utf8_stringn()
1572  // succeeds then nothing after it in this function can cause a guile
1573  // exception.
1574  std::unique_ptr<const char, Cgu::CFree> s(scm_to_utf8_stringn(scm, &len));
1575  return std::string(s.get(), len);
1576 }
1577 
1578 /**
1579  * A translator function which can be passed to the third argument of
1580  * Extension::exec() or Extension::exec_shared(). It disregards the
1581  * scheme value passed to it except to trap any guile exception thrown
1582  * by the scheme task and rethrow it as a C++ exception, and returns a
1583  * NULL void* object. It is thread safe, but see the comments above
1584  * about the thread safety of Extension::exec() and
1585  * Extension::exec_shared().
1586  *
1587  * It is mainly intended for use where the scheme script is executed
1588  * for its side effects, perhaps for I/O, and any communication
1589  * necessary is done by guile exceptions.
1590  *
1591  * @param scm An opaque guile SCM object representing the value to
1592  * which the extension file passed to Extension::exec() or
1593  * Extension::exec_shared() evaluated, which is ignored.
1594  * @return A NULL void* object.
1595  * @exception std::bad_alloc This function might throw std::bad_alloc
1596  * if memory is exhausted and the system throws in that case.
1597  * @exception Cgu::Extension::GuileException This exception will be
1598  * thrown if the scheme code in the extension file passed to
1599  * Extension::exec() or Extension::exec_shared() caused a guile
1600  * exception to be thrown. Cgu::Extension::GuileException::what()
1601  * will give particulars of the guile exception thrown, in UTF-8
1602  * encoding.
1603  * @note No native guile exception will arise in this function and so
1604  * cause guile to jump out of it if no guile out-of-memory condition
1605  * occurs (given that this function is called after a guile extension
1606  * task has completed, such a condition is very improbable). If such
1607  * an exception were to arise, the implementation would handle it and
1608  * a C++ exception would be generated in its place in
1609  * Extension::exec() or Extension::exec_shared().
1610  *
1611  * Since 2.0.22
1612  */
1613 inline void* any_to_void(SCM scm) {
1615  return 0;
1616 }
1617 
1618 /**
1619  * This function executes scheme code on the guile VM within a C++
1620  * program using this library. See the introductory remarks above for
1621  * its potential uses, about the thread safety of this function, and
1622  * about the use of the TaskManager::exec_shared() as an alternative.
1623  *
1624  * The first argument to this function is a preamble, which can be
1625  * used to pass top level definitions to the scheme code (in other
1626  * words, for argument passing). It's second argument is the filename
1627  * (with path) of the file containing the scheme code to be executed.
1628  * It's third argument is a translator, which will convert the value
1629  * to which the scheme code evaluates (in C++ terms, its return value)
1630  * to a suitable C++ representation. Preformed translators are
1631  * provided by this library to translate from scheme's integers, real
1632  * numbers and strings to C++ longs, doubles and strings respectively,
1633  * and from any uniform lists of these to C++ vectors of the
1634  * corresponding type. There is also a translator for void return
1635  * types. See the introductory remarks above for more information
1636  * about translators.
1637  *
1638  * Any native guile exceptions thrown by the code executed by this
1639  * function (and by any code which it calls) are converted and
1640  * rethrown as C++ exceptions.
1641  *
1642  * The scheme file can call other scheme code, and load modules, in
1643  * the ordinary way. Thus, this function can execute any scheme code
1644  * which guile can execute as a program, and the programmer can (if
1645  * wanted) act on its return value in the C++ code which invokes it.
1646  *
1647  * Thread cancellation is blocked for the thread in which this
1648  * function executes until this function returns.
1649  *
1650  * @param preamble Scheme code such as top level definitions to be
1651  * seen by the code in the file to be executed. This is mainly
1652  * intended for argument passing, but can comprise any valid scheme
1653  * code. It can also be empty (you can pass ""). Any string literals
1654  * must be in UTF-8 encoding.
1655  * @param file The file which is to be executed on the guile VM. This
1656  * should include the full pathname or a pathname relative to the
1657  * current directory. The contents of the file, and in particular any
1658  * string literals in it, must be in UTF-8 encoding. The filename and
1659  * path must also be given in UTF-8 encoding, even if the local
1660  * filename encoding is something different: guile will convert the
1661  * UTF-8 name which it is given to its own internal string encoding
1662  * using unicode code points, and then convert that to locale encoding
1663  * on looking up the filename. However sticking to ASCII for
1664  * filenames and paths (which is always valid UTF-8) will maximise
1665  * portability. The file name can be empty (you can pass ""), in
1666  * which case only the preamble will be evaluated (but for efficiency
1667  * reasons any complex code not at the top level should be included in
1668  * the file rather than in the preamble).
1669  * @param translator The function or callable object which will
1670  * convert the value to which the scheme code evaluates to a C++
1671  * representation which will be returned by this function. The
1672  * translator should take a single argument comprising an opaque guile
1673  * object of type SCM, and return the C++ representation for it.
1674  * @return The C++ representation returned by the translator.
1675  * @exception std::bad_alloc This function might throw std::bad_alloc
1676  * if memory is exhausted and the system throws in that case.
1677  * @exception Cgu::Extension::GuileException This exception will be
1678  * thrown if the scheme code in 'file' (or called by it) throws a
1679  * guile exception. Cgu::Extension::GuileException::what() will give
1680  * particulars of the guile exception thrown, in UTF-8 encoding.
1681  * @exception Cgu::Extension::ReturnValueError This exception will be
1682  * thrown if the code in 'file' does not evaluate to the type expected
1683  * by the translator.
1684  * @exception Cgu::Extension::WrapperError This exception will be
1685  * thrown if a custom translator throws a native guile exception or a
1686  * C++ exception not comprising Extension::GuileException or
1687  * Extension::ReturnValueError, one of the preformed translators
1688  * throws std::bad_alloc or encounters a guile out-of-memory
1689  * exception, one of the preformed list translators encounters an
1690  * input list exceeding SIZE_MAX in length, assigning to an internal
1691  * exception description string throws std::bad_alloc, or evaluation
1692  * of the preamble throws a native guile exception.
1693  *
1694  * Since 2.0.22
1695  */
1696 // we cannot take 'translator' by collapsible reference, because with
1697 // gcc-4.4 std::result_of fails if Translator deduces to a reference
1698 // type, and gcc-4.4 does not have std::declval. This is fixed in the
1699 // 2.2 series of this library, which has a minimum requirement of
1700 // gcc-4.6.
1701 template <class Translator>
1702 auto exec(const std::string& preamble,
1703  const std::string& file,
1704  Translator translator) -> typename std::result_of<Translator(SCM)>::type {
1705  // exec_impl() will fail to compile if Ret is a reference type: that
1706  // is a feature, not a bug, as there is no good reason for a
1707  // translator ever to return a reference
1708  typedef typename std::result_of<Translator(SCM)>::type Ret;
1709  return exec_impl<Ret>(preamble, file, translator, false);
1710 }
1711 
1712 /**
1713  * This function executes scheme code on the guile VM within a C++
1714  * program using this library. See the introductory remarks above for
1715  * its potential uses, about the thread safety of this function, and
1716  * about the use of the TaskManager::exec() as an alternative.
1717  *
1718  * The first argument to this function is a preamble, which can be
1719  * used to pass top level definitions to the scheme code (in other
1720  * words, for argument passing). It's second argument is the filename
1721  * (with path) of the file containing the scheme code to be executed.
1722  * It's third argument is a translator, which will convert the value
1723  * to which the scheme code evaluates (in C++ terms, its return value)
1724  * to a suitable C++ representation. Preformed translators are
1725  * provided by this library to translate from scheme's integers, real
1726  * numbers and strings to C++ longs, doubles and strings respectively,
1727  * and from any uniform lists of these to C++ vectors of the
1728  * corresponding type. There is also a translator for void return
1729  * types. See the introductory remarks above for more information
1730  * about translators.
1731  *
1732  * Any native guile exceptions thrown by the code executed by this
1733  * function (and by any code which it calls) are converted and
1734  * rethrown as C++ exceptions.
1735  *
1736  * The scheme file can call other scheme code, and load modules, in
1737  * the ordinary way. Thus, this function can execute any scheme code
1738  * which guile can execute as a program, and the programmer can (if
1739  * wanted) act on its return value in the C++ code which invokes it.
1740  *
1741  * Thread cancellation is blocked for the thread in which this
1742  * function executes until this function returns.
1743  *
1744  * @param preamble Scheme code such as top level definitions to be
1745  * seen by the code in the file to be executed. This is mainly
1746  * intended for argument passing, but can comprise any valid scheme
1747  * code. It can also be empty (you can pass ""). Any string literals
1748  * must be in UTF-8 encoding.
1749  * @param file The file which is to be executed on the guile VM. This
1750  * should include the full pathname or a pathname relative to the
1751  * current directory. The contents of the file, and in particular any
1752  * string literals in it, must be in UTF-8 encoding. The filename and
1753  * path must also be given in UTF-8 encoding, even if the local
1754  * filename encoding is something different: guile will convert the
1755  * UTF-8 name which it is given to its own internal string encoding
1756  * using unicode code points, and then convert that to locale encoding
1757  * on looking up the filename. However sticking to ASCII for
1758  * filenames and paths (which is always valid UTF-8) will maximise
1759  * portability. The file name can be empty (you can pass ""), in
1760  * which case only the preamble will be evaluated.
1761  * @param translator The function or callable object which will
1762  * convert the value to which the scheme code evaluates to a C++
1763  * representation which will be returned by this function. The
1764  * translator should take a single argument comprising an opaque guile
1765  * object of type SCM, and return the C++ representation for it.
1766  * @return The C++ representation returned by the translator.
1767  * @exception std::bad_alloc This function might throw std::bad_alloc
1768  * if memory is exhausted and the system throws in that case.
1769  * @exception Cgu::Extension::GuileException This exception will be
1770  * thrown if the scheme code in 'file' (or called by it) throws a
1771  * guile exception. Cgu::Extension::GuileException::what() will give
1772  * particulars of the guile exception thrown, in UTF-8 encoding.
1773  * @exception Cgu::Extension::ReturnValueError This exception will be
1774  * thrown if the code in 'file' does not evaluate to the type expected
1775  * by the translator.
1776  * @exception Cgu::Extension::WrapperError This exception will be
1777  * thrown if a custom translator throws a native guile exception or a
1778  * C++ exception not comprising Extension::GuileException or
1779  * Extension::ReturnValueError, one of the preformed translators
1780  * throws std::bad_alloc or encounters a guile out-of-memory
1781  * exception, one of the preformed list translators encounters an
1782  * input list exceeding SIZE_MAX in length, assigning to an internal
1783  * exception description string throws std::bad_alloc, or evaluation
1784  * of the preamble throws a native guile exception.
1785  *
1786  * Since 2.0.24
1787  */
1788 // we cannot take 'translator' by collapsible reference, because with
1789 // gcc-4.4 std::result_of fails if Translator deduces to a reference
1790 // type, and gcc-4.4 does not have std::declval. This is fixed in the
1791 // 2.2 series of this library, which has a minimum requirement of
1792 // gcc-4.6.
1793 template <class Translator>
1794 auto exec_shared(const std::string& preamble,
1795  const std::string& file,
1796  Translator translator) -> typename std::result_of<Translator(SCM)>::type {
1797  // exec_impl() will fail to compile if Ret is a reference type: that
1798  // is a feature, not a bug, as there is no good reason for a
1799  // translator ever to return a reference
1800  typedef typename std::result_of<Translator(SCM)>::type Ret;
1801  return exec_impl<Ret>(preamble, file, translator, true);
1802 }
1803 
1804 } // namespace Extension
1805 
1806 } // namespace Cgu
1807 
1808 #endif // CGU_EXTENSION_H
Cgu::Extension::list_to_vector_string
std::vector< std::string > list_to_vector_string(SCM scm)
Definition: extension.h:1322
Cgu::Extension::string_to_string
std::string string_to_string(SCM scm)
Definition: extension.h:1566
Cgu::Extension::list_to_vector_double
std::vector< double > list_to_vector_double(SCM scm)
Definition: extension.h:1164
Cgu::Callback::CallbackArg
The callback interface class.
Definition: callback.h:522
Cgu::Extension::WrapperError::what
virtual const char * what() const
Definition: extension.h:597
Cgu
Definition: application.h:44
Cgu::Extension::exception_to_string
SCM exception_to_string(SCM key, SCM args)
Definition: extension.h:838
Cgu::Extension::list_to_vector_long
std::vector< long > list_to_vector_long(SCM scm)
Definition: extension.h:1006
Cgu::Extension::ReturnValueError
Definition: extension.h:582
Cgu::Extension::real_to_double
double real_to_double(SCM scm)
Definition: extension.h:1520
Cgu::Extension::WrapperError
Definition: extension.h:594
Cgu::Extension::any_to_void
void * any_to_void(SCM scm)
Definition: extension.h:1613
callback.h
This file provides classes for type erasure.
Cgu::Extension::ReturnValueError::ReturnValueError
ReturnValueError(const char *msg)
Definition: extension.h:588
Cgu::Extension::rethrow_guile_exception
void rethrow_guile_exception(SCM scm)
Definition: extension.h:924
Cgu::Extension::GuileException::GuileException
GuileException(const char *msg)
Definition: extension.h:576
Cgu::Extension::integer_to_long
long integer_to_long(SCM scm)
Definition: extension.h:1470
Cgu::Extension::exec
auto exec(const std::string &preamble, const std::string &file, Translator translator) -> typename std::result_of< Translator(SCM)>::type
Definition: extension.h:1702
Cgu::SharedHandle< gchar *, GFree >
Cgu::Extension::GuileException::what
virtual const char * what() const
Definition: extension.h:574
Cgu::Extension::ReturnValueError::err_text
const char * err_text() const
Definition: extension.h:587
shared_handle.h
Cgu::Extension::GuileException
Definition: extension.h:570
Cgu::Extension::ReturnValueError::~ReturnValueError
~ReturnValueError()
Definition: extension.h:591
Cgu::Thread::CancelBlock
A class enabling the cancellation state of a thread to be controlled.
Definition: thread.h:686
mutex.h
Provides wrapper classes for pthread mutexes and condition variables, and scoped locking classes for ...
Cgu::Extension::WrapperError::~WrapperError
~WrapperError()
Definition: extension.h:600
Cgu::Extension::GuileException::~GuileException
~GuileException()
Definition: extension.h:579
Cgu::Extension::GuileException::guile_text
const char * guile_text() const
Definition: extension.h:575
Cgu::Extension::ReturnValueError::what
virtual const char * what() const
Definition: extension.h:586
thread.h
Cgu::Extension::exec_shared
auto exec_shared(const std::string &preamble, const std::string &file, Translator translator) -> typename std::result_of< Translator(SCM)>::type
Definition: extension.h:1794
Cgu::Thread::Mutex
A wrapper class for pthread mutexes.
Definition: mutex.h:117
Cgu::SharedHandle::get
T get() const
Definition: shared_handle.h:765
cgu_config.h
Cgu::Extension::WrapperError::WrapperError
WrapperError(const char *msg)
Definition: extension.h:598