c++-gtk-utils
extension.h
Go to the documentation of this file.
1 /* Copyright (C) 2014 and 2016 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 or guile-2.2 >= 2.1.3 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 or
363  * guile-2.2.pc). This library does NOT do that for you. Secondly,
364  * by linking with libguile you will be governed by the LGPL version 3
365  * or later, instead of the LGPL version 2.1 or later, with respect to
366  * that linking. That's fine (there is nothing wrong with the LGPL
367  * version 3 and this library permits that) but you should be aware of
368  * it. The scheme code in guile's scheme level modules is also in the
369  * main released under the LGPL version 3 or later ("in the main"
370  * because readline.scm, comprised in the readline module, is released
371  * 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-2.2 >= 2.1.3, then if it
378  * does not find that it will look for guile-2.0 >= 2.0.2, and then if
379  * it finds neither it will disable guile support; and the library
380  * header files will then be set up appropriately. guile-2.2 or
381  * guile-2.0 can be specifically picked with the \--with-guile=2.2 or
382  * \--with-guile=2.0 configuration options respectively. Guile
383  * support can be omitted with the \--with-guile=no option.
384 
385  * However, as mentioned under "Licence" above, any program using
386  * Extension::exec() or Extension::exec_shared() must link itself
387  * explicitly with libguile via either guile-2.0.pc (for guile-2.0) or
388  * guile-2.2.pc (for guile-2.2). Programs should use whichever of
389  * those is the one for which c++-gtk-utils was configured. If you
390  * get link-time messages from a program about being unable to link to
391  * scm_dynwind_block_asyncs(), then there has been a version mismatch.
392  * If you get link-time messages about being unable to link to
393  * Cgu::Extension::init_mutex() or
394  * Cgu::Extension::get_user_module_mutex() then c++-gtk-utils has not
395  * been configured to offer guile support.
396  *
397  * Custom translators
398  * ------------------
399  *
400  * Any function or callable object which translates from an opaque SCM
401  * value to a suitable C++ representation can be passed as the third
402  * argument of Extension::exec() or Extension::exec_shared(). C++
403  * type deduction on template resolution will take care of everything
404  * else. The translator can execute any functions offered by
405  * libguile, because when the translator is run the program is still
406  * in guile mode. The fulsome guile documentation sets out the
407  * libguile functions which are callable in C/C++ code.
408  *
409  * The first call in a custom translator should normally be to the
410  * Extension::rethrow_guile_exception() function. This function tests
411  * whether a guile exception arose in executing the scheme file, and
412  * throws a C++ exception if it did. The preformed translators in
413  * extension.h provide worked examples of how a custom translator
414  * might be written.
415  *
416  * If something done in a custom translator were to raise a guile
417  * exception, the library implementation would handle it and a C++
418  * exception would be generated in its place in Extension::exec() or
419  * Extension::exec_shared(). However, a custom translator should not
420  * allow a guile exception arising from calls to libguile made by it
421  * to exit a C++ scope in which the translator has constructed a local
422  * C++ object which is not trivially destructible: that would give
423  * rise to undefined behaviour, with the likely result that the C++
424  * object's destructor would not be called. One approach to this
425  * (adopted in the preformed translators) is to allocate on free store
426  * all local C++ objects to be constructed in the translator which are
427  * not trivially destructible, and to manage their lifetimes manually
428  * using local C++ try/catch blocks rather than RAII, with dynwind
429  * unwind handlers to release memory were there to be a guile
430  * exception (but note that no C++ exception should transit out of a
431  * scm_dynwind_begin()/scm_dynwind_end() pair). It is also a good
432  * idea to test for any condition which might cause a guile exception
433  * to be raised in the translator in the first place, and throw a C++
434  * exception beforehand. Then the only condition which might cause a
435  * guile exception to occur in the translator is an out-of-memory
436  * condition, which is highly improbable in a translator as the
437  * translator is run after the guile task has completed. Heap
438  * exhaustion in such a case probably spells doom for the program
439  * concerned anyway, if it has other work to do.
440  *
441  * Note also that code in a custom translator should not store guile
442  * SCM objects (which are pointers to guile scheme objects) in memory
443  * blocks allocated by malloc() or the new expression, or they will
444  * not be seen by the garbage collector used by libguile (which is the
445  * gc library) and therefore may be prematurely deallocated. To keep
446  * such items alive in custom allocators, SCM variables should be kept
447  * as local variables or parameter names in functions (and so stored
448  * on the stack or in registers, where they will be seen by the
449  * garbage collector), or in memory allocated with scm_gc_malloc(),
450  * where they will also be seen by the garbage collector.
451  *
452  * Scheme
453  * ------
454  * If you want to learn more about scheme, these are useful sources:
455  * <P>
456  * <A HREF="http://www.gnu.org/software/guile/manual/html_node/Hello-Scheme_0021.html"> Chapter 3 of the Guile Manual</A>
457  * (the rest of the manual is also good reading).</P>
458  * <P>
459  * <A HREF="http://www.scheme.com/tspl4/">The Scheme Programming Language, 4th edition</A></P>
460  */
461 
462 #include <string>
463 #include <vector>
464 #include <exception>
465 #include <memory> // for std::unique_ptr
466 #include <type_traits> // for std::remove_reference, std::remove_const and std::result_of
467 #include <limits> // for std::numeric_limits
468 #include <functional> // for std::bind
469 #include <utility> // for std::move
470 #include <new> // for std::bad_alloc
471 
472 #include <stddef.h> // for size_t
473 #include <stdlib.h> // for free()
474 #include <string.h> // for strlen() and strncmp()
475 
476 #include <glib.h>
477 
479 #include <c++-gtk-utils/callback.h>
480 #include <c++-gtk-utils/thread.h>
481 #include <c++-gtk-utils/mutex.h>
483 
484 #include <libguile.h>
485 
486 
487 #ifndef DOXYGEN_PARSING
488 namespace Cgu {
489 
490 namespace Extension {
491 
492 struct FormatArgs {
493  SCM text;
494  SCM rest;
495 };
496 
497 enum VectorDeleteType {Long, Double, String};
498 
499 struct VectorDeleteArgs {
500  VectorDeleteType type;
501  void* vec;
502 };
503 
504 // defined in extension_helper.cpp
505 extern Cgu::Thread::Mutex* get_user_module_mutex();
506 extern bool init_mutex();
507 
508 } // namespace Extension
509 
510 } // namespace Cgu
511 
512 namespace {
513 extern "C" {
514  inline SCM cgu_format_try_handler(void* data) {
515  using Cgu::Extension::FormatArgs;
516  FormatArgs* format_args = static_cast<FormatArgs*>(data);
517  return scm_simple_format(SCM_BOOL_F, format_args->text, format_args->rest);
518  }
519  inline SCM cgu_format_catch_handler(void*, SCM, SCM) {
520  return SCM_BOOL_F;
521  }
522  inline void* cgu_guile_wrapper(void* data) {
523  try {
524  static_cast<Cgu::Callback::Callback*>(data)->dispatch();
525  }
526  // an elipsis catch block is fine as thread cancellation is
527  // blocked. We can only enter this block if assigning to one of
528  // the exception strings in the callback has thrown
529  // std::bad_alloc. For that case we return a non-NULL pointer to
530  // indicate error (the 'data' argument is convenient and
531  // guaranteed to be standard-conforming for this).
532  catch (...) {
533  return data;
534  }
535  return 0;
536  }
537  inline void cgu_delete_vector(void* data) {
538  using Cgu::Extension::VectorDeleteArgs;
539  VectorDeleteArgs* args = static_cast<VectorDeleteArgs*>(data);
540  switch (args->type) {
541  case Cgu::Extension::Long:
542  delete static_cast<std::vector<long>*>(args->vec);
543  break;
544  case Cgu::Extension::Double:
545  delete static_cast<std::vector<double>*>(args->vec);
546  break;
547  case Cgu::Extension::String:
548  delete static_cast<std::vector<std::string>*>(args->vec);
549  break;
550  default:
551  g_critical("Incorrect argument passed to cgu_delete_vector");
552  }
553  delete args;
554  }
555  inline void cgu_unlock_module_mutex(void*) {
556  // this cannot give rise to an allocation or mutex error -
557  // we must have been called init_mutex() first
558  Cgu::Extension::get_user_module_mutex()->unlock();
559  }
560 } // extern "C"
561 } // unnamed namespace
562 #endif // DOXYGEN_PARSING
563 
564 namespace Cgu {
565 
566 namespace Extension {
567 
568 class GuileException: public std::exception {
569  Cgu::GcharSharedHandle message;
570  Cgu::GcharSharedHandle guile_message;
571 public:
572  virtual const char* what() const throw() {return (const char*)message.get();}
573  const char* guile_text() const throw() {return (const char*)guile_message.get();}
574  GuileException(const char* msg):
575  message(g_strdup_printf("Cgu::Extension::GuileException: %s", msg)),
576  guile_message(g_strdup(msg)) {}
577  ~GuileException() throw() {}
578 };
579 
580 class ReturnValueError: public std::exception {
581  Cgu::GcharSharedHandle message;
582  Cgu::GcharSharedHandle err_message;
583 public:
584  virtual const char* what() const throw() {return (const char*)message.get();}
585  const char* err_text() const throw() {return (const char*)err_message.get();}
586  ReturnValueError(const char* msg):
587  message(g_strdup_printf("Cgu::Extension::ReturnValueError: %s", msg)),
588  err_message(g_strdup(msg)) {}
589  ~ReturnValueError() throw() {}
590 };
591 
592 class WrapperError: public std::exception {
593  Cgu::GcharSharedHandle message;
594 public:
595  virtual const char* what() const throw() {return (const char*)message.get();}
596  WrapperError(const char* msg):
597  message(g_strdup_printf("Cgu::Extension::WrapperError: %s", msg)) {}
598  ~WrapperError() throw() {}
599 };
600 
601 #ifndef DOXYGEN_PARSING
602 
603 // this function has been renamed guile_wrapper_cb2 in version 2.0.28
604 // in order to prevent ODR issues and ensure exec_impl() in 2.0.28
605 // calls the correct version of this function
606 template <class Ret, class TransType>
607 void guile_wrapper_cb2(TransType* translator,
608  std::string* loader,
609  Ret* retval,
610  bool* result,
611  std::string* guile_except,
612  std::string* guile_ret_val_err,
613  std::string* gen_err,
614  bool shared) {
615  SCM scm;
616  if (shared) {
617  scm = scm_eval_string_in_module(scm_from_utf8_string(loader->c_str()),
618  scm_c_resolve_module("guile-user"));
619  }
620  else {
621  if (!init_mutex())
622  throw std::bad_alloc(); // this will be caught in cgu_guile_wrapper()
623 
624  scm_dynwind_begin(scm_t_dynwind_flags(0));
625  scm_dynwind_unwind_handler(&cgu_unlock_module_mutex, 0, SCM_F_WIND_EXPLICITLY);
626  get_user_module_mutex()->lock(); // won't throw
627  SCM new_mod = scm_call_0(scm_c_public_ref("guile", "make-fresh-user-module"));
628  scm_dynwind_end();
629 
630  scm = scm_eval_string_in_module(scm_from_utf8_string(loader->c_str()),
631  new_mod);
632  }
633 
634  // have a dynwind context and async block while translator is
635  // executing. This is to cater for the pathological case of the
636  // scheme script having set up a signal handler which might throw a
637  // guile exception, or having chained a series of system asyncs
638  // which are still queued for action, which might otherwise cause
639  // the translator to trigger a guile exception while a non-trivially
640  // destructible object is in the local scope of translator. (Highly
641  // unlikely, but easy to deal with.) This is entirely safe as no
642  // C++ exception arising from the translator can transit across the
643  // dynamic context in this function - see below. So we have (i) no
644  // C++ exception can transit across a guile dynamic context, and
645  // (ii) no guile exception can escape out of a local C++ scope by
646  // virtue of an async executing (it might still escape with a
647  // non-trivially destructible object in existence if a custom
648  // translator has not been written correctly, but there is nothing
649  // we can do about that). Note that some guile installations do not
650  // link scm_dynwind_block_asyncs() correctly - this is tested at
651  // configuration time.
652 #ifndef CGU_GUILE_HAS_BROKEN_LINKING
653  scm_dynwind_begin(scm_t_dynwind_flags(0));
654  scm_dynwind_block_asyncs();
655 #endif
656  // we cannot use std::exception_ptr here to store a C++ exception
657  // object, because std::exception_ptr is not trivially destructible
658  // and a guile exception in 'translator' could jump out of this
659  // scope to its continuation in scm_with_guile()
660  bool badalloc = false;
661  try {
662  *retval = (*translator)(scm);
663  *result = true; // this will detect any guile exception in the
664  // preamble or 'translator' which causes
665  // scm_with_guile() to return prematurely. We
666  // have could have done it instead by reversing
667  // the return values of cgu_guile_wrapper
668  // (non-NULL for success and NULL for failure)
669  // because scm_with_guile() returns NULL if it
670  // exits on an uncaught guile exception, but this
671  // approach enables us to discriminate between a
672  // C++ memory exception in the wrapper and a guile
673  // exception in the preamble or 'translator', at a
674  // minimal cost of one assignment to a bool.
675  }
676  catch (Cgu::Extension::GuileException& e) {
677  try {
678  *guile_except = e.guile_text();
679  }
680  catch (...) {
681  badalloc = true;
682  }
683  }
685  try {
686  *guile_ret_val_err = e.err_text();
687  }
688  catch (...) {
689  badalloc = true;
690  }
691  }
692  catch (std::exception& e) {
693  try {
694  *gen_err = e.what();
695  }
696  catch (...) {
697  badalloc = true;
698  }
699  }
700  catch (...) {
701  try {
702  *gen_err = "C++ exception thrown in guile_wrapper_cb()";
703  }
704  catch (...) {
705  badalloc = true;
706  }
707  }
708 #ifndef CGU_GUILE_HAS_BROKEN_LINKING
709  scm_dynwind_end();
710 #endif
711  if (badalloc) throw std::bad_alloc(); // this will be caught in cgu_guile_wrapper()
712 }
713 
714 template <class Ret, class Translator>
715 Ret exec_impl(const std::string& preamble,
716  const std::string& file,
717  Translator translator,
718  bool shared) {
719 
721 
722  std::string loader;
723  loader += preamble;
724  if (!file.empty()) {
725  if (shared)
726  loader += "((lambda ()";
727  loader += "(catch "
728  "#t"
729  "(lambda ()"
730  "(";
731  if (shared)
732  loader += "primitive-load \"";
733  else
734  loader += "load \"";
735  loader += file;
736  loader += "\"))"
737  "(lambda (key . details)"
738  "(cons \"***cgu-guile-exception***\" (cons key details))))";
739  if (shared)
740  loader += "))";
741  }
742 
743  Ret retval;
744  bool result = false;
745  std::string guile_except;
746  std::string guile_ret_val_err;
747  std::string gen_err;
748 
749  // we construct a Callback::Callback object here to perform type
750  // erasure. Otherwise we would have to pass scm_with_guile() a
751  // function pointer to a function templated on Translator and Ret,
752  // which must have C++ language linkage (§14/4 of C++ standard).
753  // Technically this would give undefined behaviour as
754  // scm_with_guile() expects a function pointer with C language
755  // linkage, although gcc and clang would accept it. The whole of
756  // this callback will be executed in guile mode via
757  // cgu_guile_wrapper(), so it can safely call libguile functions
758  // (provided that a translator does not allow any guile exceptions
759  // to escape a C++ scope with local objects which are not trivially
760  // destructible). It is also safe to pass 'translator', 'retval',
761  // 'loader', 'result' and the exception strings to it by reference,
762  // because scm_with_guile() will block until it has completed
763  // executing. cgu_guile_wrapper() will trap any std::bad_alloc
764  // exception thrown by the string assignments in the catch blocks in
765  // guile_wrapper_cb. guile_wrapper_cb is safe against a jump to an
766  // exit from scm_with_guile() arising from a native guile exception
767  // in translator, because its body has no objects in local scope
768  // requiring destruction.
769  std::unique_ptr<Cgu::Callback::Callback> cb(
770  Cgu::Callback::lambda<>(std::bind(&guile_wrapper_cb2<Ret, Translator>,
771  &translator,
772  &loader,
773  &retval,
774  &result,
775  &guile_except,
776  &guile_ret_val_err,
777  &gen_err,
778  shared))
779  );
780  // cgu_guile_wrapper(), and so scm_with_guile() will return a
781  // non-NULL value if assigning to one of the exception description
782  // strings above threw std::bad_alloc
783  if (scm_with_guile(&cgu_guile_wrapper, cb.get()))
784  throw WrapperError("cgu_guile_wrapper() has trapped std::bad_alloc");
785  if (!guile_except.empty())
786  throw GuileException(guile_except.c_str());
787  if (!guile_ret_val_err.empty())
788  throw ReturnValueError(guile_ret_val_err.c_str());
789  if (!gen_err.empty())
790  throw WrapperError(gen_err.c_str());
791  if (!result)
792  throw WrapperError("the preamble or translator threw a native guile exception");
793  return retval;
794 }
795 
796 #endif // DOXYGEN_PARSING
797 
798 /**
799  * This function is called by Extension::rethrow_guile_exception()
800  * where the scheme code executed by Extension::exec() or
801  * Extension::exec_shared() has exited with a guile exception. It
802  * converts the raw guile exception information represented by the
803  * 'key' and 'args' arguments of a guile catch handler to a more
804  * readable form. It is made available as part of the public
805  * interface so that any custom translators can also use it if they
806  * choose to provide their own catch expressions. This function does
807  * not throw any C++ exceptions. No native guile exception will arise
808  * in this function and so cause guile to jump out of it assuming no
809  * guile out-of-memory condition occurs (and given that this function
810  * is called after a guile extension task has completed, such a
811  * condition is very improbable). It is thread safe, but see the
812  * comments above about the thread safety of Extension::exec() and
813  * Extension::exec_shared().
814  *
815  * @param key An opaque guile SCM object representing a symbol
816  * comprising the 'key' argument of the exception handler of a guile
817  * catch expression.
818  * @param args An opaque guile SCM object representing a list
819  * comprising the 'args' argument of the exception handler of a guile
820  * catch expression.
821  * @return An opaque guile SCM object representing a guile string.
822  *
823  * Since 2.0.22
824  */
825 inline SCM exception_to_string(SCM key, SCM args) {
826  // The args of most exceptions thrown by guile are in the following format:
827  // (car args) - a string comprising the name of the procedure generating the exception
828  // (cadr args) - a string containing text, possibly with format directives (escape sequences)
829  // (caddr args) - a list containing items matching the format directives, or #f if none
830  // (cadddr args) - (not used here) a list of additional objects (eg the errno for some errors),
831  // or #f if none
832  SCM ret = SCM_BOOL_F;
833  int length = scm_to_int(scm_length(args));
834  if (length) {
835  SCM first = scm_car(args);
836  if (scm_is_true(scm_string_p(first))) {
837  // if a single user string, output it
838  if (length == 1) {
839  ret = scm_string_append(scm_list_4(scm_from_utf8_string("Exception "),
840  scm_symbol_to_string(key),
841  scm_from_utf8_string(": "),
842  first));
843  }
844  else { // length > 1
845  SCM second = scm_cadr(args);
846  if (scm_is_true(scm_string_p(second))) {
847  // we should have a standard guile exception string, as above
848  SCM text = scm_string_append(scm_list_n(scm_from_utf8_string("Exception "),
849  scm_symbol_to_string(key),
850  scm_from_utf8_string(" in procedure "),
851  first,
852  scm_from_utf8_string(": "),
853  second,
854  SCM_UNDEFINED));
855  if (length == 2)
856  ret = text;
857  else { // length > 2
858  SCM third = scm_caddr(args);
859  if (scm_is_false(third))
860  ret = text;
861  else if (scm_is_true(scm_list_p(third))) {
862  FormatArgs format_args = {text, third};
863  ret = scm_internal_catch(SCM_BOOL_T,
864  &cgu_format_try_handler,
865  &format_args,
866  &cgu_format_catch_handler,
867  0);
868  }
869  }
870  }
871  }
872  }
873  }
874  // fall back to generic formatting if first or second elements of
875  // args is not a string or simple-format failed above
876  if (scm_is_false(ret)) {
877  // there is no need for a catch block: we know simple-format
878  // cannot raise an exception here
879  ret = scm_simple_format(SCM_BOOL_F,
880  scm_from_utf8_string("Exception ~S: ~S"),
881  scm_list_2(key, args));
882  }
883  return ret;
884 }
885 
886 /**
887  * This function tests whether a guile exception arose in executing a
888  * scheme extension file, and throws Cgu::Extension::GuileException if
889  * it did. It is intended for use by custom translators, as the first
890  * thing the translator does. It is thread safe, but see the comments
891  * above about the thread safety of Extension::exec() and
892  * Extension::exec_shared().
893  *
894  * @param scm An opaque guile SCM object representing the value to
895  * which the extension file passed to Extension::exec() or
896  * Extension::exec_shared() evaluated.
897  * @exception std::bad_alloc This function might throw std::bad_alloc
898  * if memory is exhausted and the system throws in that case.
899  * @exception Cgu::Extension::GuileException This exception will be
900  * thrown if the scheme code executed in the extension file passed to
901  * Extension::exec() or Extension::exec_shared() threw a guile
902  * exception. Cgu::Extension::GuileException::what() will give
903  * particulars of the guile exception thrown, in UTF-8 encoding.
904  * @note No native guile exception will arise in this function and so
905  * cause guile to jump out of it if no guile out-of-memory condition
906  * occurs (given that this function is called after a guile extension
907  * task has completed, such a condition is very improbable).
908  *
909  * Since 2.0.22
910  */
911 inline void rethrow_guile_exception(SCM scm) {
912  // guile exceptions are always presented to this function as a
913  // scheme list
914  if (scm_is_false(scm_list_p(scm))
915  || scm_is_true(scm_null_p(scm))) return;
916  SCM first = scm_car(scm);
917  if (scm_is_true(scm_string_p(first))) {
918  size_t len;
919  const char* text = 0;
920  // nothing in this function should throw a guile exception unless
921  // there is a guile out-of-memory exception (which is extremely
922  // improbable). However, let's cover ourselves in case
923  scm_dynwind_begin(scm_t_dynwind_flags(0));
924  char* car = scm_to_utf8_stringn(first, &len);
925  // there may be a weakness in guile's implementation here: if
926  // calling scm_dynwind_unwind_handler() were to give rise to an
927  // out-of-memory exception before the handler is set up by it,
928  // then we could leak memory allocated from the preceding call to
929  // scm_to_utf8_stringn(). Whether that could happen is not
930  // documented, but because (a) it is so improbable, and (b) once
931  // we are in out-of-memory land we are already in severe trouble
932  // and glib is likely to terminate the program at some point
933  // anyway, it is not worth troubling ourselves over.
934  scm_dynwind_unwind_handler(&free, car, scm_t_wind_flags(0));
935  if (len == strlen("***cgu-guile-exception***")
936  && !strncmp(car, "***cgu-guile-exception***", len)) {
937  SCM str = exception_to_string(scm_cadr(scm), scm_cddr(scm));
938  // we don't need a dynwind handler for 'text' because nothing
939  // after the call to scm_to_utf8_stringn() can cause a guile
940  // exception to be raised
941  text = scm_to_utf8_stringn(str, &len);
942  }
943  // all done - no more guile exceptions are possible in this
944  // function after this so end the dynamic context, take control of
945  // the memory by RAII and if necessary throw a C++ exception
946  scm_dynwind_end();
947  std::unique_ptr<char, Cgu::CFree> up_car(car);
948  std::unique_ptr<const char, Cgu::CFree> up_text(text);
949  // if 'text' is not NULL, 'len' contains its length in bytes
950  if (text) throw GuileException(std::string(text, len).c_str());
951  }
952 }
953 
954 /**
955  * A translator function which can be passed to the third argument of
956  * Extension::exec() or Extension::exec_shared(). It converts from a
957  * homogeneous scheme list of integers to a C++ representation of
958  * std::vector<long>. It is thread safe, but see the comments above
959  * about the thread safety of Extension::exec() and
960  * Extension::exec_shared().
961  *
962  * @param scm An opaque guile SCM object representing the value to
963  * which the extension file passed to Extension::exec() or
964  * Extension::exec_shared() evaluated, where that value is a
965  * homogeneous list of integers.
966  * @return The std::vector<long> representation.
967  * @exception std::bad_alloc This function might throw std::bad_alloc
968  * if memory is exhausted and the system throws in that case, or if
969  * the length of the input list exceeds std::vector::max_size().
970  * @exception Cgu::Extension::GuileException This exception will be
971  * thrown if the scheme code in the extension file passed to
972  * Extension::exec() or Extension::exec_shared() caused a guile
973  * exception to be thrown. Cgu::Extension::GuileException::what()
974  * will give particulars of the guile exception thrown, in UTF-8
975  * encoding.
976  * @exception Cgu::Extension::ReturnValueError This exception will be
977  * thrown if the scheme code in the extension file passed to
978  * Extension::exec() or Extension::exec_shared() does not evaluate to
979  * the type expected by the translator, or it is out of range for a
980  * long.
981  * @note No native guile exception will arise in this function and so
982  * cause guile to jump out of it unless a guile out-of-memory
983  * condition occurs (given that this function is called after a guile
984  * extension task has completed, such a condition is very improbable)
985  * or the length of the input list exceeds SIZE_MAX (the maximum value
986  * of std::size_t). If such an exception were to arise, the
987  * implementation would handle it and a C++ exception would be
988  * generated in its place in Extension::exec() or
989  * Extension::exec_shared().
990  *
991  * Since 2.0.22
992  */
993 inline std::vector<long> list_to_vector_long(SCM scm) {
995  if (scm_is_false(scm_list_p(scm)))
996  throw ReturnValueError("scheme code did not evaluate to a list\n");
997 
998  // nothing in this function should throw a guile exception unless
999  // there is a guile out-of-memory exception (which is extremely
1000  // improbable). However, let's cover ourselves in case.
1001  scm_dynwind_begin(scm_t_dynwind_flags(0));
1002  // we cannot have a std::vector object in a scope where a guile
1003  // exception might be raised because it has a non-trivial
1004  // destructor, nor can we use RAII. Instead allocate on free store
1005  // and manage the memory by hand until we can no longer jump on a
1006  // guile exception. In addition we cannot store a C++ exception
1007  // using std::exception_ptr because std::exception_ptr is not
1008  // trivially destructible.
1009  bool badalloc = false;
1010  const char* rv_error = 0;
1011  std::vector<long>* res = 0;
1012  VectorDeleteArgs* args = 0;
1013  try {
1014  // it doesn't matter if the second allocation fails, as we clean
1015  // up at the end if there is no guile exception, and if both
1016  // allocations succeed and there were to be a subsequent guile
1017  // exception, cgu_delete_vector cleans up
1018  res = new std::vector<long>;
1019  // allocate 'args' on free store, because the continuation in
1020  // which it executes will be up the stack
1021  args = new VectorDeleteArgs{Long, res};
1022  }
1023  catch (...) {
1024  badalloc = true;
1025  }
1026  if (!badalloc) {
1027  // there may be a weakness in guile's implementation here: if
1028  // calling scm_dynwind_unwind_handler() were to give rise to a
1029  // guile out-of-memory exception before the handler is set up by
1030  // it, then we could leak memory allocated from the preceding new
1031  // expressions. Whether that could happen is not documented by
1032  // guile, but because (a) it is so improbable, and (b) once we are
1033  // in out-of-memory land we are already in severe trouble and glib
1034  // is likely to terminate the program at some point anyway, it is
1035  // not worth troubling ourselves over.
1036  scm_dynwind_unwind_handler(&cgu_delete_vector, args, scm_t_wind_flags(0));
1037  // convert the list to a guile vector so we can access its items
1038  // efficiently in a for loop. This conversion is reasonably
1039  // efficient, in the sense that an ordinary guile vector is an
1040  // array of pointers, pointing to the same scheme objects that the
1041  // list refers to
1042  SCM guile_vec = scm_vector(scm);
1043 
1044  // std::vector::size_type is the same as size_t with the standard
1045  // allocators (but if we were to get a silent narrowing conversion
1046  // on calling std::vector::reserve() below, that doesn't matter -
1047  // instead if 'length' is less than SIZE_MAX but greater than the
1048  // maximum value of std::vector::size_type, at some point a call
1049  // to std::vector::push_back() below would throw and be caught,
1050  // and this function would end up rethrowing it as std::bad_alloc.
1051  // If in a particular implementation SIZE_MAX exceeds
1052  // std::vector::max_size(), a std::length_error exception would be
1053  // thrown by reserve() where max_size() is exceeded. On all
1054  // common implementations, max_size() is equal to SIZE_MAX, but
1055  // were such an exception to arise it would be swallowed (see
1056  // below) and then rethrown by this function as std::bad_alloc.
1057  // If 'length' is greater than SIZE_MAX, a guile out-of-range
1058  // exception would be thrown by scm_to_size_t() which would be
1059  // rethrown by Cgu:Extension::exec() or
1060  // Cgu::Exception::exec_shared as a Cgu::Extension::WrapperError
1061  // C++ exception. This is nice to know but in practice such large
1062  // lists would be unusably slow and a memory exception would be
1063  // reached long before std::vector::max_size() or SIZE_MAX are
1064  // exceeded.
1065  size_t length = scm_to_size_t(scm_vector_length(guile_vec));
1066  try {
1067  res->reserve(length);
1068  }
1069  catch (...) {
1070  badalloc = true;
1071  }
1072  for (size_t count = 0;
1073  count < length && !rv_error && !badalloc;
1074  ++count) {
1075  SCM item = scm_vector_ref(guile_vec, scm_from_size_t(count));
1076  if (scm_is_false(scm_integer_p(item)))
1077  rv_error = "scheme code did not evaluate to a homogeneous list of integer\n";
1078  else {
1079  SCM min = scm_from_long(std::numeric_limits<long>::min());
1080  SCM max = scm_from_long(std::numeric_limits<long>::max());
1081  if (scm_is_false(scm_leq_p(item, max)) || scm_is_false(scm_geq_p(item, min)))
1082  rv_error = "scheme code evaluated out of range for long\n";
1083  else {
1084  try {
1085  res->push_back(scm_to_long(item));
1086  }
1087  catch (...) {
1088  badalloc = true;
1089  }
1090  }
1091  }
1092  }
1093  }
1094  // all done - no more guile exceptions are possible in this function
1095  // after this so end the dynamic context, take control of the memory
1096  // by RAII and if necessary throw a C++ exception
1097  scm_dynwind_end();
1098  std::unique_ptr<std::vector<long>> up_res(res);
1099  std::unique_ptr<VectorDeleteArgs> up_args(args);
1100  if (badalloc) throw std::bad_alloc();
1101  if (rv_error) throw ReturnValueError(rv_error);
1102  // neither gcc-4.9 nor clang-3.4 will optimize with RVO or move
1103  // semantics here, so force it by hand
1104  return std::move(*res);
1105 }
1106 
1107 /**
1108  * A translator function which can be passed to the third argument of
1109  * Extension::exec() or Extension::exec_shared(). It converts from a
1110  * homogeneous scheme list of real numbers to a C++ representation of
1111  * std::vector<double>. It is thread safe, but see the comments above
1112  * about the thread safety of Extension::exec() and
1113  * Extension::exec_shared().
1114  *
1115  * @param scm An opaque guile SCM object representing the value to
1116  * which the extension file passed to Extension::exec() or
1117  * Extension::exec_shared() evaluated, where that value is a
1118  * homogeneous list of real numbers.
1119  * @return The std::vector<double> representation.
1120  * @exception std::bad_alloc This function might throw std::bad_alloc
1121  * if memory is exhausted and the system throws in that case, or if
1122  * the length of the input list exceeds std::vector::max_size().
1123  * @exception Cgu::Extension::GuileException This exception will be
1124  * thrown if the scheme code in the extension file passed to
1125  * Extension::exec() or Extension::exec_shared() caused a guile
1126  * exception to be thrown. Cgu::Extension::GuileException::what()
1127  * will give particulars of the guile exception thrown, in UTF-8
1128  * encoding.
1129  * @exception Cgu::Extension::ReturnValueError This exception will be
1130  * thrown if the scheme code in the extension file passed to
1131  * Extension::exec() or Extension::exec_shared() does not evaluate to
1132  * the type expected by the translator, or it is out of range for a
1133  * double.
1134  * @note 1. Prior to version 2.0.25, this translator had a bug which
1135  * caused an out-of-range Cgu::Extension::ReturnValueError to be
1136  * thrown if any of the numbers in the list to which the scheme code
1137  * in the extension file evaluated was 0.0 or a negative number. This
1138  * was fixed in version 2.0.25.
1139  * @note 2. No native guile exception will arise in this function and
1140  * so cause guile to jump out of it unless a guile out-of-memory
1141  * condition occurs (given that this function is called after a guile
1142  * extension task has completed, such a condition is very improbable)
1143  * or the length of the input list exceeds SIZE_MAX (the maximum value
1144  * of std::size_t). If such an exception were to arise, the
1145  * implementation would handle it and a C++ exception would be
1146  * generated in its place in Extension::exec() or
1147  * Extension::exec_shared().
1148  *
1149  * Since 2.0.22
1150  */
1151 inline std::vector<double> list_to_vector_double(SCM scm) {
1153  if (scm_is_false(scm_list_p(scm)))
1154  throw ReturnValueError("scheme code did not evaluate to a list\n");
1155 
1156  // nothing in this function should throw a guile exception unless
1157  // there is a guile out-of-memory exception (which is extremely
1158  // improbable). However, let's cover ourselves in case.
1159  scm_dynwind_begin(scm_t_dynwind_flags(0));
1160  // we cannot have a std::vector object in a scope where a guile
1161  // exception might be raised because it has a non-trivial
1162  // destructor, nor can we use RAII. Instead allocate on free store
1163  // and manage the memory by hand until we can no longer jump on a
1164  // guile exception. In addition we cannot store a C++ exception
1165  // using std::exception_ptr because std::exception_ptr is not
1166  // trivially destructible.
1167  bool badalloc = false;
1168  const char* rv_error = 0;
1169  std::vector<double>* res = 0;
1170  VectorDeleteArgs* args = 0;
1171  try {
1172  // it doesn't matter if the second allocation fails, as we clean
1173  // up at the end if there is no guile exception, and if both
1174  // allocations succeed and there were to be a subsequent guile
1175  // exception, cgu_delete_vector cleans up
1176  res = new std::vector<double>;
1177  // allocate 'args' on free store, because the continuation in
1178  // which it executes will be up the stack
1179  args = new VectorDeleteArgs{Double, res};
1180  }
1181  catch (...) {
1182  badalloc = true;
1183  }
1184  if (!badalloc) {
1185  // there may be a weakness in guile's implementation here: if
1186  // calling scm_dynwind_unwind_handler() were to give rise to a
1187  // guile out-of-memory exception before the handler is set up by
1188  // it, then we could leak memory allocated from the preceding
1189  // new expressions. Whether that could happen is not documented
1190  // by guile, but because (a) it is so improbable, and (b) once
1191  // we are in out-of-memory land we are already in severe trouble
1192  // and glib is likely to terminate the program at some point
1193  // anyway, it is not worth troubling ourselves over.
1194  scm_dynwind_unwind_handler(&cgu_delete_vector, args, scm_t_wind_flags(0));
1195  // convert the list to a guile vector so we can access its items
1196  // efficiently in a for loop. This conversion is reasonably
1197  // efficient, in the sense that an ordinary guile vector is an
1198  // array of pointers, pointing to the same scheme objects that the
1199  // list refers to
1200  SCM guile_vec = scm_vector(scm);
1201 
1202  // std::vector::size_type is the same as size_t with the standard
1203  // allocators (but if we were to get a silent narrowing conversion
1204  // on calling std::vector::reserve() below, that doesn't matter -
1205  // instead if 'length' is less than SIZE_MAX but greater than the
1206  // maximum value of std::vector::size_type, at some point a call
1207  // to std::vector::push_back() below would throw and be caught,
1208  // and this function would end up rethrowing it as std::bad_alloc.
1209  // If in a particular implementation SIZE_MAX exceeds
1210  // std::vector::max_size(), a std::length_error exception would be
1211  // thrown by reserve() where max_size() is exceeded. On all
1212  // common implementations, max_size() is equal to SIZE_MAX, but
1213  // were such an exception to arise it would be swallowed (see
1214  // below) and then rethrown by this function as std::bad_alloc.
1215  // If 'length' is greater than SIZE_MAX, a guile out-of-range
1216  // exception would be thrown by scm_to_size_t() which would be
1217  // rethrown by Cgu:Extension::exec() or
1218  // Cgu::Exception::exec_shared as a Cgu::Extension::WrapperError
1219  // C++ exception. This is nice to know but in practice such large
1220  // lists would be unusably slow and a memory exception would be
1221  // reached long before std::vector::max_size() or SIZE_MAX are
1222  // exceeded.
1223  size_t length = scm_to_size_t(scm_vector_length(guile_vec));
1224  try {
1225  res->reserve(length);
1226  }
1227  catch (...) {
1228  badalloc = true;
1229  }
1230  for (size_t count = 0;
1231  count < length && !rv_error && !badalloc;
1232  ++count) {
1233  SCM item = scm_vector_ref(guile_vec, scm_from_size_t(count));
1234  if (scm_is_false(scm_real_p(item)))
1235  rv_error = "scheme code did not evaluate to a homogeneous list of real numbers\n";
1236  else {
1237  SCM min = scm_from_double(-std::numeric_limits<double>::max());
1238  SCM max = scm_from_double(std::numeric_limits<double>::max());
1239  if (scm_is_false(scm_leq_p(item, max)) || scm_is_false(scm_geq_p(item, min)))
1240  rv_error = "scheme code evaluated out of range for double\n";
1241  else {
1242  try {
1243  res->push_back(scm_to_double(item));
1244  }
1245  catch (...) {
1246  badalloc = true;
1247  }
1248  }
1249  }
1250  }
1251  }
1252  // all done - no more guile exceptions are possible in this function
1253  // after this so end the dynamic context, take control of the memory
1254  // by RAII and if necessary throw a C++ exception
1255  scm_dynwind_end();
1256  std::unique_ptr<std::vector<double>> up_res(res);
1257  std::unique_ptr<VectorDeleteArgs> up_args(args);
1258  if (badalloc) throw std::bad_alloc();
1259  if (rv_error) throw ReturnValueError(rv_error);
1260  // neither gcc-4.9 nor clang-3.4 will optimize with RVO or move
1261  // semantics here, so force it by hand
1262  return std::move(*res);
1263 }
1264 
1265 /**
1266  * A translator function which can be passed to the third argument of
1267  * Extension::exec() or Extension::exec_shared(). It converts from a
1268  * homogeneous scheme list of strings to a C++ representation of
1269  * std::vector<std::string>. It is thread safe, but see the comments
1270  * above about the thread safety of Extension::exec() and
1271  * Extension::exec_shared().
1272  *
1273  * The returned strings will be in UTF-8 encoding.
1274  *
1275  * Note that the first string in the returned list must not be
1276  * "***cgu-guile-exception***": that string is reserved to the
1277  * implementation.
1278  *
1279  * @param scm An opaque guile SCM object representing the value to
1280  * which the extension file passed to Extension::exec() or
1281  * Extension::exec_shared() evaluated, where that value is a
1282  * homogeneous list of strings.
1283  * @return The std::vector<std::string> representation.
1284  * @exception std::bad_alloc This function might throw std::bad_alloc
1285  * if memory is exhausted and the system throws in that case, or if
1286  * the length of the input list exceeds std::vector::max_size().
1287  * @exception Cgu::Extension::GuileException This exception will be
1288  * thrown if the scheme code in the extension file passed to
1289  * Extension::exec() or Extension::exec_shared() caused a guile
1290  * exception to be thrown. Cgu::Extension::GuileException::what()
1291  * will give particulars of the guile exception thrown, in UTF-8
1292  * encoding.
1293  * @exception Cgu::Extension::ReturnValueError This exception will be
1294  * thrown if the scheme code in the extension file passed to
1295  * Extension::exec() or Extension::exec_shared() does not evaluate to
1296  * the type expected by the translator.
1297  * @note No native guile exception will arise in this function and so
1298  * cause guile to jump out of it unless a guile out-of-memory
1299  * condition occurs (given that this function is called after a guile
1300  * extension task has completed, such a condition is very improbable)
1301  * or the length of the input list exceeds SIZE_MAX (the maximum value
1302  * of std::size_t). If such an exception were to arise, the
1303  * implementation would handle it and a C++ exception would be
1304  * generated in its place in Extension::exec() or
1305  * Extension::exec_shared().
1306  *
1307  * Since 2.0.22
1308  */
1309 inline std::vector<std::string> list_to_vector_string(SCM scm) {
1311  if (scm_is_false(scm_list_p(scm)))
1312  throw ReturnValueError("scheme code did not evaluate to a list\n");
1313 
1314  // nothing in this function should throw a guile exception unless
1315  // there is a guile out-of-memory exception (which is extremely
1316  // improbable). However, let's cover ourselves in case.
1317  scm_dynwind_begin(scm_t_dynwind_flags(0));
1318  // we cannot have a std::vector object in a scope where a guile
1319  // exception might be raised because it has a non-trivial
1320  // destructor, nor can we use RAII. Instead allocate on free store
1321  // and manage the memory by hand until we can no longer jump on a
1322  // guile exception. In addition we cannot store a C++ exception
1323  // using std::exception_ptr because std::exception_ptr is not
1324  // trivially destructible.
1325  bool badalloc = false;
1326  const char* rv_error = 0;
1327  std::vector<std::string>* res = 0;
1328  VectorDeleteArgs* args = 0;
1329  try {
1330  // it doesn't matter if the second allocation fails, as we clean
1331  // up at the end if there is no guile exception, and if both
1332  // allocations succeed and there were to be a subsequent guile
1333  // exception, cgu_delete_vector cleans up
1334  res = new std::vector<std::string>;
1335  // allocate 'args' on free store, because the continuation in
1336  // which it executes will be up the stack
1337  args = new VectorDeleteArgs{String, res};
1338  }
1339  catch (...) {
1340  badalloc = true;
1341  }
1342  if (!badalloc) {
1343  // there may be a weakness in guile's implementation here: if
1344  // calling scm_dynwind_unwind_handler() were to give rise to a
1345  // guile out-of-memory exception before the handler is set up by
1346  // it, then we could leak memory allocated from the preceding new
1347  // expressions. Whether that could happen is not documented by
1348  // guile, but because (a) it is so improbable, and (b) once we are
1349  // in out-of-memory land we are already in severe trouble and glib
1350  // is likely to terminate the program at some point anyway, it is
1351  // not worth troubling ourselves over.
1352  scm_dynwind_unwind_handler(&cgu_delete_vector, args, scm_t_wind_flags(0));
1353  // convert the list to a guile vector so we can access its items
1354  // efficiently in a for loop. This conversion is reasonably
1355  // efficient, in the sense that an ordinary guile vector is an
1356  // array of pointers, pointing to the same scheme objects that the
1357  // list refers to
1358  SCM guile_vec = scm_vector(scm);
1359 
1360  // std::vector::size_type is the same as size_t with the standard
1361  // allocators (but if we were to get a silent narrowing conversion
1362  // on calling std::vector::reserve() below, that doesn't matter -
1363  // instead if 'length' is less than SIZE_MAX but greater than the
1364  // maximum value of std::vector::size_type, at some point a call
1365  // to std::vector::emplace_back() below would throw and be caught,
1366  // and this function would end up rethrowing it as std::bad_alloc.
1367  // If in a particular implementation SIZE_MAX exceeds
1368  // std::vector::max_size(), a std::length_error exception would be
1369  // thrown by reserve() where max_size() is exceeded. On all
1370  // common implementations, max_size() is equal to SIZE_MAX, but
1371  // were such an exception to arise it would be swallowed (see
1372  // below) and then rethrown by this function as std::bad_alloc.
1373  // If 'length' is greater than SIZE_MAX, a guile out-of-range
1374  // exception would be thrown by scm_to_size_t() which would be
1375  // rethrown by Cgu:Extension::exec() or
1376  // Cgu::Exception::exec_shared as a Cgu::Extension::WrapperError
1377  // C++ exception. This is nice to know but in practice such large
1378  // lists would be unusably slow and a memory exception would be
1379  // reached long before std::vector::max_size() or SIZE_MAX are
1380  // exceeded.
1381  size_t length = scm_to_size_t(scm_vector_length(guile_vec));
1382  try {
1383  res->reserve(length);
1384  }
1385  catch (...) {
1386  badalloc = true;
1387  }
1388  for (size_t count = 0;
1389  count < length && !rv_error && !badalloc;
1390  ++count) {
1391  SCM item = scm_vector_ref(guile_vec, scm_from_size_t(count));
1392  if (scm_is_false(scm_string_p(item)))
1393  rv_error = "scheme code did not evaluate to a homogeneous list of string\n";
1394  else {
1395  size_t len;
1396  // we don't need a dynwind handler for 'str' because nothing
1397  // after the call to scm_to_utf8_stringn() and before the call
1398  // to free() can cause a guile exception to be raised
1399  char* str = scm_to_utf8_stringn(item, &len);
1400  try {
1401  res->emplace_back(str, len);
1402  }
1403  catch (...) {
1404  badalloc = true;
1405  }
1406  free(str);
1407  }
1408  }
1409  }
1410  // all done - no more guile exceptions are possible in this function
1411  // after this so end the dynamic context, take control of the memory
1412  // by RAII and if necessary throw a C++ exception
1413  scm_dynwind_end();
1414  std::unique_ptr<std::vector<std::string>> up_res(res);
1415  std::unique_ptr<VectorDeleteArgs> up_args(args);
1416  if (badalloc) throw std::bad_alloc();
1417  if (rv_error) throw ReturnValueError(rv_error);
1418  // neither gcc-4.9 nor clang-3.4 will optimize with RVO or move
1419  // semantics here, so force it by hand
1420  return std::move(*res);
1421 }
1422 
1423 /**
1424  * A translator function which can be passed to the third argument of
1425  * Extension::exec() or Extension::exec_shared(). It converts from a
1426  * scheme integer to a C++ representation of long. It is thread safe,
1427  * but see the comments above about the thread safety of
1428  * Extension::exec() and Extension::exec_shared().
1429  *
1430  * @param scm An opaque guile SCM object representing the value to
1431  * which the extension file passed to Extension::exec() or
1432  * Extension::exec_shared() evaluated, where that value is an integer.
1433  * @return The C++ long representation.
1434  * @exception std::bad_alloc This function might throw std::bad_alloc
1435  * if memory is exhausted and the system throws in that case.
1436  * @exception Cgu::Extension::GuileException This exception will be
1437  * thrown if the scheme code in the extension file passed to
1438  * Extension::exec() or Extension::exec_shared() caused a guile
1439  * exception to be thrown. Cgu::Extension::GuileException::what()
1440  * will give particulars of the guile exception thrown, in UTF-8
1441  * encoding.
1442  * @exception Cgu::Extension::ReturnValueError This exception will be
1443  * thrown if the scheme code in the extension file passed to
1444  * Extension::exec() or Extension::exec_shared() does not evaluate to
1445  * the type expected by the translator, or it is out of range for a
1446  * long.
1447  * @note No native guile exception will arise in this function and so
1448  * cause guile to jump out of it if no guile out-of-memory condition
1449  * occurs (given that this function is called after a guile extension
1450  * task has completed, such a condition is very improbable). If such
1451  * an exception were to arise, the implementation would handle it and
1452  * a C++ exception would be generated in its place in
1453  * Extension::exec() or Extension::exec_shared().
1454  *
1455  * Since 2.0.22
1456  */
1457 inline long integer_to_long(SCM scm) {
1459  if (scm_is_false(scm_integer_p(scm)))
1460  throw ReturnValueError("scheme code did not evaluate to an integer\n");
1461  SCM min = scm_from_long(std::numeric_limits<long>::min());
1462  SCM max = scm_from_long(std::numeric_limits<long>::max());
1463  if (scm_is_false(scm_leq_p(scm, max)) || scm_is_false(scm_geq_p(scm, min)))
1464  throw ReturnValueError("scheme code evaluated out of range for long\n");
1465  return scm_to_long(scm);
1466 }
1467 
1468 /**
1469  * A translator function which can be passed to the third argument of
1470  * Extension::exec() or Extension::exec_shared(). It converts from a
1471  * scheme real number to a C++ representation of double. It is thread
1472  * safe, but see the comments above about the thread safety of
1473  * Extension::exec() and Extension::exec_shared().
1474  *
1475  * @param scm An opaque guile SCM object representing the value to
1476  * which the extension file passed to Extension::exec() or
1477  * Extension::exec_shared() evaluated, where that value is a real
1478  * number.
1479  * @return The C++ double representation.
1480  * @exception std::bad_alloc This function might throw std::bad_alloc
1481  * if memory is exhausted and the system throws in that case.
1482  * @exception Cgu::Extension::GuileException This exception will be
1483  * thrown if the scheme code in the extension file passed to
1484  * Extension::exec() or Extension::exec_shared() caused a guile
1485  * exception to be thrown. Cgu::Extension::GuileException::what()
1486  * will give particulars of the guile exception thrown, in UTF-8
1487  * encoding.
1488  * @exception Cgu::Extension::ReturnValueError This exception will be
1489  * thrown if the scheme code in the extension file passed to
1490  * Extension::exec() or Extension::exec_shared() does not evaluate to
1491  * the type expected by the translator, or it is out of range for a
1492  * double.
1493  * @note 1. Prior to version 2.0.25, this translator had a bug which
1494  * caused an out-of-range Cgu::Extension::ReturnValueError to be
1495  * thrown if the scheme code in the extension file evaluated to 0.0 or
1496  * a negative number. This was fixed in version 2.0.25.
1497  * @note 2. No native guile exception will arise in this function and
1498  * so cause guile to jump out of it if no guile out-of-memory
1499  * condition occurs (given that this function is called after a guile
1500  * extension task has completed, such a condition is very improbable).
1501  * If such an exception were to arise, the implementation would handle
1502  * it and a C++ exception would be generated in its place in
1503  * Extension::exec() or Extension::exec_shared().
1504  *
1505  * Since 2.0.22
1506  */
1507 inline double real_to_double(SCM scm) {
1509  if (scm_is_false(scm_real_p(scm)))
1510  throw ReturnValueError("scheme code did not evaluate to a real number\n");
1511  SCM min = scm_from_double(-std::numeric_limits<double>::max());
1512  SCM max = scm_from_double(std::numeric_limits<double>::max());
1513  if (scm_is_false(scm_leq_p(scm, max)) || scm_is_false(scm_geq_p(scm, min)))
1514  throw ReturnValueError("scheme code evaluated out of range for double\n");
1515  return scm_to_double(scm);
1516 }
1517 
1518 /**
1519  * A translator function which can be passed to the third argument of
1520  * Extension::exec() or Extension::exec_shared(). It converts from a
1521  * scheme string to a C++ representation of std::string. It is thread
1522  * safe, but see the comments above about the thread safety of
1523  * Extension::exec() and Extension::exec_shared().
1524  *
1525  * The returned string will be in UTF-8 encoding.
1526  *
1527  * @param scm An opaque guile SCM object representing the value to
1528  * which the extension file passed to Extension::exec() or
1529  * Extension::exec_shared() evaluated, where that value is a string.
1530  * @return The std::string representation.
1531  * @exception std::bad_alloc This function might throw std::bad_alloc
1532  * if memory is exhausted and the system throws in that case.
1533  * @exception Cgu::Extension::GuileException This exception will be
1534  * thrown if the scheme code in the extension file passed to
1535  * Extension::exec() or Extension::exec_shared() caused a guile
1536  * exception to be thrown. Cgu::Extension::GuileException::what()
1537  * will give particulars of the guile exception thrown, in UTF-8
1538  * encoding.
1539  * @exception Cgu::Extension::ReturnValueError This exception will be
1540  * thrown if the scheme code in the extension file passed to
1541  * Extension::exec() or Extension::exec_shared() does not evaluate to
1542  * the type expected by the translator.
1543  * @note No native guile exception will arise in this function and so
1544  * cause guile to jump out of it if no guile out-of-memory condition
1545  * occurs (given that this function is called after a guile extension
1546  * task has completed, such a condition is very improbable). If such
1547  * an exception were to arise, the implementation would handle it and
1548  * a C++ exception would be generated in its place in
1549  * Extension::exec() or Extension::exec_shared().
1550  *
1551  * Since 2.0.22
1552  */
1553 inline std::string string_to_string(SCM scm) {
1555  if (scm_is_false(scm_string_p(scm)))
1556  throw ReturnValueError("scheme code did not evaluate to a string\n");
1557  size_t len;
1558  // it is safe to use unique_ptr here. If scm_to_utf8_stringn()
1559  // succeeds then nothing after it in this function can cause a guile
1560  // exception.
1561  std::unique_ptr<const char, Cgu::CFree> s(scm_to_utf8_stringn(scm, &len));
1562  return std::string(s.get(), len);
1563 }
1564 
1565 /**
1566  * A translator function which can be passed to the third argument of
1567  * Extension::exec() or Extension::exec_shared(). It disregards the
1568  * scheme value passed to it except to trap any guile exception thrown
1569  * by the scheme task and rethrow it as a C++ exception, and returns a
1570  * NULL void* object. It is thread safe, but see the comments above
1571  * about the thread safety of Extension::exec() and
1572  * Extension::exec_shared().
1573  *
1574  * It is mainly intended for use where the scheme script is executed
1575  * for its side effects, perhaps for I/O, and any communication
1576  * necessary is done by guile exceptions.
1577  *
1578  * @param scm An opaque guile SCM object representing the value to
1579  * which the extension file passed to Extension::exec() or
1580  * Extension::exec_shared() evaluated, which is ignored.
1581  * @return A NULL void* object.
1582  * @exception std::bad_alloc This function might throw std::bad_alloc
1583  * if memory is exhausted and the system throws in that case.
1584  * @exception Cgu::Extension::GuileException This exception will be
1585  * thrown if the scheme code in the extension file passed to
1586  * Extension::exec() or Extension::exec_shared() caused a guile
1587  * exception to be thrown. Cgu::Extension::GuileException::what()
1588  * will give particulars of the guile exception thrown, in UTF-8
1589  * encoding.
1590  * @note No native guile exception will arise in this function and so
1591  * cause guile to jump out of it if no guile out-of-memory condition
1592  * occurs (given that this function is called after a guile extension
1593  * task has completed, such a condition is very improbable). If such
1594  * an exception were to arise, the implementation would handle it and
1595  * a C++ exception would be generated in its place in
1596  * Extension::exec() or Extension::exec_shared().
1597  *
1598  * Since 2.0.22
1599  */
1600 inline void* any_to_void(SCM scm) {
1602  return 0;
1603 }
1604 
1605 /**
1606  * This function executes scheme code on the guile VM within a C++
1607  * program using this library. See the introductory remarks above for
1608  * its potential uses, about the thread safety of this function, and
1609  * about the use of the TaskManager::exec_shared() as an alternative.
1610  *
1611  * The first argument to this function is a preamble, which can be
1612  * used to pass top level definitions to the scheme code (in other
1613  * words, for argument passing). It's second argument is the filename
1614  * (with path) of the file containing the scheme code to be executed.
1615  * It's third argument is a translator, which will convert the value
1616  * to which the scheme code evaluates (in C++ terms, its return value)
1617  * to a suitable C++ representation. Preformed translators are
1618  * provided by this library to translate from scheme's integers, real
1619  * numbers and strings to C++ longs, doubles and strings respectively,
1620  * and from any uniform lists of these to C++ vectors of the
1621  * corresponding type. There is also a translator for void return
1622  * types. See the introductory remarks above for more information
1623  * about translators.
1624  *
1625  * Any native guile exceptions thrown by the code executed by this
1626  * function (and by any code which it calls) are converted and
1627  * rethrown as C++ exceptions.
1628  *
1629  * The scheme file can call other scheme code, and load modules, in
1630  * the ordinary way. Thus, this function can execute any scheme code
1631  * which guile can execute as a program, and the programmer can (if
1632  * wanted) act on its return value in the C++ code which invokes it.
1633  *
1634  * Thread cancellation is blocked for the thread in which this
1635  * function executes until this function returns.
1636  *
1637  * @param preamble Scheme code such as top level definitions to be
1638  * seen by the code in the file to be executed. This is mainly
1639  * intended for argument passing, but can comprise any valid scheme
1640  * code. It can also be empty (you can pass ""). Any string literals
1641  * must be in UTF-8 encoding.
1642  * @param file The file which is to be executed on the guile VM. This
1643  * should include the full pathname or a pathname relative to the
1644  * current directory. The contents of the file, and in particular any
1645  * string literals in it, must be in UTF-8 encoding. The filename and
1646  * path must also be given in UTF-8 encoding, even if the local
1647  * filename encoding is something different: guile will convert the
1648  * UTF-8 name which it is given to its own internal string encoding
1649  * using unicode code points, and then convert that to locale encoding
1650  * on looking up the filename. However sticking to ASCII for
1651  * filenames and paths (which is always valid UTF-8) will maximise
1652  * portability. The file name can be empty (you can pass ""), in
1653  * which case only the preamble will be evaluated (but for efficiency
1654  * reasons any complex code not at the top level should be included in
1655  * the file rather than in the preamble).
1656  * @param translator The function or callable object which will
1657  * convert the value to which the scheme code evaluates to a C++
1658  * representation which will be returned by this function. The
1659  * translator should take a single argument comprising an opaque guile
1660  * object of type SCM, and return the C++ representation for it.
1661  * @return The C++ representation returned by the translator.
1662  * @exception std::bad_alloc This function might throw std::bad_alloc
1663  * if memory is exhausted and the system throws in that case.
1664  * @exception Cgu::Extension::GuileException This exception will be
1665  * thrown if the scheme code in 'file' (or called by it) throws a
1666  * guile exception. Cgu::Extension::GuileException::what() will give
1667  * particulars of the guile exception thrown, in UTF-8 encoding.
1668  * @exception Cgu::Extension::ReturnValueError This exception will be
1669  * thrown if the code in 'file' does not evaluate to the type expected
1670  * by the translator.
1671  * @exception Cgu::Extension::WrapperError This exception will be
1672  * thrown if a custom translator throws a native guile exception or a
1673  * C++ exception not comprising Extension::GuileException or
1674  * Extension::ReturnValueError, one of the preformed translators
1675  * throws std::bad_alloc or encounters a guile out-of-memory
1676  * exception, one of the preformed list translators encounters an
1677  * input list exceeding SIZE_MAX in length, assigning to an internal
1678  * exception description string throws std::bad_alloc, or evaluation
1679  * of the preamble throws a native guile exception.
1680  *
1681  * Since 2.0.22
1682  */
1683 // we cannot take 'translator' by collapsible reference, because with
1684 // gcc-4.4 std::result_of fails if Translator deduces to a reference
1685 // type, and gcc-4.4 does not have std::declval. This is fixed in the
1686 // 2.2 series of this library, which has a minimum requirement of
1687 // gcc-4.6.
1688 template <class Translator>
1689 auto exec(const std::string& preamble,
1690  const std::string& file,
1691  Translator translator) -> typename std::result_of<Translator(SCM)>::type {
1692  // exec_impl() will fail to compile if Ret is a reference type: that
1693  // is a feature, not a bug, as there is no good reason for a
1694  // translator ever to return a reference
1695  typedef typename std::result_of<Translator(SCM)>::type Ret;
1696  return exec_impl<Ret>(preamble, file, translator, false);
1697 }
1698 
1699 /**
1700  * This function executes scheme code on the guile VM within a C++
1701  * program using this library. See the introductory remarks above for
1702  * its potential uses, about the thread safety of this function, and
1703  * about the use of the TaskManager::exec() as an alternative.
1704  *
1705  * The first argument to this function is a preamble, which can be
1706  * used to pass top level definitions to the scheme code (in other
1707  * words, for argument passing). It's second argument is the filename
1708  * (with path) of the file containing the scheme code to be executed.
1709  * It's third argument is a translator, which will convert the value
1710  * to which the scheme code evaluates (in C++ terms, its return value)
1711  * to a suitable C++ representation. Preformed translators are
1712  * provided by this library to translate from scheme's integers, real
1713  * numbers and strings to C++ longs, doubles and strings respectively,
1714  * and from any uniform lists of these to C++ vectors of the
1715  * corresponding type. There is also a translator for void return
1716  * types. See the introductory remarks above for more information
1717  * about translators.
1718  *
1719  * Any native guile exceptions thrown by the code executed by this
1720  * function (and by any code which it calls) are converted and
1721  * rethrown as C++ exceptions.
1722  *
1723  * The scheme file can call other scheme code, and load modules, in
1724  * the ordinary way. Thus, this function can execute any scheme code
1725  * which guile can execute as a program, and the programmer can (if
1726  * wanted) act on its return value in the C++ code which invokes it.
1727  *
1728  * Thread cancellation is blocked for the thread in which this
1729  * function executes until this function returns.
1730  *
1731  * @param preamble Scheme code such as top level definitions to be
1732  * seen by the code in the file to be executed. This is mainly
1733  * intended for argument passing, but can comprise any valid scheme
1734  * code. It can also be empty (you can pass ""). Any string literals
1735  * must be in UTF-8 encoding.
1736  * @param file The file which is to be executed on the guile VM. This
1737  * should include the full pathname or a pathname relative to the
1738  * current directory. The contents of the file, and in particular any
1739  * string literals in it, must be in UTF-8 encoding. The filename and
1740  * path must also be given in UTF-8 encoding, even if the local
1741  * filename encoding is something different: guile will convert the
1742  * UTF-8 name which it is given to its own internal string encoding
1743  * using unicode code points, and then convert that to locale encoding
1744  * on looking up the filename. However sticking to ASCII for
1745  * filenames and paths (which is always valid UTF-8) will maximise
1746  * portability. The file name can be empty (you can pass ""), in
1747  * which case only the preamble will be evaluated.
1748  * @param translator The function or callable object which will
1749  * convert the value to which the scheme code evaluates to a C++
1750  * representation which will be returned by this function. The
1751  * translator should take a single argument comprising an opaque guile
1752  * object of type SCM, and return the C++ representation for it.
1753  * @return The C++ representation returned by the translator.
1754  * @exception std::bad_alloc This function might throw std::bad_alloc
1755  * if memory is exhausted and the system throws in that case.
1756  * @exception Cgu::Extension::GuileException This exception will be
1757  * thrown if the scheme code in 'file' (or called by it) throws a
1758  * guile exception. Cgu::Extension::GuileException::what() will give
1759  * particulars of the guile exception thrown, in UTF-8 encoding.
1760  * @exception Cgu::Extension::ReturnValueError This exception will be
1761  * thrown if the code in 'file' does not evaluate to the type expected
1762  * by the translator.
1763  * @exception Cgu::Extension::WrapperError This exception will be
1764  * thrown if a custom translator throws a native guile exception or a
1765  * C++ exception not comprising Extension::GuileException or
1766  * Extension::ReturnValueError, one of the preformed translators
1767  * throws std::bad_alloc or encounters a guile out-of-memory
1768  * exception, one of the preformed list translators encounters an
1769  * input list exceeding SIZE_MAX in length, assigning to an internal
1770  * exception description string throws std::bad_alloc, or evaluation
1771  * of the preamble throws a native guile exception.
1772  *
1773  * Since 2.0.24
1774  */
1775 // we cannot take 'translator' by collapsible reference, because with
1776 // gcc-4.4 std::result_of fails if Translator deduces to a reference
1777 // type, and gcc-4.4 does not have std::declval. This is fixed in the
1778 // 2.2 series of this library, which has a minimum requirement of
1779 // gcc-4.6.
1780 template <class Translator>
1781 auto exec_shared(const std::string& preamble,
1782  const std::string& file,
1783  Translator translator) -> typename std::result_of<Translator(SCM)>::type {
1784  // exec_impl() will fail to compile if Ret is a reference type: that
1785  // is a feature, not a bug, as there is no good reason for a
1786  // translator ever to return a reference
1787  typedef typename std::result_of<Translator(SCM)>::type Ret;
1788  return exec_impl<Ret>(preamble, file, translator, true);
1789 }
1790 
1791 } // namespace Extension
1792 
1793 } // namespace Cgu
1794 
1795 #endif // CGU_EXTENSION_H
std::vector< long > list_to_vector_long(SCM scm)
Definition: extension.h:993
GuileException(const char *msg)
Definition: extension.h:574
long integer_to_long(SCM scm)
Definition: extension.h:1457
~ReturnValueError()
Definition: extension.h:589
~GuileException()
Definition: extension.h:577
const char * err_text() const
Definition: extension.h:585
void * any_to_void(SCM scm)
Definition: extension.h:1600
auto exec(const std::string &preamble, const std::string &file, Translator translator) -> typename std::result_of< Translator(SCM)>::type
Definition: extension.h:1689
WrapperError(const char *msg)
Definition: extension.h:596
This file provides classes for type erasure.
Definition: extension.h:580
A class enabling the cancellation state of a thread to be controlled.
Definition: thread.h:686
double real_to_double(SCM scm)
Definition: extension.h:1507
Definition: extension.h:568
std::string string_to_string(SCM scm)
Definition: extension.h:1553
std::vector< double > list_to_vector_double(SCM scm)
Definition: extension.h:1151
auto exec_shared(const std::string &preamble, const std::string &file, Translator translator) -> typename std::result_of< Translator(SCM)>::type
Definition: extension.h:1781
virtual const char * what() const
Definition: extension.h:595
T get() const
Definition: shared_handle.h:762
A wrapper class for pthread mutexes.
Definition: mutex.h:117
Provides wrapper classes for pthread mutexes and condition variables, and scoped locking classes for ...
Definition: application.h:44
SCM exception_to_string(SCM key, SCM args)
Definition: extension.h:825
std::vector< std::string > list_to_vector_string(SCM scm)
Definition: extension.h:1309
Definition: extension.h:592
virtual const char * what() const
Definition: extension.h:584
~WrapperError()
Definition: extension.h:598
virtual const char * what() const
Definition: extension.h:572
void rethrow_guile_exception(SCM scm)
Definition: extension.h:911
ReturnValueError(const char *msg)
Definition: extension.h:586
The callback interface class.
Definition: callback.h:522
const char * guile_text() const
Definition: extension.h:573