c++-gtk-utils

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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