c++-gtk-utils
extension.h
Go to the documentation of this file.
1 /* Copyright (C) 2014 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>
447 
448 #include <libguile.h>
449 
450 
451 #ifndef DOXYGEN_PARSING
452 namespace Cgu {
453 
454 namespace Extension {
455 
456 struct FormatArgs {
457  SCM text;
458  SCM rest;
459 };
460 
461 enum VectorDeleteType {Long, Double, String};
462 
463 struct VectorDeleteArgs {
464  VectorDeleteType type;
465  void* vec;
466 };
467 
468 } // namespace Extension
469 
470 } // namespace Cgu
471 
472 namespace {
473 extern "C" {
474  inline SCM cgu_format_try_handler(void* data) {
475  using Cgu::Extension::FormatArgs;
476  FormatArgs* format_args = static_cast<FormatArgs*>(data);
477  return scm_simple_format(SCM_BOOL_F, format_args->text, format_args->rest);
478  }
479  inline SCM cgu_format_catch_handler(void*, SCM, SCM) {
480  return SCM_BOOL_F;
481  }
482  inline void* cgu_guile_wrapper(void* data) {
483  try {
484  static_cast<Cgu::Callback::Callback*>(data)->dispatch();
485  }
486  // an elipsis catch block is fine as thread cancellation is
487  // blocked. We can only enter this block if assigning to one of
488  // the exception strings in the callback has thrown
489  // std::bad_alloc. For that case we return a non-NULL pointer to
490  // indicate error (the 'data' argument is convenient and
491  // guaranteed to be standard-conforming for this).
492  catch (...) {
493  return data;
494  }
495  return 0;
496  }
497  inline void cgu_delete_vector(void* data) {
498  using Cgu::Extension::VectorDeleteArgs;
499  VectorDeleteArgs* args = static_cast<VectorDeleteArgs*>(data);
500  switch (args->type) {
501  case Cgu::Extension::Long:
502  delete static_cast<std::vector<long>*>(args->vec);
503  break;
504  case Cgu::Extension::Double:
505  delete static_cast<std::vector<double>*>(args->vec);
506  break;
507  case Cgu::Extension::String:
508  delete static_cast<std::vector<std::string>*>(args->vec);
509  break;
510  default:
511  g_critical("Incorrect argument passed to cgu_delete_vector");
512  }
513  delete args;
514  }
515 } // extern "C"
516 } // unnamed namespace
517 #endif // DOXYGEN_PARSING
518 
519 namespace Cgu {
520 
521 namespace Extension {
522 
523 class GuileException: public std::exception {
524  Cgu::GcharSharedHandle message;
525  Cgu::GcharSharedHandle guile_message;
526 public:
527  virtual const char* what() const throw() {return (const char*)message.get();}
528  const char* guile_text() const throw() {return (const char*)guile_message.get();}
529  GuileException(const char* msg):
530  message(g_strdup_printf("Cgu::Extension::GuileException: %s", msg)),
531  guile_message(g_strdup(msg)) {}
532  ~GuileException() throw() {}
533 };
534 
535 class ReturnValueError: public std::exception {
536  Cgu::GcharSharedHandle message;
537  Cgu::GcharSharedHandle err_message;
538 public:
539  virtual const char* what() const throw() {return (const char*)message.get();}
540  const char* err_text() const throw() {return (const char*)err_message.get();}
541  ReturnValueError(const char* msg):
542  message(g_strdup_printf("Cgu::Extension::ReturnValueError: %s", msg)),
543  err_message(g_strdup(msg)) {}
544  ~ReturnValueError() throw() {}
545 };
546 
547 class WrapperError: public std::exception {
548  Cgu::GcharSharedHandle message;
549 public:
550  virtual const char* what() const throw() {return (const char*)message.get();}
551  WrapperError(const char* msg):
552  message(g_strdup_printf("Cgu::Extension::WrapperError: %s", msg)) {}
553  ~WrapperError() throw() {}
554 };
555 
556 #ifndef DOXYGEN_PARSING
557 template <class Ret, class TransType>
558 void guile_wrapper_cb(TransType* translator,
559  std::string* loader,
560  Ret* retval,
561  bool* result,
562  std::string* guile_except,
563  std::string* guile_ret_val_err,
564  std::string* gen_err) {
565  SCM scm = scm_eval_string(scm_from_utf8_string(loader->c_str()));
566 
567  // have a dynwind context and async block while translator is
568  // executing. This is to cater for the pathological case of the
569  // scheme script having set up a signal handler which might throw a
570  // guile exception, or having chained a series of system asyncs
571  // which are still queued for action, which might otherwise cause
572  // the translator to trigger a guile exception while a non-trivially
573  // destructible object is in the local scope of translator. (Highly
574  // unlikely, but easy to deal with.) This is entirely safe as no
575  // C++ exception arising from the translator can transit across the
576  // dynamic context in this function - see below. So we have (i) no
577  // C++ exception can transit across a guile dynamic context, and
578  // (ii) no guile exception can escape out of a local C++ scope by
579  // virtue of an async executing (it might still escape with a
580  // non-trivially destructible object in existence if a custom
581  // translator has not been written correctly, but there is nothing
582  // we can do about that). Note that some guile installations do not
583  // link scm_dynwind_block_asyncs() correctly - this is tested at
584  // configuration time.
585 #ifndef CGU_GUILE_HAS_BROKEN_LINKING
586  scm_dynwind_begin(scm_t_dynwind_flags(0));
587  scm_dynwind_block_asyncs();
588 #endif
589  // we cannot use std::exception_ptr here to store a C++ exception
590  // object, because std::exception_ptr is not trivially destructible
591  // and a guile exception in 'translator' could jump out of this
592  // scope to its continuation in scm_with_guile()
593  bool badalloc = false;
594  try {
595  *retval = (*translator)(scm);
596  *result = true; // this will detect any guile exception in the
597  // preamble or 'translator' which causes
598  // scm_with_guile() to return prematurely. We
599  // have could have done it instead by reversing
600  // the return values of cgu_guile_wrapper
601  // (non-NULL for success and NULL for failure)
602  // because scm_with_guile() returns NULL if it
603  // exits on an uncaught guile exception, but this
604  // approach enables us to discriminate between a
605  // C++ memory exception in the wrapper and a guile
606  // exception in the preamble or 'translator', at a
607  // minimal cost of one assignment to a bool.
608  }
609  catch (Cgu::Extension::GuileException& e) {
610  try {
611  *guile_except = e.guile_text();
612  }
613  catch (...) {
614  badalloc = true;
615  }
616  }
618  try {
619  *guile_ret_val_err = e.err_text();
620  }
621  catch (...) {
622  badalloc = true;
623  }
624  }
625  catch (std::exception& e) {
626  try {
627  *gen_err = e.what();
628  }
629  catch (...) {
630  badalloc = true;
631  }
632  }
633  catch (...) {
634  try {
635  *gen_err = "C++ exception thrown in guile_wrapper_cb()";
636  }
637  catch (...) {
638  badalloc = true;
639  }
640  }
641 #ifndef CGU_GUILE_HAS_BROKEN_LINKING
642  scm_dynwind_end();
643 #endif
644  if (badalloc) throw std::bad_alloc(); // this will be caught in cgu_guile_wrapper()
645 }
646 
647 template <class Ret, class Translator>
648 Ret exec_impl(const std::string& preamble,
649  const std::string& file,
650  Translator translator,
651  bool shared) {
652 
654 
655  std::string loader;
656  if (!shared)
657  loader += "(set-current-module (make-fresh-user-module))";
658  loader += preamble;
659  if (!file.empty()) {
660  if (shared)
661  loader += "((lambda ()";
662  loader += "(catch "
663  "#t"
664  "(lambda ()"
665  "(";
666  if (shared)
667  loader += "primitive-load \"";
668  else
669  loader += "load \"";
670  loader += file;
671  loader += "\"))"
672  "(lambda (key . details)"
673  "(cons \"***cgu-guile-exception***\" (cons key details))))";
674  if (shared)
675  loader += "))";
676  }
677 
678  Ret retval;
679  bool result = false;
680  std::string guile_except;
681  std::string guile_ret_val_err;
682  std::string gen_err;
683 
684  // we construct a Callback::Callback object here to perform type
685  // erasure. Otherwise we would have to pass scm_with_guile() a
686  // function pointer to a function templated on Translator and Ret,
687  // which must have C++ language linkage (§14/4 of C++ standard).
688  // Technically this would give undefined behaviour as
689  // scm_with_guile() expects a function pointer with C language
690  // linkage, although gcc and clang would accept it. The whole of
691  // this callback will be executed in guile mode via
692  // cgu_guile_wrapper(), so it can safely call libguile functions
693  // (provided that a translator does not allow any guile exceptions
694  // to escape a C++ scope with local objects which are not trivially
695  // destructible). It is also safe to pass 'translator', 'retval',
696  // 'loader', 'result' and the exception strings to it by reference,
697  // because scm_with_guile() will block until it has completed
698  // executing. cgu_guile_wrapper() will trap any std::bad_alloc
699  // exception thrown by the string assignments in the catch blocks in
700  // guile_wrapper_cb. guile_wrapper_cb is safe against a jump to an
701  // exit from scm_with_guile() arising from a native guile exception
702  // in translator, because its body has no objects in local scope
703  // requiring destruction.
704  std::unique_ptr<Cgu::Callback::Callback> cb(
705  Cgu::Callback::lambda<>(std::bind(&guile_wrapper_cb<Ret, Translator>,
706  &translator,
707  &loader,
708  &retval,
709  &result,
710  &guile_except,
711  &guile_ret_val_err,
712  &gen_err))
713  );
714  // cgu_guile_wrapper(), and so scm_with_guile() will return a
715  // non-NULL value if assigning to one of the exception description
716  // strings above threw std::bad_alloc
717  if (scm_with_guile(&cgu_guile_wrapper, cb.get()))
718  throw WrapperError("cgu_guile_wrapper() has trapped std::bad_alloc");
719  if (!guile_except.empty())
720  throw GuileException(guile_except.c_str());
721  if (!guile_ret_val_err.empty())
722  throw ReturnValueError(guile_ret_val_err.c_str());
723  if (!gen_err.empty())
724  throw WrapperError(gen_err.c_str());
725  if (!result)
726  throw WrapperError("the preamble or translator threw a native guile exception");
727  return retval;
728 }
729 
730 #endif // DOXYGEN_PARSING
731 
732 /**
733  * This function is called by Extension::rethrow_guile_exception()
734  * where the scheme code executed by Extension::exec() or
735  * Extension::exec_shared() has exited with a guile exception. It
736  * converts the raw guile exception information represented by the
737  * 'key' and 'args' arguments of a guile catch handler to a more
738  * readable form. It is made available as part of the public
739  * interface so that any custom translators can also use it if they
740  * choose to provide their own catch expressions. This function does
741  * not throw any C++ exceptions. No native guile exception will arise
742  * in this function and so cause guile to jump out of it assuming no
743  * guile out-of-memory condition occurs (and given that this function
744  * is called after a guile extension task has completed, such a
745  * condition is very improbable). It is thread safe, but see the
746  * comments above about the thread safety of Extension::exec() and
747  * Extension::exec_shared().
748  *
749  * @param key An opaque guile SCM object representing a symbol
750  * comprising the 'key' argument of the exception handler of a guile
751  * catch expression.
752  * @param args An opaque guile SCM object representing a list
753  * comprising the 'args' argument of the exception handler of a guile
754  * catch expression.
755  * @return An opaque guile SCM object representing a guile string.
756  *
757  * Since 2.0.22
758  */
759 inline SCM exception_to_string(SCM key, SCM args) {
760  // The args of most exceptions thrown by guile are in the following format:
761  // (car args) - a string comprising the name of the procedure generating the exception
762  // (cadr args) - a string containing text, possibly with format directives (escape sequences)
763  // (caddr args) - a list containing items matching the format directives, or #f if none
764  // (cadddr args) - (not used here) a list of additional objects (eg the errno for some errors),
765  // or #f if none
766  SCM ret = SCM_BOOL_F;
767  int length = scm_to_int(scm_length(args));
768  if (length) {
769  SCM first = scm_car(args);
770  if (scm_is_true(scm_string_p(first))) {
771  // if a single user string, output it
772  if (length == 1) {
773  ret = scm_string_append(scm_list_4(scm_from_utf8_string("Exception "),
774  scm_symbol_to_string(key),
775  scm_from_utf8_string(": "),
776  first));
777  }
778  else { // length > 1
779  SCM second = scm_cadr(args);
780  if (scm_is_true(scm_string_p(second))) {
781  // we should have a standard guile exception string, as above
782  SCM text = scm_string_append(scm_list_n(scm_from_utf8_string("Exception "),
783  scm_symbol_to_string(key),
784  scm_from_utf8_string(" in procedure "),
785  first,
786  scm_from_utf8_string(": "),
787  second,
788  SCM_UNDEFINED));
789  if (length == 2)
790  ret = text;
791  else { // length > 2
792  SCM third = scm_caddr(args);
793  if (scm_is_false(third))
794  ret = text;
795  else if (scm_is_true(scm_list_p(third))) {
796  FormatArgs format_args = {text, third};
797  ret = scm_internal_catch(SCM_BOOL_T,
798  &cgu_format_try_handler,
799  &format_args,
800  &cgu_format_catch_handler,
801  0);
802  }
803  }
804  }
805  }
806  }
807  }
808  // fall back to generic formatting if first or second elements of
809  // args is not a string or simple-format failed above
810  if (scm_is_false(ret)) {
811  // there is no need for a catch block: we know simple-format
812  // cannot raise an exception here
813  ret = scm_simple_format(SCM_BOOL_F,
814  scm_from_utf8_string("Exception ~S: ~S"),
815  scm_list_2(key, args));
816  }
817  return ret;
818 }
819 
820 /**
821  * This function tests whether a guile exception arose in executing a
822  * scheme extension file, and throws Cgu::Extension::GuileException if
823  * it did. It is intended for use by custom translators, as the first
824  * thing the translator does. It is thread safe, but see the comments
825  * above about the thread safety of Extension::exec() and
826  * Extension::exec_shared().
827  *
828  * @param scm An opaque guile SCM object representing the value to
829  * which the extension file passed to Extension::exec() or
830  * Extension::exec_shared() evaluated.
831  * @exception std::bad_alloc This function might throw std::bad_alloc
832  * if memory is exhausted and the system throws in that case.
833  * @exception Cgu::Extension::GuileException This exception will be
834  * thrown if the scheme code executed in the extension file passed to
835  * Extension::exec() or Extension::exec_shared() threw a guile
836  * exception. Cgu::Extension::GuileException::what() will give
837  * particulars of the guile exception thrown, in UTF-8 encoding.
838  * @note No native guile exception will arise in this function and so
839  * cause guile to jump out of it if no guile out-of-memory condition
840  * occurs (given that this function is called after a guile extension
841  * task has completed, such a condition is very improbable).
842  *
843  * Since 2.0.22
844  */
845 inline void rethrow_guile_exception(SCM scm) {
846  // guile exceptions are always presented to this function as a
847  // scheme list
848  if (scm_is_false(scm_list_p(scm))
849  || scm_is_true(scm_null_p(scm))) return;
850  SCM first = scm_car(scm);
851  if (scm_is_true(scm_string_p(first))) {
852  size_t len;
853  const char* text = 0;
854  // nothing in this function should throw a guile exception unless
855  // there is a guile out-of-memory exception (which is extremely
856  // improbable). However, let's cover ourselves in case
857  scm_dynwind_begin(scm_t_dynwind_flags(0));
858  char* car = scm_to_utf8_stringn(first, &len);
859  // there may be a weakness in guile's implementation here: if
860  // calling scm_dynwind_unwind_handler() were to give rise to an
861  // out-of-memory exception before the handler is set up by it,
862  // then we could leak memory allocated from the preceding call to
863  // scm_to_utf8_stringn(). Whether that could happen is not
864  // documented, but because (a) it is so improbable, and (b) once
865  // we are in out-of-memory land we are already in severe trouble
866  // and glib is likely to terminate the program at some point
867  // anyway, it is not worth troubling ourselves over.
868  scm_dynwind_unwind_handler(&free, car, scm_t_wind_flags(0));
869  if (len == strlen("***cgu-guile-exception***")
870  && !strncmp(car, "***cgu-guile-exception***", len)) {
871  SCM str = exception_to_string(scm_cadr(scm), scm_cddr(scm));
872  // we don't need a dynwind handler for 'text' because nothing
873  // after the call to scm_to_utf8_stringn() can cause a guile
874  // exception to be raised
875  text = scm_to_utf8_stringn(str, &len);
876  }
877  // all done - no more guile exceptions are possible in this
878  // function after this so end the dynamic context, take control of
879  // the memory by RAII and if necessary throw a C++ exception
880  scm_dynwind_end();
881  std::unique_ptr<char, Cgu::CFree> up_car(car);
882  std::unique_ptr<const char, Cgu::CFree> up_text(text);
883  // if 'text' is not NULL, 'len' contains its length in bytes
884  if (text) throw GuileException(std::string(text, len).c_str());
885  }
886 }
887 
888 /**
889  * A translator function which can be passed to the third argument of
890  * Extension::exec() or Extension::exec_shared(). It converts from a
891  * homogeneous scheme list of integers to a C++ representation of
892  * std::vector<long>. It is thread safe, but see the comments above
893  * about the thread safety of Extension::exec() and
894  * Extension::exec_shared().
895  *
896  * @param scm An opaque guile SCM object representing the value to
897  * which the extension file passed to Extension::exec() or
898  * Extension::exec_shared() evaluated, where that value is a
899  * homogeneous list of integers.
900  * @return The std::vector<long> representation.
901  * @exception std::bad_alloc This function might throw std::bad_alloc
902  * if memory is exhausted and the system throws in that case.
903  * @exception Cgu::Extension::GuileException This exception will be
904  * thrown if the scheme code in the extension file passed to
905  * Extension::exec() or Extension::exec_shared() caused a guile
906  * exception to be thrown. Cgu::Extension::GuileException::what()
907  * will give particulars of the guile exception thrown, in UTF-8
908  * encoding.
909  * @exception Cgu::Extension::ReturnValueError This exception will be
910  * thrown if the scheme code in the extension file passed to
911  * Extension::exec() or Extension::exec_shared() does not evaluate to
912  * the type expected by the translator, or it is out of range for a
913  * long.
914  * @note No native guile exception will arise in this function and so
915  * cause guile to jump out of it if no guile out-of-memory condition
916  * occurs (given that this function is called after a guile extension
917  * task has completed, such a condition is very improbable). If such
918  * an exception were to arise, the implementation would handle it and
919  * a C++ exception would be generated in its place in
920  * Extension::exec() or Extension::exec_shared().
921  *
922  * Since 2.0.22
923  */
924 inline std::vector<long> list_to_vector_long(SCM scm) {
926  if (scm_is_false(scm_list_p(scm)))
927  throw ReturnValueError("scheme code did not evaluate to a list\n");
928 
929  // nothing in this function should throw a guile exception unless
930  // there is a guile out-of-memory exception (which is extremely
931  // improbable). However, let's cover ourselves in case.
932  scm_dynwind_begin(scm_t_dynwind_flags(0));
933  // we cannot have a std::vector object in a scope where a guile
934  // exception might be raised because it has a non-trivial
935  // destructor, nor can we use RAII. Instead allocate on free store
936  // and manage the memory by hand until we can no longer jump on a
937  // guile exception. In addition we cannot store a C++ exception
938  // using std::exception_ptr because std::exception_ptr is not
939  // trivially destructible.
940  bool badalloc = false;
941  const char* rv_error = 0;
942  std::vector<long>* res = 0;
943  VectorDeleteArgs* args = 0;
944  try {
945  res = new std::vector<long>;
946  }
947  catch (...) {
948  badalloc = true;
949  }
950  if (!badalloc) {
951  // allocate 'args' on free store, because the continuation in
952  // which it executes will be up the stack
953  try {
954  args = new VectorDeleteArgs{Long, res};
955  }
956  catch (...) {
957  badalloc = true;
958  }
959  if (!badalloc) {
960  // there may be a weakness in guile's implementation here: if
961  // calling scm_dynwind_unwind_handler() were to give rise to a
962  // guile out-of-memory exception before the handler is set up by
963  // it, then we could leak memory allocated from the preceding
964  // new expressions. Whether that could happen is not documented
965  // by guile, but because (a) it is so improbable, and (b) once
966  // we are in out-of-memory land we are already in severe trouble
967  // and glib is likely to terminate the program at some point
968  // anyway, it is not worth troubling ourselves over.
969  scm_dynwind_unwind_handler(&cgu_delete_vector, args, scm_t_wind_flags(0));
970  int length = scm_to_int(scm_length(scm));
971  try {
972  res->reserve(length);
973  }
974  catch (...) {
975  badalloc = true;
976  }
977  for (int count = 0;
978  count < length && !rv_error && !badalloc;
979  ++count) {
980  SCM item = scm_list_ref(scm, scm_from_int(count));
981  if (scm_is_false(scm_integer_p(item)))
982  rv_error = "scheme code did not evaluate to a homogeneous list of integer\n";
983  else {
984  SCM min = scm_from_long(std::numeric_limits<long>::min());
985  SCM max = scm_from_long(std::numeric_limits<long>::max());
986  if (scm_is_false(scm_leq_p(item, max)) || scm_is_false(scm_geq_p(item, min)))
987  rv_error = "scheme code evaluated out of range for long\n";
988  else {
989  try {
990  res->push_back(scm_to_long(item));
991  }
992  catch (...) {
993  badalloc = true;
994  }
995  }
996  }
997  }
998  }
999  }
1000  // all done - no more guile exceptions are possible in this function
1001  // after this so end the dynamic context, take control of the memory
1002  // by RAII and if necessary throw a C++ exception
1003  scm_dynwind_end();
1004  std::unique_ptr<std::vector<long>> up_res(res);
1005  std::unique_ptr<VectorDeleteArgs> up_args(args);
1006  if (badalloc) throw std::bad_alloc();
1007  if (rv_error) throw ReturnValueError(rv_error);
1008  // neither gcc-4.9 nor clang-3.4 will optimize with RVO or move
1009  // semantics here, so force it by hand
1010  return std::move(*res);
1011 }
1012 
1013 /**
1014  * A translator function which can be passed to the third argument of
1015  * Extension::exec() or Extension::exec_shared(). It converts from a
1016  * homogeneous scheme list of real numbers to a C++ representation of
1017  * std::vector<double>. It is thread safe, but see the comments above
1018  * about the thread safety of Extension::exec() and
1019  * Extension::exec_shared().
1020  *
1021  * @param scm An opaque guile SCM object representing the value to
1022  * which the extension file passed to Extension::exec() or
1023  * Extension::exec_shared() evaluated, where that value is a
1024  * homogeneous list of real numbers.
1025  * @return The std::vector<double> representation.
1026  * @exception std::bad_alloc This function might throw std::bad_alloc
1027  * if memory is exhausted and the system throws in that case.
1028  * @exception Cgu::Extension::GuileException This exception will be
1029  * thrown if the scheme code in the extension file passed to
1030  * Extension::exec() or Extension::exec_shared() caused a guile
1031  * exception to be thrown. Cgu::Extension::GuileException::what()
1032  * will give particulars of the guile exception thrown, in UTF-8
1033  * encoding.
1034  * @exception Cgu::Extension::ReturnValueError This exception will be
1035  * thrown if the scheme code in the extension file passed to
1036  * Extension::exec() or Extension::exec_shared() does not evaluate to
1037  * the type expected by the translator, or it is out of range for a
1038  * double.
1039  * @note 1. Prior to version 2.0.25, this translator had a bug which
1040  * caused an out-of-range Cgu::Extension::ReturnValueError to be
1041  * thrown if any of the numbers in the list to which the scheme code
1042  * in the extension file evaluated was 0.0 or a negative number. This
1043  * was fixed in version 2.0.25.
1044  * @note 2. No native guile exception will arise in this function and
1045  * so cause guile to jump out of it if no guile out-of-memory
1046  * condition occurs (given that this function is called after a guile
1047  * extension task has completed, such a condition is very improbable).
1048  * If such an exception were to arise, the implementation would handle
1049  * it and a C++ exception would be generated in its place in
1050  * Extension::exec() or Extension::exec_shared().
1051  *
1052  * Since 2.0.22
1053  */
1054 inline std::vector<double> list_to_vector_double(SCM scm) {
1056  if (scm_is_false(scm_list_p(scm)))
1057  throw ReturnValueError("scheme code did not evaluate to a list\n");
1058 
1059  // nothing in this function should throw a guile exception unless
1060  // there is a guile out-of-memory exception (which is extremely
1061  // improbable). However, let's cover ourselves in case.
1062  scm_dynwind_begin(scm_t_dynwind_flags(0));
1063  // we cannot have a std::vector object in a scope where a guile
1064  // exception might be raised because it has a non-trivial
1065  // destructor, nor can we use RAII. Instead allocate on free store
1066  // and manage the memory by hand until we can no longer jump on a
1067  // guile exception. In addition we cannot store a C++ exception
1068  // using std::exception_ptr because std::exception_ptr is not
1069  // trivially destructible.
1070  bool badalloc = false;
1071  const char* rv_error = 0;
1072  std::vector<double>* res = 0;
1073  VectorDeleteArgs* args = 0;
1074  try {
1075  res = new std::vector<double>;
1076  }
1077  catch (...) {
1078  badalloc = true;
1079  }
1080  if (!badalloc) {
1081  // allocate 'args' on free store, because the continuation in
1082  // which it executes will be up the stack
1083  try {
1084  args = new VectorDeleteArgs{Double, res};
1085  }
1086  catch (...) {
1087  badalloc = true;
1088  }
1089  if (!badalloc) {
1090  // there may be a weakness in guile's implementation here: if
1091  // calling scm_dynwind_unwind_handler() were to give rise to a
1092  // guile out-of-memory exception before the handler is set up by
1093  // it, then we could leak memory allocated from the preceding
1094  // new expressions. Whether that could happen is not documented
1095  // by guile, but because (a) it is so improbable, and (b) once
1096  // we are in out-of-memory land we are already in severe trouble
1097  // and glib is likely to terminate the program at some point
1098  // anyway, it is not worth troubling ourselves over.
1099  scm_dynwind_unwind_handler(&cgu_delete_vector, args, scm_t_wind_flags(0));
1100  int length = scm_to_int(scm_length(scm));
1101  try {
1102  res->reserve(length);
1103  }
1104  catch (...) {
1105  badalloc = true;
1106  }
1107  for (int count = 0;
1108  count < length && !rv_error && !badalloc;
1109  ++count) {
1110  SCM item = scm_list_ref(scm, scm_from_int(count));
1111  if (scm_is_false(scm_real_p(item)))
1112  rv_error = "scheme code did not evaluate to a homogeneous list of real numbers\n";
1113  else {
1114  SCM min = scm_from_double(-std::numeric_limits<double>::max());
1115  SCM max = scm_from_double(std::numeric_limits<double>::max());
1116  if (scm_is_false(scm_leq_p(item, max)) || scm_is_false(scm_geq_p(item, min)))
1117  rv_error = "scheme code evaluated out of range for double\n";
1118  else {
1119  try {
1120  res->push_back(scm_to_double(item));
1121  }
1122  catch (...) {
1123  badalloc = true;
1124  }
1125  }
1126  }
1127  }
1128  }
1129  }
1130  // all done - no more guile exceptions are possible in this function
1131  // after this so end the dynamic context, take control of the memory
1132  // by RAII and if necessary throw a C++ exception
1133  scm_dynwind_end();
1134  std::unique_ptr<std::vector<double>> up_res(res);
1135  std::unique_ptr<VectorDeleteArgs> up_args(args);
1136  if (badalloc) throw std::bad_alloc();
1137  if (rv_error) throw ReturnValueError(rv_error);
1138  // neither gcc-4.9 nor clang-3.4 will optimize with RVO or move
1139  // semantics here, so force it by hand
1140  return std::move(*res);
1141 }
1142 
1143 /**
1144  * A translator function which can be passed to the third argument of
1145  * Extension::exec() or Extension::exec_shared(). It converts from a
1146  * homogeneous scheme list of strings to a C++ representation of
1147  * std::vector<std::string>. It is thread safe, but see the comments
1148  * above about the thread safety of Extension::exec() and
1149  * Extension::exec_shared().
1150  *
1151  * The returned strings will be in UTF-8 encoding.
1152  *
1153  * Note that the first string in the returned list must not be
1154  * "***cgu-guile-exception***": that string is reserved to the
1155  * implementation.
1156  *
1157  * @param scm An opaque guile SCM object representing the value to
1158  * which the extension file passed to Extension::exec() or
1159  * Extension::exec_shared() evaluated, where that value is a
1160  * homogeneous list of strings.
1161  * @return The std::vector<std::string> representation.
1162  * @exception std::bad_alloc This function might throw std::bad_alloc
1163  * if memory is exhausted and the system throws in that case.
1164  * @exception Cgu::Extension::GuileException This exception will be
1165  * thrown if the scheme code in the extension file passed to
1166  * Extension::exec() or Extension::exec_shared() caused a guile
1167  * exception to be thrown. Cgu::Extension::GuileException::what()
1168  * will give particulars of the guile exception thrown, in UTF-8
1169  * encoding.
1170  * @exception Cgu::Extension::ReturnValueError This exception will be
1171  * thrown if the scheme code in the extension file passed to
1172  * Extension::exec() or Extension::exec_shared() does not evaluate to
1173  * the type expected by the translator.
1174  * @note No native guile exception will arise in this function and so
1175  * cause guile to jump out of it if no guile out-of-memory condition
1176  * occurs (given that this function is called after a guile extension
1177  * task has completed, such a condition is very improbable). If such
1178  * an exception were to arise, the implementation would handle it and
1179  * a C++ exception would be generated in its place in
1180  * Extension::exec() or Extension::exec_shared().
1181  *
1182  * Since 2.0.22
1183  */
1184 inline std::vector<std::string> list_to_vector_string(SCM scm) {
1186  if (scm_is_false(scm_list_p(scm)))
1187  throw ReturnValueError("scheme code did not evaluate to a list\n");
1188 
1189  // nothing in this function should throw a guile exception unless
1190  // there is a guile out-of-memory exception (which is extremely
1191  // improbable). However, let's cover ourselves in case.
1192  scm_dynwind_begin(scm_t_dynwind_flags(0));
1193  // we cannot have a std::vector object in a scope where a guile
1194  // exception might be raised because it has a non-trivial
1195  // destructor, nor can we use RAII. Instead allocate on free store
1196  // and manage the memory by hand until we can no longer jump on a
1197  // guile exception. In addition we cannot store a C++ exception
1198  // using std::exception_ptr because std::exception_ptr is not
1199  // trivially destructible.
1200  bool badalloc = false;
1201  const char* rv_error = 0;
1202  std::vector<std::string>* res = 0;
1203  VectorDeleteArgs* args = 0;
1204  try {
1205  res = new std::vector<std::string>;
1206  }
1207  catch (...) {
1208  badalloc = true;
1209  }
1210  if (!badalloc) {
1211  // allocate 'args' on free store, because the continuation in
1212  // which it executes will be up the stack
1213  try {
1214  args = new VectorDeleteArgs{String, res};
1215  }
1216  catch (...) {
1217  badalloc = true;
1218  }
1219  if (!badalloc) {
1220  // there may be a weakness in guile's implementation here: if
1221  // calling scm_dynwind_unwind_handler() were to give rise to a
1222  // guile out-of-memory exception before the handler is set up by
1223  // it, then we could leak memory allocated from the preceding
1224  // new expressions. Whether that could happen is not documented
1225  // by guile, but because (a) it is so improbable, and (b) once
1226  // we are in out-of-memory land we are already in severe trouble
1227  // and glib is likely to terminate the program at some point
1228  // anyway, it is not worth troubling ourselves over.
1229  scm_dynwind_unwind_handler(&cgu_delete_vector, args, scm_t_wind_flags(0));
1230  int length = scm_to_int(scm_length(scm));
1231  try {
1232  res->reserve(length);
1233  }
1234  catch (...) {
1235  badalloc = true;
1236  }
1237  for (int count = 0;
1238  count < length && !rv_error && !badalloc;
1239  ++count) {
1240  SCM item = scm_list_ref(scm, scm_from_int(count));
1241  if (scm_is_false(scm_string_p(item)))
1242  rv_error = "scheme code did not evaluate to a homogeneous list of string\n";
1243  else {
1244  size_t len;
1245  // we don't need a dynwind handler for 'str' because nothing
1246  // after the call to scm_to_utf8_stringn() and before the
1247  // call to free() can cause a guile exception to be raised
1248  char* str = scm_to_utf8_stringn(item, &len);
1249  try {
1250  res->emplace_back(str, len);
1251  }
1252  catch (...) {
1253  badalloc = true;
1254  }
1255  free(str);
1256  }
1257  }
1258  }
1259  }
1260  // all done - no more guile exceptions are possible in this function
1261  // after this so end the dynamic context, take control of the memory
1262  // by RAII and if necessary throw a C++ exception
1263  scm_dynwind_end();
1264  std::unique_ptr<std::vector<std::string>> up_res(res);
1265  std::unique_ptr<VectorDeleteArgs> up_args(args);
1266  if (badalloc) throw std::bad_alloc();
1267  if (rv_error) throw ReturnValueError(rv_error);
1268  // neither gcc-4.9 nor clang-3.4 will optimize with RVO or move
1269  // semantics here, so force it by hand
1270  return std::move(*res);
1271 }
1272 
1273 /**
1274  * A translator function which can be passed to the third argument of
1275  * Extension::exec() or Extension::exec_shared(). It converts from a
1276  * scheme integer to a C++ representation of long. It is thread safe,
1277  * but see the comments above about the thread safety of
1278  * Extension::exec() and Extension::exec_shared().
1279  *
1280  * @param scm An opaque guile SCM object representing the value to
1281  * which the extension file passed to Extension::exec() or
1282  * Extension::exec_shared() evaluated, where that value is an integer.
1283  * @return The C++ long representation.
1284  * @exception std::bad_alloc This function might throw std::bad_alloc
1285  * if memory is exhausted and the system throws in that case.
1286  * @exception Cgu::Extension::GuileException This exception will be
1287  * thrown if the scheme code in the extension file passed to
1288  * Extension::exec() or Extension::exec_shared() caused a guile
1289  * exception to be thrown. Cgu::Extension::GuileException::what()
1290  * will give particulars of the guile exception thrown, in UTF-8
1291  * encoding.
1292  * @exception Cgu::Extension::ReturnValueError This exception will be
1293  * thrown if the scheme code in the extension file passed to
1294  * Extension::exec() or Extension::exec_shared() does not evaluate to
1295  * the type expected by the translator, or it is out of range for a
1296  * long.
1297  * @note No native guile exception will arise in this function and so
1298  * cause guile to jump out of it if no guile out-of-memory condition
1299  * occurs (given that this function is called after a guile extension
1300  * task has completed, such a condition is very improbable). If such
1301  * an exception were to arise, the implementation would handle it and
1302  * a C++ exception would be generated in its place in
1303  * Extension::exec() or Extension::exec_shared().
1304  *
1305  * Since 2.0.22
1306  */
1307 inline long integer_to_long(SCM scm) {
1309  if (scm_is_false(scm_integer_p(scm)))
1310  throw ReturnValueError("scheme code did not evaluate to an integer\n");
1311  SCM min = scm_from_long(std::numeric_limits<long>::min());
1312  SCM max = scm_from_long(std::numeric_limits<long>::max());
1313  if (scm_is_false(scm_leq_p(scm, max)) || scm_is_false(scm_geq_p(scm, min)))
1314  throw ReturnValueError("scheme code evaluated out of range for long\n");
1315  return scm_to_long(scm);
1316 }
1317 
1318 /**
1319  * A translator function which can be passed to the third argument of
1320  * Extension::exec() or Extension::exec_shared(). It converts from a
1321  * scheme real number to a C++ representation of double. It is thread
1322  * safe, but see the comments above about the thread safety of
1323  * Extension::exec() and Extension::exec_shared().
1324  *
1325  * @param scm An opaque guile SCM object representing the value to
1326  * which the extension file passed to Extension::exec() or
1327  * Extension::exec_shared() evaluated, where that value is a real
1328  * number.
1329  * @return The C++ double representation.
1330  * @exception std::bad_alloc This function might throw std::bad_alloc
1331  * if memory is exhausted and the system throws in that case.
1332  * @exception Cgu::Extension::GuileException This exception will be
1333  * thrown if the scheme code in the extension file passed to
1334  * Extension::exec() or Extension::exec_shared() caused a guile
1335  * exception to be thrown. Cgu::Extension::GuileException::what()
1336  * will give particulars of the guile exception thrown, in UTF-8
1337  * encoding.
1338  * @exception Cgu::Extension::ReturnValueError This exception will be
1339  * thrown if the scheme code in the extension file passed to
1340  * Extension::exec() or Extension::exec_shared() does not evaluate to
1341  * the type expected by the translator, or it is out of range for a
1342  * double.
1343  * @note 1. Prior to version 2.0.25, this translator had a bug which
1344  * caused an out-of-range Cgu::Extension::ReturnValueError to be
1345  * thrown if the scheme code in the extension file evaluated to 0.0 or
1346  * a negative number. This was fixed in version 2.0.25.
1347  * @note 2. No native guile exception will arise in this function and
1348  * so cause guile to jump out of it if no guile out-of-memory
1349  * condition occurs (given that this function is called after a guile
1350  * extension task has completed, such a condition is very improbable).
1351  * If such an exception were to arise, the implementation would handle
1352  * it and a C++ exception would be generated in its place in
1353  * Extension::exec() or Extension::exec_shared().
1354  *
1355  * Since 2.0.22
1356  */
1357 inline double real_to_double(SCM scm) {
1359  if (scm_is_false(scm_real_p(scm)))
1360  throw ReturnValueError("scheme code did not evaluate to a real number\n");
1361  SCM min = scm_from_double(-std::numeric_limits<double>::max());
1362  SCM max = scm_from_double(std::numeric_limits<double>::max());
1363  if (scm_is_false(scm_leq_p(scm, max)) || scm_is_false(scm_geq_p(scm, min)))
1364  throw ReturnValueError("scheme code evaluated out of range for double\n");
1365  return scm_to_double(scm);
1366 }
1367 
1368 /**
1369  * A translator function which can be passed to the third argument of
1370  * Extension::exec() or Extension::exec_shared(). It converts from a
1371  * scheme string to a C++ representation of std::string. It is thread
1372  * safe, but see the comments above about the thread safety of
1373  * Extension::exec() and Extension::exec_shared().
1374  *
1375  * The returned string will be in UTF-8 encoding.
1376  *
1377  * @param scm An opaque guile SCM object representing the value to
1378  * which the extension file passed to Extension::exec() or
1379  * Extension::exec_shared() evaluated, where that value is a string.
1380  * @return The std::string representation.
1381  * @exception std::bad_alloc This function might throw std::bad_alloc
1382  * if memory is exhausted and the system throws in that case.
1383  * @exception Cgu::Extension::GuileException This exception will be
1384  * thrown if the scheme code in the extension file passed to
1385  * Extension::exec() or Extension::exec_shared() caused a guile
1386  * exception to be thrown. Cgu::Extension::GuileException::what()
1387  * will give particulars of the guile exception thrown, in UTF-8
1388  * encoding.
1389  * @exception Cgu::Extension::ReturnValueError This exception will be
1390  * thrown if the scheme code in the extension file passed to
1391  * Extension::exec() or Extension::exec_shared() does not evaluate to
1392  * the type expected by the translator.
1393  * @note No native guile exception will arise in this function and so
1394  * cause guile to jump out of it if no guile out-of-memory condition
1395  * occurs (given that this function is called after a guile extension
1396  * task has completed, such a condition is very improbable). If such
1397  * an exception were to arise, the implementation would handle it and
1398  * a C++ exception would be generated in its place in
1399  * Extension::exec() or Extension::exec_shared().
1400  *
1401  * Since 2.0.22
1402  */
1403 inline std::string string_to_string(SCM scm) {
1405  if (scm_is_false(scm_string_p(scm)))
1406  throw ReturnValueError("scheme code did not evaluate to a string\n");
1407  size_t len;
1408  // it is safe to use unique_ptr here. If scm_to_utf8_stringn()
1409  // succeeds then nothing after it in this function can cause a guile
1410  // exception.
1411  std::unique_ptr<const char, Cgu::CFree> s(scm_to_utf8_stringn(scm, &len));
1412  return std::string(s.get(), len);
1413 }
1414 
1415 /**
1416  * A translator function which can be passed to the third argument of
1417  * Extension::exec() or Extension::exec_shared(). It disregards the
1418  * scheme value passed to it except to trap any guile exception thrown
1419  * by the scheme task and rethrow it as a C++ exception, and returns a
1420  * NULL void* object. It is thread safe, but see the comments above
1421  * about the thread safety of Extension::exec() and
1422  * Extension::exec_shared().
1423  *
1424  * It is mainly intended for use where the scheme script is executed
1425  * for its side effects, perhaps for I/O, and any communication
1426  * necessary is done by guile exceptions.
1427  *
1428  * @param scm An opaque guile SCM object representing the value to
1429  * which the extension file passed to Extension::exec() or
1430  * Extension::exec_shared() evaluated, which is ignored.
1431  * @return A NULL void* object.
1432  * @exception std::bad_alloc This function might throw std::bad_alloc
1433  * if memory is exhausted and the system throws in that case.
1434  * @exception Cgu::Extension::GuileException This exception will be
1435  * thrown if the scheme code in the extension file passed to
1436  * Extension::exec() or Extension::exec_shared() caused a guile
1437  * exception to be thrown. Cgu::Extension::GuileException::what()
1438  * will give particulars of the guile exception thrown, in UTF-8
1439  * encoding.
1440  * @note No native guile exception will arise in this function and so
1441  * cause guile to jump out of it if no guile out-of-memory condition
1442  * occurs (given that this function is called after a guile extension
1443  * task has completed, such a condition is very improbable). If such
1444  * an exception were to arise, the implementation would handle it and
1445  * a C++ exception would be generated in its place in
1446  * Extension::exec() or Extension::exec_shared().
1447  *
1448  * Since 2.0.22
1449  */
1450 inline void* any_to_void(SCM scm) {
1452  return 0;
1453 }
1454 
1455 /**
1456  * This function executes scheme code on the guile VM within a C++
1457  * program using this library. See the introductory remarks above for
1458  * its potential uses, about the thread safety of this function, and
1459  * about the use of the TaskManager::exec_shared() as an alternative.
1460  *
1461  * The first argument to this function is a preamble, which can be
1462  * used to pass top level definitions to the scheme code (in other
1463  * words, for argument passing). It's second argument is the filename
1464  * (with path) of the file containing the scheme code to be executed.
1465  * It's third argument is a translator, which will convert the value
1466  * to which the scheme code evaluates (in C++ terms, its return value)
1467  * to a suitable C++ representation. Preformed translators are
1468  * provided by this library to translate from scheme's integers, real
1469  * numbers and strings to C++ longs, doubles and strings respectively,
1470  * and from any uniform lists of these to C++ vectors of the
1471  * corresponding type. There is also a translator for void return
1472  * types. See the introductory remarks above for more information
1473  * about translators.
1474  *
1475  * Any native guile exceptions thrown by the code executed by this
1476  * function (and by any code which it calls) are converted and
1477  * rethrown as C++ exceptions.
1478  *
1479  * The scheme file can call other scheme code, and load modules, in
1480  * the ordinary way. Thus, this function can execute any scheme code
1481  * which guile can execute as a program, and the programmer can (if
1482  * wanted) act on its return value in the C++ code which invokes it.
1483  *
1484  * Thread cancellation is blocked for the thread in which this
1485  * function executes until this function returns.
1486  *
1487  * @param preamble Scheme code such as top level definitions to be
1488  * seen by the code in the file to be executed. This is mainly
1489  * intended for argument passing, but can comprise any valid scheme
1490  * code. It can also be empty (you can pass ""). Any string literals
1491  * must be in UTF-8 encoding.
1492  * @param file The file which is to be executed on the guile VM. This
1493  * should include the full pathname or a pathname relative to the
1494  * current directory. The contents of the file, and in particular any
1495  * string literals in it, must be in UTF-8 encoding. The filename and
1496  * path must also be given in UTF-8 encoding, even if the local
1497  * filename encoding is something different: guile will convert the
1498  * UTF-8 name which it is given to its own internal string encoding
1499  * using unicode code points, and then convert that to locale encoding
1500  * on looking up the filename. However sticking to ASCII for
1501  * filenames and paths (which is always valid UTF-8) will maximise
1502  * portability. The file name can be empty (you can pass ""), in
1503  * which case only the preamble will be evaluated (but for efficiency
1504  * reasons any complex code not at the top level should be included in
1505  * the file rather than in the preamble).
1506  * @param translator The function or callable object which will
1507  * convert the value to which the scheme code evaluates to a C++
1508  * representation which will be returned by this function. The
1509  * translator should take a single argument comprising an opaque guile
1510  * object of type SCM, and return the C++ representation for it.
1511  * @return The C++ representation returned by the translator.
1512  * @exception std::bad_alloc This function might throw std::bad_alloc
1513  * if memory is exhausted and the system throws in that case.
1514  * @exception Cgu::Extension::GuileException This exception will be
1515  * thrown if the scheme code in 'file' (or called by it) throws a
1516  * guile exception. Cgu::Extension::GuileException::what() will give
1517  * particulars of the guile exception thrown, in UTF-8 encoding.
1518  * @exception Cgu::Extension::ReturnValueError This exception will be
1519  * thrown if the code in 'file' does not evaluate to the type expected
1520  * by the translator.
1521  * @exception Cgu::Extension::WrapperError This exception will be
1522  * thrown if a custom translator throws a native guile exception or a
1523  * C++ exception not comprising Extension::GuileException or
1524  * Extension::ReturnValueError, one of the preformed translators
1525  * throws std::bad_alloc or encounters a guile out-of-memory
1526  * exception, assigning to an internal exception description string
1527  * throws std::bad_alloc, or evaluation of the preamble throws a
1528  * native guile exception.
1529  *
1530  * Since 2.0.22
1531  */
1532 // we cannot take 'translator' by collapsible reference, because with
1533 // gcc-4.4 std::result_of fails if Translator deduces to a reference
1534 // type, and gcc-4.4 does not have std::declval. This is fixed in the
1535 // 2.2 series of this library, which has a minimum requirement of
1536 // gcc-4.6.
1537 template <class Translator>
1538 auto exec(const std::string& preamble,
1539  const std::string& file,
1540  Translator translator) -> typename std::result_of<Translator(SCM)>::type {
1541  typedef typename std::result_of<Translator(SCM)>::type Ret;
1542  return exec_impl<Ret>(preamble, file, translator, false);
1543 }
1544 
1545 /**
1546  * This function executes scheme code on the guile VM within a C++
1547  * program using this library. See the introductory remarks above for
1548  * its potential uses, about the thread safety of this function, and
1549  * about the use of the TaskManager::exec() as an alternative.
1550  *
1551  * The first argument to this function is a preamble, which can be
1552  * used to pass top level definitions to the scheme code (in other
1553  * words, for argument passing). It's second argument is the filename
1554  * (with path) of the file containing the scheme code to be executed.
1555  * It's third argument is a translator, which will convert the value
1556  * to which the scheme code evaluates (in C++ terms, its return value)
1557  * to a suitable C++ representation. Preformed translators are
1558  * provided by this library to translate from scheme's integers, real
1559  * numbers and strings to C++ longs, doubles and strings respectively,
1560  * and from any uniform lists of these to C++ vectors of the
1561  * corresponding type. There is also a translator for void return
1562  * types. See the introductory remarks above for more information
1563  * about translators.
1564  *
1565  * Any native guile exceptions thrown by the code executed by this
1566  * function (and by any code which it calls) are converted and
1567  * rethrown as C++ exceptions.
1568  *
1569  * The scheme file can call other scheme code, and load modules, in
1570  * the ordinary way. Thus, this function can execute any scheme code
1571  * which guile can execute as a program, and the programmer can (if
1572  * wanted) act on its return value in the C++ code which invokes it.
1573  *
1574  * Thread cancellation is blocked for the thread in which this
1575  * function executes until this function returns.
1576  *
1577  * @param preamble Scheme code such as top level definitions to be
1578  * seen by the code in the file to be executed. This is mainly
1579  * intended for argument passing, but can comprise any valid scheme
1580  * code. It can also be empty (you can pass ""). Any string literals
1581  * must be in UTF-8 encoding.
1582  * @param file The file which is to be executed on the guile VM. This
1583  * should include the full pathname or a pathname relative to the
1584  * current directory. The contents of the file, and in particular any
1585  * string literals in it, must be in UTF-8 encoding. The filename and
1586  * path must also be given in UTF-8 encoding, even if the local
1587  * filename encoding is something different: guile will convert the
1588  * UTF-8 name which it is given to its own internal string encoding
1589  * using unicode code points, and then convert that to locale encoding
1590  * on looking up the filename. However sticking to ASCII for
1591  * filenames and paths (which is always valid UTF-8) will maximise
1592  * portability. The file name can be empty (you can pass ""), in
1593  * which case only the preamble will be evaluated.
1594  * @param translator The function or callable object which will
1595  * convert the value to which the scheme code evaluates to a C++
1596  * representation which will be returned by this function. The
1597  * translator should take a single argument comprising an opaque guile
1598  * object of type SCM, and return the C++ representation for it.
1599  * @return The C++ representation returned by the translator.
1600  * @exception std::bad_alloc This function might throw std::bad_alloc
1601  * if memory is exhausted and the system throws in that case.
1602  * @exception Cgu::Extension::GuileException This exception will be
1603  * thrown if the scheme code in 'file' (or called by it) throws a
1604  * guile exception. Cgu::Extension::GuileException::what() will give
1605  * particulars of the guile exception thrown, in UTF-8 encoding.
1606  * @exception Cgu::Extension::ReturnValueError This exception will be
1607  * thrown if the code in 'file' does not evaluate to the type expected
1608  * by the translator.
1609  * @exception Cgu::Extension::WrapperError This exception will be
1610  * thrown if a custom translator throws a native guile exception or a
1611  * C++ exception not comprising Extension::GuileException or
1612  * Extension::ReturnValueError, one of the preformed translators
1613  * throws std::bad_alloc or encounters a guile out-of-memory
1614  * exception, assigning to an internal exception description string
1615  * throws std::bad_alloc, or evaluation of the preamble throws a
1616  * native guile exception.
1617  *
1618  * Since 2.0.24
1619  */
1620 // we cannot take 'translator' by collapsible reference, because with
1621 // gcc-4.4 std::result_of fails if Translator deduces to a reference
1622 // type, and gcc-4.4 does not have std::declval. This is fixed in the
1623 // 2.2 series of this library, which has a minimum requirement of
1624 // gcc-4.6.
1625 template <class Translator>
1626 auto exec_shared(const std::string& preamble,
1627  const std::string& file,
1628  Translator translator) -> typename std::result_of<Translator(SCM)>::type {
1629  typedef typename std::result_of<Translator(SCM)>::type Ret;
1630  return exec_impl<Ret>(preamble, file, translator, true);
1631 }
1632 
1633 } // namespace Extension
1634 
1635 } // namespace Cgu
1636 
1637 #endif // CGU_EXTENSION_H