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