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