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