1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 Copyright (c) 2011-2021 The plumed team
3 (see the PEOPLE file at the root of the distribution for a list of names)
4
5 See http://www.plumed.org for more information.
6
7 This file is part of plumed, version 2.
8
9 plumed is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 plumed is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #ifndef __PLUMED_wrapper_Plumed_h
23 #define __PLUMED_wrapper_Plumed_h
24
25 /*
26 This header might be included more than once in order to provide
27 the declarations and the definitions. The guard is thus closed before the end of the file
28 (match this brace) {
29 and a new guard is added for the definitions.
30 */
31
32 /**
33 \page ReferencePlumedH Reference for interfacing MD codes with PLUMED
34
35 Plumed.h and Plumed.c contain the external plumed interface, which is used to
36 integrate it with MD engines. This interface is very general, and is expected
37 not to change across plumed versions. Plumed.c also implements a dummy version
38 of the interface, so as to allow a code to be fully linked even if the plumed
39 library is not available yet. These files could be directly included in the official
40 host MD distribution. In this manner, it will be sufficient to link the plumed
41 library at link time (on all systems) or directly at runtime (on systems where
42 dynamic loading is enabled) to include plumed features.
43
44 Notice that in PLUMED 2.5 this interface has been rewritten in order to allow
45 more debugging features and a better behavior in multithread environments.
46 The interface is almost perfectly backward compatible, although it implements
47 a few additional functions. See more details below.
48
49 Why is Plumed.c written in C and not C++? The reason is that the resulting Plumed.o
50 needs to be linked with the host MD code immediately (whereas the rest of plumed
51 could be linked a posteriori). Imagine the MD code is written in FORTRAN: when we
52 link the Plumed.o file we would like not to need any C++ library linked. In this
53 manner, we do not need to know which C++ compiler will be used to compile plumed.
54 The C++ library is only linked to the "rest" of plumed, which actually uses it.
55 Anyway, Plumed.c is written in such a manner to allow its compilation also in C++
56 (C++ is a bit stricter than C). This will
57 allow e.g. MD codes written in C++ to just incorporate Plumed.c (maybe renamed into
58 Plumed.cpp), without the need of configuring a plain C compiler.
59
60 Plumed interface can be used from C, C++ and FORTRAN. Everything concerning plumed
61 is hidden inside a single object type, which is described in C by a structure
62 (struct \ref plumed), in C++ by a class (PLMD::Plumed) and in FORTRAN by a
63 fixed-length string (CHARACTER(LEN=32)). Obviously C++ can use both struct
64 and class interfaces, but the second should be preferred since it will automatically take
65 care of objects constructions and destructions. The reference interface
66 is the C one, whereas FORTRAN and C++ interfaces are implemented as wrappers
67 around it.
68 In the C++ interface, all the routines are implemented as methods of PLMD::Plumed.
69 In the C and FORTRAN interfaces, all the routines are named plumed_*, to
70 avoid potential name clashes. Notice that the entire plumed library
71 is implemented in C++, and it is hidden inside the PLMD namespace.
72
73 Handlers to the plumed object can be converted among different representations,
74 to allow inter-operability among languages. In C, there are tools to convert
75 to/from FORTRAN, whereas in C++ there are tools to convert to/from FORTRAN and C.
76
77 These handlers only contain a pointer to the real structure, so that
78 when a plumed object is brought from one language to another,
79 it brings a reference to the same environment.
80
81 Moreover, to simplify life in all cases where a single Plumed object is
82 required for the entire simulation (which covers many of the practical
83 applications with conventional MD codes) it is possible to take advantage
84 of a global interface, which is implicitly referring to a unique global instance.
85 The global object should still be initialized and finalized properly.
86 This global object is obviously not usable in a multithread context.
87
88 As of PLUMED 2.5, the interface contains a reference counter that allows
89 for a better control of plumed initializations and deallocations.
90 This is particularly useful for the C++ interface that now
91 behaves similarly to a primitive shared pointer and can be thus copied.
92 In other languages, to use the reference counter correctly it is sufficient to
93 remember the following rule: for any `plumed_create*` call, there should be a corresponding
94 `plumed_finalize` call. More examples can be found below.
95
96 The basic method to send a message to plumed is
97 \verbatim
98 (C) plumed_cmd
99 (C++) PLMD::Plumed::cmd
100 (FORTRAN) PLUMED_F_CMD
101 \endverbatim
102
103 To initialize a plumed object, use:
104 \verbatim
105 (C) plumed_create
106 (C++) (constructor of PLMD::Plumed)
107 (FORTRAN) PLUMED_F_CREATE
108 \endverbatim
109
110 As of PLUMED 2.5, you can also initialize a plumed object using the following functions,
111 that load a specific kernel. The function plumed_create_dlopen2 allows to specify options
112 for dlopen. The C++ version accepts an optional argument to this aim.
113 \verbatim
114 (C) plumed_create_dlopen or plumed_create_dlopen2
115 (C++) PLMD::Plumed::dlopen
116 (FORTRAN) PLUMED_F_CREATE_DLOPEN
117 \endverbatim
118
119 To finalize a plumed object, use
120 \verbatim
121 (C) plumed_finalize
122 (C++) (destructor of PLMD::Plumed)
123 (FORTRAN) PLUMED_F_FINALIZE
124 \endverbatim
125
126 To access to the global-object, use
127 \verbatim
128 (C) plumed_gcreate, plumed_gfinalize, plumed_gcmd
129 (C++) PLMD::Plumed::gcreate, PLMD::Plumed::gfinalize, PLMD::Plumed::gcmd
130 (FORTRAN) PLUMED_F_GCREATE, PLUMED_F_GFINALIZE, PLUMED_F_GCMD
131 \endverbatim
132
133 To check if the global object has been initialized, use
134 \verbatim
135 (C) plumed_ginitialized
136 (C++) PLMD::Plumed::ginitialized
137 (FORTRAN) PLUMED_F_GINITIALIZED
138 \endverbatim
139
140 Notice that when using runtime binding the plumed library might be not available.
141 In this case, plumed_create (and plumed_gcreate) will still succeed, but a subsequent
142 call to plumed_cmd (or plumed_gcmd) would exit. In order to avoid this
143 unpleasant situation you have two options.
144
145 First, you can check if plumed library is available before actually creating an object
146 using this function:
147 \verbatim
148 (C) plumed_installed
149 (C++) PLMD::Plumed::installed
150 (FORTRAN) PLUMED_F_INSTALLED
151 \endverbatim
152
153 Alternatively, as of PLUMED 2.5, you can interrogate the just created plumed
154 object using the following function:
155 \verbatim
156 (C) plumed_valid
157 (C++) PLMD::Plumed::valid
158 (FORTRAN) PLUMED_F_VALID
159 \endverbatim
160
161 If you want to create on purpose an invalid Plumed object (useful in C++ to postpone
162 the loading of the library) you can use `Plumed p(Plumed::makeInvalid());`.
163
164 To know if the global object is valid instead you should use the following function:
165 \verbatim
166 (C) plumed_gvalid
167 (C++) PLMD::Plumed::gvalid
168 (FORTRAN) PLUMED_F_GVALID
169 \endverbatim
170
171 To convert handlers between different languages, use
172 \verbatim
173 (C) plumed_c2f (C to FORTRAN)
174 (C) plumed_f2c (FORTRAN to C)
175 (C++) Plumed(plumed) constructor (C to C++)
176 (C++) operator plumed() cast (C++ to C)
177 (C++) Plumed(char*) constructor (FORTRAN to C++)
178 (C++) toFortran(char*) (C++ to FORTRAN)
179 \endverbatim
180
181 As of PLUMED 2.5, when using C or C++ we allow a user to explicitly store a plumed object as
182 a void pointer (indeed: that's the only thing contained in a plumed object).
183 This might be useful in case you do not want to include the Plumed.h header in some
184 of your headers. In order to convert to/from void pointers you can use the following functions
185 \verbatim
186 (C) plumed_v2c (void* to C)
187 (C) plumed_c2v (C to void*)
188 (C++) Plumed(void*) constructor (void* to C++)
189 (C++) toVoid() (C++ to void*)
190 \endverbatim
191 Using the functions above is much safer than accessing directly the pointer contained in the \ref plumed struct
192 since, when compiling with debug options, it will check if the void pointer actually points to a plumed object.
193
194 As of PLUMED 2.5, we added a reference count. It is in practice possible
195 to create multiple `plumed` objects that refer to the same environment.
196 This is done using the following functions
197 \verbatim
198 (C) plumed_create_reference (from a C object)
199 (C) plumed_create_reference_f (from a FORTRAN object)
200 (C) plumed_create_reference_v (from a void pointer)
201 (FORTRAN) plumed_f_create_reference (from a FORTRAN object)
202 \endverbatim
203 In C++ references are managed automatically by constructors and destructor.
204 In addition, you can manually manage them (with care!) using incref() and decref().
205
206 The interface of the FORTRAN functions is very similar to that of the C functions
207 and is listed below:
208
209 \verbatim
210 FORTRAN interface
211 SUBROUTINE PLUMED_F_CREATE(p)
212 CHARACTER(LEN=32), INTENT(OUT) :: p
213 SUBROUTINE PLUMED_F_CREATE_DLOPEN(p,path)
214 CHARACTER(LEN=32), INTENT(OUT) :: p
215 CHARACTER(LEN=*), INTENT(IN) :: path
216 SUBROUTINE PLUMED_F_CREATE_REFERENCE(p,r)
217 CHARACTER(LEN=32), INTENT(OUT) :: p
218 CHARACTER(LEN=32), INTENT(IN) :: r
219 SUBROUTINE PLUMED_F_CREATE_INVALID(p)
220 CHARACTER(LEN=32), INTENT(OUT) :: p
221 SUBROUTINE PLUMED_F_CMD(p,key,val)
222 CHARACTER(LEN=32), INTENT(IN) :: p
223 CHARACTER(LEN=*), INTENT(IN) :: key
224 UNSPECIFIED_TYPE, INTENT(INOUT) :: val(*)
225 SUBROUTINE PLUMED_F_FINALIZE(p)
226 CHARACTER(LEN=32), INTENT(IN) :: p
227 SUBROUTINE PLUMED_F_INSTALLED(i)
228 INTEGER, INTENT(OUT) :: i
229 SUBROUTINE PLUMED_F_VALID(p,i)
230 CHARACTER(LEN=32), INTENT(IN) :: p
231 INTEGER, INTENT(OUT) :: i
232 SUBROUTINE PLUMED_F_USE_COUNT(p,i)
233 CHARACTER(LEN=32), INTENT(IN) :: p
234 INTEGER, INTENT(OUT) :: i
235 SUBROUTINE PLUMED_F_GLOBAL(p)
236 CHARACTER(LEN=32), INTENT(OUT) :: p
237 SUBROUTINE PLUMED_F_GINITIALIZED(i)
238 INTEGER, INTENT(OUT) :: i
239 SUBROUTINE PLUMED_F_GCREATE()
240 SUBROUTINE PLUMED_F_GCMD(key,val)
241 CHARACTER(LEN=*), INTENT(IN) :: key
242 UNSPECIFIED_TYPE, INTENT(INOUT) :: val(*)
243 SUBROUTINE PLUMED_F_GFINALIZE()
244 SUBROUTINE PLUMED_F_GVALID(i)
245 INTEGER, INTENT(OUT) :: i
246 \endverbatim
247
248 Almost all C functions have a corresponding FORTRAN function.
249 As a simple mnemonic, if you know the name of the C function you can obtain the
250 corresponding FORTRAN subroutine by adding `F_` after the `PLUMED_` prefix.
251 In addition, all `plumed` objects are replaced by `CHARACTER(LEN=32)` objects
252 holding the same information. These pointers basically contain a text representation
253 of the stored pointer, that is suitable to be contained in a string.
254 Finally, whenever a C function returns a value,
255 the corresponding FORTRAN subroutine will have an additional `INTENT(OUT)` parameter
256 passed as the its last argument.
257
258 When you compile the FORTRAN interface, wrapper functions are added with several possible
259 name manglings, so you should not experience problems linking the plumed library with a FORTRAN file.
260
261 \section ReferencePlumedH-exceptions Error handling
262
263 In case an error is detected by PLUMED, either because of some user error, some internal bug,
264 or some mistake in using the library, an exception will be thrown. The behavior is different depending if you use
265 PLUMED from C/FORTRAN or from C++.
266
267 First of all, notice that access to PLUMED goes through three functions:
268 - plumed_create: this, as of PLUMED 2.5, is guaranteed not to throw any exception. If there is a problem, it will
269 just return a plumed object containing a NULL pointer
270 - plumed_cmd: this function might throw exceptions.
271 - plumed_finalize: this is a destructor and is guaranteed not to throw any exception.
272
273 The following discussion concerns all the exceptions thrown by plumed_cmd.
274
275 If you use C/FORTRAN, you will basically have no way to intercept the exception and the program will just terminate.
276
277 If you use C++ but you are calling the C interface (e.g. \ref plumed_cmd), then you might be
278 able to catch the exceptions thrown by PLUMED. Notice that all the exceptions thrown by PLUMED inherit from std::exception,
279 so you might want to catch it by reference. Notice however that there is a C layer between your C++ code and the PLUMED
280 library. In principle, the stack unwinding performed during exception handling is undefined in C and might lead to problems
281 that are system and compiler dependent. In addition to this, there might be troubles when combining different compilers
282 or different standard libraries. E.g., if you MD code is linked against a given C++ library and PLUMED is linked against
283 another one, the two std::exception types will differ and you won't be able to catch exceptions raised by PLUMED.
284
285 If you use C++ and you are calling the C++ interface (e.g. \ref Plumed::cmd), as of PLUMED 2.5 we implemented a complete
286 remapping of the exceptions thrown by PLUMED. This solves both the problems mentioned above. In particular:
287 - Instead of throwing an exception, PLUMED will return (using a \ref plumed_nothrow_handler) the details about the occurred error.
288 - An equivalent exception will be thrown within the inline PLUMED interface compiled with your MD code.
289
290 As a consequence, you will be able to combine different compilers and avoid stack unwinding in the C layer.
291
292 Notice that, even if you use \ref Plumed::cmd, if you are loading a kernel <=2.4 any exception generated by PLUMED will
293 leak through the C layer. This might lead to undefined behavior. If you are lucky (with some compiler it works!) and
294 the exception arrives to C, PLUMED will catch it and rethrow it as it would do if you were using a kernel >=2.5.
295
296 The remapping of exceptions takes care of all the standard C++ exceptions plus all the exceptions raised within
297 PLUMED. Unexpected exceptions that are derived from std::exception will be rethrown as std::exception.
298 Notice that this implies some loss of information, since the original exception might have been of a different type.
299 However, it also implies that the virtual table of the original exception won't be needed anymore. This allows to
300 completely decouple the MD code from the PLUMED library.
301
302 \section ReferencePlumedH-2-5 New in PLUMED 2.5
303
304 The wrappers in PLUMED 2.5 have been completely rewritten with several improvements.
305 The interface is almost perfectly backward compatible, although the behavior of C++ constructors
306 has been modified slightly.
307 In addition, a few new functions are introduced (explicitly marked in the documentation).
308 As a consequence, if your code uses some of the new functions, you will not be able
309 to link it directly with an older PLUMED library (though you will still be able to load
310 an older PLUMED library at runtime). In addition, the reference counter changes slightly
311 the behavior of the C++ methods used to interoperate with C and FORTRAN.
312
313 An important novelty is in the way the runtime loader is implemented.
314 In particular, the loader works also if the symbols of the main executable are not exported.
315 The proper functions from the kernel are indeed searched explicitly now using `dlsym`.
316
317 Some additional features can be enabled using suitable environment variables. In particular:
318 - `PLUMED_LOAD_DEBUG` can be set to report more information about the loading process.
319 - `PLUMED_LOAD_NAMESPACE` can be set to `LOCAL` to load the PLUMED kernel in a separate
320 namespace. The default is global namespace, which is the same behavior of PLUMED <=2.4,
321 and is consistent with what happens when linking PLUMED as a shared library.
322 - `PLUMED_LOAD_NODEEPBIND` can be set to load the PLUMED kernel in not-deepbind mode. Deepbind
323 mode implies that the symbols defined in the library are preferred to other symbols with the same name.
324 Only works on systems supporting `RTLD_DEEPBIND` and is mostly for debugging purposes.
325
326 Another difference is that the implementation of the wrappers is now completely contained in the `Plumed.h`
327 file. You can see that the `Plumed.c` is much simpler now and just includes `Plumed.h`. With a similar
328 procedure you could compile the wrappers directly into your code making it unnecessary to link
329 the libplumedWrapper.a library. The corresponding macros are still subject to change and are not documented here.
330
331 As written above, the plumed object now implements a reference counter. Consider the following example
332 \verbatim
333 plumed p=plumed_create();
334 plumed_cmd(p,"init",NULL);
335 plumed q=plumed_create_reference(p);
336 plumed_finalize(p);
337 // at this stage, object q still exists
338 plumed_cmd(q,"whatever",NULL);
339 plumed_finalize(q);
340 // now plumed has been really finalized
341 \endverbatim
342
343 In other words, every \ref plumed_create, \ref plumed_create_dlopen, \ref plumed_create_reference,
344 \ref plumed_create_reference_f, and \ref plumed_create_reference_v call must be matched by a \ref plumed_finalize.
345 Notice that in C++ whenever an object goes out of scope the reference counter
346 will be decreased. In addition, consider that conversion from C/FORTRAN/void* to C++ implies calling a C++ constructor, that
347 is increases the number of references by one. Converting from C++ to C/FORTRAN/void* instead does not call any constructor,
348 that is the number of references is unchanged.
349
350 The change in the behavior of C++ constructors means that the following code will behave in a backward incompatible manner:
351 \verbatim
352 plumed p=plumed_create();
353 plumed_cmd(p,"init",NULL);
354 Plumed q(p);
355 plumed_finalize(p);
356 // at this stage, object q still exists with PLUMED 2.5
357 // on the other hand, with PLUMED 2.4 object q refers to an
358 // already finalized object
359 q.cmd("whatever",NULL);
360 \endverbatim
361
362 Another difference is that the value of the variable `PLUMED_KERNEL` is read every time a new
363 plumed object is instantiated. So, you might even use it to load different plumed versions
364 simultaneously, although the preferred way to do this is using the function \ref plumed_create_dlopen.
365 Notice that if you want to load multiple versions simultaneously you should load them in a local namespace.
366 \ref plumed_create_dlopen does it automatically, whereas loading through env var `PLUMED_KERNEL` only does it if
367 you also set env var `PLUMED_NAMESPACE=LOCAL`.
368
369 Finally, a few functions have been added, namely:
370 - Functions to find if a plumed object is valid
371 (\ref plumed_valid(), \ref plumed_gvalid(), \ref PLMD::Plumed::valid(), and \ref PLMD::Plumed::gvalid()).
372 - Functions to create a plumed object based on the path of a specific kernel
373 (\ref plumed_create_dlopen() and \ref PLMD::Plumed::dlopen()).
374 - Functions to create a plumed object referencing to another one, implementing a reference counter
375 (\ref plumed_create_reference(), \ref plumed_create_reference_v(), \ref plumed_create_reference_f().
376
377 */
378
379 /* BEGINNING OF DECLARATIONS */
380
381 /* SETTING DEFAULT VALUES FOR CONTROL MACROS */
382
383 /*
384 1: make the C wrapper functions extern (default)
385 0: make the C wrapper functions static (C) or inline (C++)
386
387 If set to zero, it disables all functions that only make sense as extern, such as
388 Fortran wrappers, global objects, and plumed_kernel_register.
389
390 It can be set to zero to include multiple copies of the wrapper implementation without worrying
391 about duplicated symbols.
392
393 Notice that C++ wrappers are always inline. What this function controls is if the C wrappers
394 (called by the C++ wrappers) is inline or not. Also consider that if this header is compiled
395 with C++ and inline C wrappers, the C wrappers will be actually compiled with C++ linkage
396 in the root namespace.
397
398 Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
399 */
400
401 #ifndef __PLUMED_WRAPPER_EXTERN
402 #define __PLUMED_WRAPPER_EXTERN 1
403 #endif
404
405 /*
406 1: emit global plumed object and related functions (default)
407 0: do not emit global plumed object and related functions
408
409 Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
410 */
411
412 #ifndef __PLUMED_WRAPPER_GLOBAL
413 #define __PLUMED_WRAPPER_GLOBAL 1
414 #endif
415
416 /*
417 1: enable C++ wrapper (default)
418 0: disable C++ wrapper
419
420 Only used in declarations, but affects the scope of the C interface also in definitions.
421 */
422
423 #ifndef __PLUMED_WRAPPER_CXX
424 #define __PLUMED_WRAPPER_CXX 1
425 #endif
426
427 /*
428 1: new headers such as cstdlib are included in C++ (default)
429 0: old headers such as stdlib.h are included in C++
430
431 Should only be set to zero when including the Plumed.h file in a file using the
432 old (stdlib.h) convention.
433
434 Used both in declarations and definitions.
435 */
436
437 #ifndef __PLUMED_WRAPPER_CXX_STD
438 #define __PLUMED_WRAPPER_CXX_STD 1
439 #endif
440
441 /*
442 1: place C++ wrappers in an anonymous namespace
443 0: place C++ wrappers in the PLMD namespace (default)
444
445 It will make PLMD::Plumed a different class (though with the same name)
446 in each of the translation units in which `Plumed.h` is included.
447
448 Can be used to completey separate C++ implementations. However, it will make
449 it impossible to transfer Plumed objects between different translation units
450 without converting to a void* or plumed object.
451
452 Only used in declarations, but affects the scope of the C interface also in definitions.
453 */
454
455 #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE
456 #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 0
457 #endif
458
459 /*
460 1: make PLMD::Plumed class polymorphic (default)
461 0: make PLMD::Plumed class non-polymorphic
462
463 Only used in declarations.
464 */
465
466 #ifndef __PLUMED_WRAPPER_CXX_POLYMORPHIC
467 #define __PLUMED_WRAPPER_CXX_POLYMORPHIC 1
468 #endif
469
470 /*
471 1: make the default constructor create an invalid object
472 0: make the default constructor create a valid object
473
474 Only for internal usage.
475 */
476 #ifndef __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
477 #define __PLUMED_WRAPPER_CXX_DEFAULT_INVALID 0
478 #endif
479
480 /*
481 Size of a buffer used to store message for exceptions with noexcept constructor.
482 Should typically hold short messages. Anyway, as long as the stack size stays within the correct
483 limits it does not seem to affect efficiency. Notice that there cannot be recursive calls of
484 PLMD::Plumed::cmd, so that it should be in practice irrelevant.
485 */
486 #ifndef __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER
487 #define __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER 512
488 #endif
489
490
491 /*
492 By default, assume C++11 compliant library is not available.
493 */
494
495 #ifndef __PLUMED_WRAPPER_LIBCXX11
496 #define __PLUMED_WRAPPER_LIBCXX11 0
497 #endif
498
499 /* The following macros are just to define shortcuts */
500
501 /* Simplify addition of extern "C" blocks. */
502 #ifdef __cplusplus
503 #define __PLUMED_WRAPPER_EXTERN_C_BEGIN extern "C" {
504 #define __PLUMED_WRAPPER_EXTERN_C_END }
505 #else
506 #define __PLUMED_WRAPPER_EXTERN_C_BEGIN
507 #define __PLUMED_WRAPPER_EXTERN_C_END
508 #endif
509
510 /* Without C++, stdlib functions should not be prepended with ::std:: */
511 #ifndef __cplusplus
512 #undef __PLUMED_WRAPPER_CXX_STD
513 #define __PLUMED_WRAPPER_CXX_STD 0
514 #endif
515
516 /* Set prefix for stdlib functions */
517 #if __PLUMED_WRAPPER_CXX_STD
518 #define __PLUMED_WRAPPER_STD ::std::
519 #else
520 #define __PLUMED_WRAPPER_STD
521 #endif
522
523 /* Allow using noexcept, explicit, and override with C++11 compilers */
524 #if __cplusplus > 199711L
525 #define __PLUMED_WRAPPER_CXX_NOEXCEPT noexcept
526 #define __PLUMED_WRAPPER_CXX_EXPLICIT explicit
527 #define __PLUMED_WRAPPER_CXX_OVERRIDE override
528 #else
529 #define __PLUMED_WRAPPER_CXX_NOEXCEPT throw()
530 #define __PLUMED_WRAPPER_CXX_EXPLICIT
531 #define __PLUMED_WRAPPER_CXX_OVERRIDE
532 #endif
533
534 /* Macros for anonymous namespace */
535 #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE && defined(__cplusplus) /*{*/
536 #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN namespace {
537 #define __PLUMED_WRAPPER_ANONYMOUS_END }
538 #else
539 #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN
540 #define __PLUMED_WRAPPER_ANONYMOUS_END
541 #endif /*}*/
542
543 #if __PLUMED_WRAPPER_EXTERN /*{*/
544
545 #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN extern
546 #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_EXTERN_C_END
547 #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN static
548 #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_EXTERN_C_END
549
550 #else
551
552 #ifdef __cplusplus
553 #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_ANONYMOUS_BEGIN inline
554 #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_ANONYMOUS_END
555 #else
556 #define __PLUMED_WRAPPER_C_BEGIN static
557 #define __PLUMED_WRAPPER_C_END
558 #endif
559
560 #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_C_BEGIN
561 #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_C_END
562
563 /* with an not-external interface, it does not make sense to define global functions */
564 #undef __PLUMED_WRAPPER_GLOBAL
565 #define __PLUMED_WRAPPER_GLOBAL 0
566
567 #endif /*}*/
568
569 /**
570 \brief Main plumed object
571
572 This is an object containing a Plumed instance, which should be used in
573 the MD engine. It should first be initialized with plumed_create(),
574 then it communicates with the MD engine using plumed_cmd(). Finally,
575 before the termination, it should be deallocated with plumed_finalize().
576 Its interface is very simple and general, and is expected
577 not to change across plumed versions. See \ref ReferencePlumedH.
578 */
579 typedef struct {
580 /**
581 \private
582 \brief Void pointer holding the real PlumedMain structure
583
584 To maintain binary compatibility, we should not add members to this structure.
585 As of PLUMED 2.5, in order to add new components we do not store the pointer
586 to \ref PlumedMain here but rather a pointer to an intermediate private structure
587 that contains all the details.
588 */
589 void*p;
590 } plumed;
591
592 typedef struct {
593 void* ptr;
594 void (*handler)(void*,int,const char*,const void*);
595 } plumed_nothrow_handler;
596
597 /** \relates plumed
598 \brief Constructor
599
600 Constructs a plumed object.
601
602 Notice that if you are linking against libplumedWrapper.a, if you are
603 using a code patched in runtime mode, or if you are including the `Plumed.c`
604 file directly in your code, this constructor might return an invalid plumed
605 object. In particular, this could happen if the `PLUMED_KERNEL` environment
606 variable is not set or set incorrectly. In order to detect an incorrect
607 plumed object you might use \ref plumed_valid() on the resulting object.
608 Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
609 Also notice that to avoid memory leaks you should call \ref plumed_finalize()
610 to finalize a plumed object even if it is invalid:
611 \verbatim
612 plumed p=plumed_create();
613 if(!plumed_valid(p)) {
614 // this will happen if the PLUMED_KERNEL variable is not set correctly
615 plumed_finalize(p);
616 return whatever;
617 }
618 \endverbatim
619
620 \return The constructed plumed object
621 */
622 __PLUMED_WRAPPER_C_BEGIN
623 plumed plumed_create(void);
624 __PLUMED_WRAPPER_C_END
625
626 /** \relates plumed
627 \brief Constructor from path. Available as of PLUMED 2.5
628
629 It tries to construct a plumed object loading the kernel located at path.
630 Notice that it could leave the resulting object in an invalid state.
631 In order to detect an invalid
632 plumed object you might use \ref plumed_valid() on the resulting object.
633 Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
634
635 Also notice that to avoid memory leaks you should call \ref plumed_finalize()
636 to finalize a plumed object even if it is invalid.
637 \verbatim
638 plumed p=plumed_create(path);
639 if(!plumed_valid(p)) {
640 // this will happen if the path argument is not set correctly
641 plumed_finalize(p);
642 return whatever;
643 }
644 \endverbatim
645
646 \return The constructed plumed object
647 */
648 __PLUMED_WRAPPER_C_BEGIN
649 plumed plumed_create_dlopen(const char*path);
650 __PLUMED_WRAPPER_C_END
651
652
653 /**
654 \brief Constructor from path. Available as of PLUMED 2.5
655
656 Same as \ref plumed_create_dlopen, but also allows to specify the mode for dlopen.
657
658 \warning
659 Use with care, since not all the possible modes work correctly with PLUMED.
660 */
661 __PLUMED_WRAPPER_C_BEGIN
662 plumed plumed_create_dlopen2(const char*path,int mode);
663 __PLUMED_WRAPPER_C_END
664
665 /** \relates plumed
666 Create a new reference to an existing object, increasing its reference count. Available as of PLUMED 2.5
667
668 Use it to increase by one the reference count of a plumed object.
669 The resulting pointer might be identical to the one passed as an
670 argument, but the reference count will be incremented by one.
671 Notice that you should finalize the resulting object.
672 \verbatim
673 plumed p1;
674 plumed p2;
675 p1=plumed_create();
676 p2=plumed_create_reference(p1);
677 plumed_finalize(p1);
678 // now you can still use p2
679 plumed_cmd(p2,"init",NULL);
680 plumed_finalize(p2);
681 // now the underlying object is destroyed.
682 \endverbatim
683
684 If the `p` object is invalid, also the returned object will be invalid.
685
686 \param p The plumed object that will be referenced to.
687 \return The constructed plumed object
688 */
689
690 __PLUMED_WRAPPER_C_BEGIN
691 plumed plumed_create_reference(plumed p);
692 __PLUMED_WRAPPER_C_END
693
694 /** \relates plumed
695 \brief Create a new reference to an existing object passed as a void pointer, increasing its reference count. Available as of PLUMED 2.5
696
697 \return The constructed plumed object
698 */
699
700 __PLUMED_WRAPPER_C_BEGIN
701 plumed plumed_create_reference_v(void*v);
702 __PLUMED_WRAPPER_C_END
703
704 /** \relates plumed
705 \brief Create a new reference to an existing object passed as a fortran string, increasing its reference count. Available as of PLUMED 2.5
706
707 \return The constructed plumed object
708 */
709
710 __PLUMED_WRAPPER_C_BEGIN
711 plumed plumed_create_reference_f(const char*f);
712 __PLUMED_WRAPPER_C_END
713
714 /** \relates plumed
715 \brief Constructor as invalid. Available as of PLUMED 2.5
716
717 Can be used to create an object in the same state as if it was returned by
718 plumed_create_dlopen with an incorrect path (or plumed_create using runtime binding
719 and an incorrect PLUMED_KERNEL).
720
721 Can be used to initialize a plumed object to a well-defined state without explicitly
722 creating it. The resulting object can be checked later with \ref plumed_valid.
723 Consider the following example
724 \verbatim
725 plumed p;
726 p=plumed_create_invalid();
727 // at this point p is initialized to a well-defined (invalid) state.
728 setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
729 plumed_finalize(p);
730 p=plumed_create();
731 \endverbatim
732
733 \return The constructed plumed object
734 */
735
736 __PLUMED_WRAPPER_C_BEGIN
737 plumed plumed_create_invalid();
738 __PLUMED_WRAPPER_C_END
739
740 /** \relates plumed
741 \brief Tells p to execute a command.
742
743 If the object is not valid (see \ref plumed_valid), this command will exit.
744
745 \param p The plumed object on which command is acting
746 \param key The name of the command to be executed
747 \param val The argument. It is declared as const to allow calls like plumed_cmd(p,"A","B"),
748 but for some choice of key it can change the content.
749
750 Notice that within PLUMED we use a const_cast to remove any const qualifier from the second
751 argument of \ref plumed_cmd.
752
753 In some cases val can be omitted: just pass a NULL pointer (in C++, val is optional and can be omitted,
754 or you can equivalently pass NULL or nullptr).
755 The set of possible keys is the real API of the plumed library, and will be expanded with time.
756 New commands will be added, but backward compatibility will be retained as long as possible.
757 */
758
759 __PLUMED_WRAPPER_C_BEGIN
760 void plumed_cmd(plumed p,const char*key,const void*val);
761 __PLUMED_WRAPPER_C_END
762
763 /**
764 \relates plumed
765 \brief Same as \ref plumed_cmd, but does not throw exceptions.
766
767 This function is meant to be used when errors should be handled explicitly.
768 if an exception is raised within PLUMED, the function nothrow.handler() will
769 be called with arguments (nothrow.ptr,code,message,opt). This allows the C++ interface
770 to correctly rethrow exceptions, but might be used from C as well. opt can be used
771 to pass further information (not used yet).
772 */
773
774 __PLUMED_WRAPPER_C_BEGIN
775 void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow);
776 __PLUMED_WRAPPER_C_END
777
778 /** \relates plumed
779 \brief Destructor.
780
781 It must be used for any object created using \ref plumed_create(),
782 even if the created object is not valid.
783
784 \param p The plumed object to be deallocated
785 */
786
787 __PLUMED_WRAPPER_C_BEGIN
788 void plumed_finalize(plumed p);
789 __PLUMED_WRAPPER_C_END
790
791 /** \relates plumed
792 \brief Check if plumed is installed (for runtime binding).
793
794 Notice that this is equivalent to creating a dummy object and checking if it is valid.
795
796 \verbatim
797 // this:
798 //int a=plumed_installed();
799 // is equivalent to this:
800
801 plumed p=plumed_create();
802 int a=plumed_valid(p);
803 plumed_finalize(p);
804
805 \endverbatim
806
807 This function is mostly provided for compatibility with PLUMED 2.4, where \ref plumed_valid()
808 was not available. Using \ref plumed_valid() is now preferred since it creates a single object
809 instead of creating a dummy object that is then discarded.
810
811 \return 1 if plumed is installed, 0 otherwise
812 */
813
814 __PLUMED_WRAPPER_C_BEGIN
815 int plumed_installed(void);
816 __PLUMED_WRAPPER_C_END
817
818 /** \relates plumed
819 \brief Check if plumed object is valid. Available as of PLUMED 2.5
820
821 It might return false if plumed is not available at runtime.
822
823 \return 1 if plumed is valid, 0 otherwise
824 */
825
826 __PLUMED_WRAPPER_C_BEGIN
827 int plumed_valid(plumed p);
828 __PLUMED_WRAPPER_C_END
829
830 /** \relates plumed
831 \brief Returns the number of references to the underlying object. Available as of PLUMED 2.5.
832 */
833
834 __PLUMED_WRAPPER_C_BEGIN
835 int plumed_use_count(plumed p);
836 __PLUMED_WRAPPER_C_END
837
838
839 /* routines to convert char handler from/to plumed objects */
840
841 /** \related plumed
842 \brief Converts a C handler to a FORTRAN handler
843
844 \param p The C handler
845 \param c The FORTRAN handler (a char[32])
846
847 This function can be used to convert a plumed object created in C to
848 a plumed handler that can be used in FORTRAN. Notice that the reference counter
849 is not incremented. In other words, the FORTRAN object will be a weak reference.
850 If you later finalize the C handler, the FORTRAN handler will be invalid.
851 \verbatim
852 #include <plumed/wrapper/Plumed.h>
853 int main(int argc,char*argv[]){
854 plumed p;
855 p=plumed_create();
856 char fortran_handler[32];
857 plumed_c2f(p,fortran_handler);
858 printf("DEBUG: this is a string representation for the plumed handler: %s\n",fortran_handler);
859 fortran_routine(fortran_handler);
860 plumed_finalize(p);
861 return 0;
862 }
863 \endverbatim
864 Here `fortran_routine` is a routine implemented in FORTRAN that manipulates the
865 fortran_handler.
866 */
867
868 __PLUMED_WRAPPER_C_BEGIN
869 void plumed_c2f(plumed p,char* c);
870 __PLUMED_WRAPPER_C_END
871
872 /** \related plumed
873 \brief Converts a FORTRAN handler to a C handler
874 \param c The FORTRAN handler (a char[32])
875 \return The C handler
876
877 This function can be used to convert a plumed object created in FORTRAN
878 to a plumed handler that can be used in C. Notice that the reference counter
879 is not incremented. In other words, the C object will be a weak reference.
880 If you later finalize the FORTRAN handler, the C handler will be invalid.
881 \verbatim
882 void c_routine(char handler[32]){
883 plumed p;
884 p=plumed_f2c(handler);
885 plumed_cmd(p,"init",NULL);
886 }
887 \endverbatim
888 Here `c_routine` is a C function that can be called from FORTRAN
889 and interact with the provided plumed handler.
890 */
891
892 __PLUMED_WRAPPER_C_BEGIN
893 plumed plumed_f2c(const char* c);
894 __PLUMED_WRAPPER_C_END
895
896 /** \related plumed
897 \brief Converts a plumed object to a void pointer. Available as of PLUMED 2.5.
898
899 It returns a void pointer that can be converted back to a plumed object using \ref plumed_v2c.
900 When compiling without NDEBUG, it checks if the plumed object was properly created.
901 Notice that an invalid object (see \ref plumed_valid) can be converted to void* and back.
902
903 Can be used to store a reference to a plumed object without including the Plumed.h header.
904 */
905
906 __PLUMED_WRAPPER_C_BEGIN
907 void* plumed_c2v(plumed p);
908 __PLUMED_WRAPPER_C_END
909
910
911 /** \related plumed
912 \brief Converts a void pointer to a plumed object. Available as of PLUMED 2.5.
913
914 It returns a plumed object from a void pointer obtained with \ref plumed_c2v.
915 When compiling without NDEBUG, it checks if the plumed object was properly created.
916
917 Can be used to store a reference to a plumed object without including the Plumed.h header.
918 */
919
920 __PLUMED_WRAPPER_C_BEGIN
921 plumed plumed_v2c(void*);
922 __PLUMED_WRAPPER_C_END
923
924
925 #if __PLUMED_WRAPPER_GLOBAL /*{*/
926
927 /* Global C functions are always extern */
928 __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
929
930 /** \relates plumed
931 \brief Retrieves an handler to the global structure.
932
933 You can use this if you work on a code that uses the global structure and you want to
934 pass to a generic routine an handler to the same structure. E.g.
935
936 \verbatim
937 plumed p=plumed_global();
938 some_routine(p);
939 \endverbatim
940 */
941 extern
942 plumed plumed_global(void);
943
944 /** \relates plumed
945 \brief Check if the global interface has been initialized.
946
947 \return 1 if plumed has been initialized, 0 otherwise
948 */
949 extern
950 int plumed_ginitialized(void);
951
952 /** \relates plumed
953 \brief Constructor for the global interface.
954
955 \note Equivalent to plumed_create(), but initialize the static global plumed object
956 */
957 extern
958 void plumed_gcreate(void);
959
960 /** \relates plumed
961 \brief Tells to the global interface to execute a command.
962
963 \param key The name of the command to be executed
964 \param val The argument. It is declared as const to allow calls like plumed_gcmd("A","B"),
965 but for some choice of key it can change the content
966
967 `plumed_gcmd(a,b);` is equivalent to `plumed_cmd(plumed_global(),a,b);`.
968 */
969 extern
970 void plumed_gcmd(const char* key,const void* val);
971
972 /** \relates plumed
973 \brief Destructor for the global interface.
974
975 `plumed_gfinalize(a,b);` is similar to `plumed_finalize(plumed_global(),a,b);`, but not completely
976 equivalent. In particular, plumed_gfinalize() also makes sure that the global object
977 is reset to its initial status. After calling it, \ref plumed_ginitialized() will thus return 0.
978 */
979 extern
980 void plumed_gfinalize(void);
981
982 /** \relates plumed
983 \brief Check if global plumed object is valid. Available as of PLUMED 2.5
984
985 It might return zero if plumed is not available at runtime.
986
987 \return 1 if plumed is valid, 0 otherwise.
988 */
989 extern
990 int plumed_gvalid();
991
992 __PLUMED_WRAPPER_EXTERN_C_END /*}*/
993
994 #endif /*}*/
995
996 #if defined( __cplusplus) && __PLUMED_WRAPPER_CXX /*{*/
997
998 #if __PLUMED_WRAPPER_CXX_STD
999 #include <cstdlib> /* NULL getenv */
1000 #include <cstring> /* strncat strlen */
1001 #include <cstdio> /* fprintf */
1002 #else
1003 #include <stdlib.h>
1004 #include <string.h>
1005 #include <stdio.h>
1006 #endif
1007
1008 #include <exception> /* exception bad_exception */
1009 #include <stdexcept> /* runtime_error logic_error invalid_argument domain_error length_error out_of_range range_error overflow_error underflow_error */
1010 #include <string> /* string */
1011 #include <ios> /* iostream_category (C++11) ios_base::failure (C++11 and C++<11) */
1012 #include <new> /* bad_alloc bad_array_new_length (C++11) */
1013 #include <typeinfo> /* bad_typeid bad_cast */
1014 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1015 #include <system_error> /* system_error generic_category system_category */
1016 #include <future> /* future_category */
1017 #include <memory> /* bad_weak_ptr */
1018 #include <functional> /* bad_function_call */
1019 #endif
1020
1021 /* C++ interface is hidden in PLMD namespace (same as plumed library) */
1022 namespace PLMD {
1023
1024 /**
1025 Retrieve PLUMED_EXCEPTIONS_DEBUG (internal utility).
1026
1027 This function should not be used by external programs. It is defined
1028 as inline static so that it can store a static variable (for quicker access)
1029 without adding a unique global symbol to a library including this header file.
1030 */
PlumedGetenvExceptionsDebug()1031 inline static bool PlumedGetenvExceptionsDebug() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1032 static const char* res=__PLUMED_WRAPPER_STD getenv("PLUMED_EXCEPTIONS_DEBUG");
1033 return res;
1034 }
1035
1036 /* Optionally, it is further hidden in an anonymous namespace */
1037
1038 __PLUMED_WRAPPER_ANONYMOUS_BEGIN /*{*/
1039
1040 /**
1041 C++ wrapper for \ref plumed.
1042
1043 This class provides a C++ interface to PLUMED.
1044 It only containts a \ref plumed object, but wraps it with a number of useful methods.
1045 All methods are inlined so as to avoid the compilation of an extra c++ file.
1046
1047 */
1048
1049 class Plumed {
1050 /**
1051 C structure.
1052 */
1053 plumed main;
1054
1055 /**
1056 Error handler used to rethrow exceptions.
1057 */
1058
1059 struct NothrowHandler {
1060 /** code used for translating messages */
1061 int code;
1062 /** short message buffer for non-throwing exceptions */
1063 char exception_buffer[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER];
1064 /** if exception_buffer='\0', message stored as an allocatable string */
1065 ::std::string what;
1066 /** error code for system_error */
1067 int error_code;
1068 };
1069
1070 /**
1071 Callback function that sets the error handler.
1072
1073 opt argument is interpreted as the pointer to a null terminated array of void*.
1074 The number of non-null element is expected to be even, and there should be a null element
1075 that follows. Every pair of pointers should point
1076 to a char, identifying the type of argument passed, and an arbitrary object.
1077 Currently used to (optionally) pass error_code.
1078 */
nothrow_handler(void * ptr,int code,const char * what,const void * opt)1079 static void nothrow_handler(void*ptr,int code,const char*what,const void* opt) {
1080 NothrowHandler* h=(NothrowHandler*) ptr;
1081 h->code=code;
1082 h->exception_buffer[0]='\0';
1083 h->what.clear();
1084 h->error_code=0;
1085 /*
1086 These codes correspond to exceptions that should not allocate a separate buffer but use the fixed one.
1087 Notice that a mismatch between the exceptions using the stack buffer here and those implementing
1088 the stack buffer would be in practice harmless. However, it makes sense to be consistent.
1089 */
1090 if(code==10000 || (code>=11000 && code<12000)) {
1091 __PLUMED_WRAPPER_STD strncat(h->exception_buffer,what,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1);
1092 } else {
1093 h->what=what;
1094 }
1095
1096 /* interpret optional arguments */
1097 const void** options=(const void**)opt;
1098 if(options) while(*options) {
1099 if(*((char*)*options)=='c') h->error_code=*((int*)*(options+1));
1100 options+=2;
1101 }
1102
1103 if(PlumedGetenvExceptionsDebug()) {
1104 __PLUMED_WRAPPER_STD fprintf(stderr,"+++ PLUMED_EXCEPTIONS_DEBUG\n");
1105 __PLUMED_WRAPPER_STD fprintf(stderr,"+++ code: %d error_code: %d message:\n%s\n",h->code,h->error_code,what);
1106 if(__PLUMED_WRAPPER_STD strlen(what) > __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1) __PLUMED_WRAPPER_STD fprintf(stderr,"+++ WARNING: message will be truncated\n");
1107 __PLUMED_WRAPPER_STD fprintf(stderr,"+++ END PLUMED_EXCEPTIONS_DEBUG\n");
1108 }
1109
1110 }
1111
1112 /**
1113 Rethrow the exception based on the information saved in the NothrowHandler.
1114 */
1115
rethrow(const NothrowHandler & h)1116 static void rethrow(const NothrowHandler&h) {
1117 /* The interpretation of the codes should be kept in sync with core/PlumedMainInitializer.cpp */
1118 /* check if we are using a full string or a fixes size buffer */
1119 const char* msg=(h.exception_buffer[0]?h.exception_buffer:h.what.c_str());
1120 if(h.code==1) throw Plumed::Invalid(msg);
1121 /* logic errors */
1122 if(h.code>=10100 && h.code<10200) {
1123 if(h.code>=10105 && h.code<10110) throw ::std::invalid_argument(msg);
1124 if(h.code>=10110 && h.code<10115) throw ::std::domain_error(msg);
1125 if(h.code>=10115 && h.code<10120) throw ::std::length_error(msg);
1126 if(h.code>=10120 && h.code<10125) throw ::std::out_of_range(msg);
1127 throw ::std::logic_error(msg);
1128 }
1129 /* runtime errors */
1130 if(h.code>=10200 && h.code<10300) {
1131 if(h.code>=10205 && h.code<10210) throw ::std::range_error(msg);
1132 if(h.code>=10210 && h.code<10215) throw ::std::overflow_error(msg);
1133 if(h.code>=10215 && h.code<10220) throw ::std::underflow_error(msg);
1134 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1135 if(h.code==10220) throw ::std::system_error(h.error_code,::std::generic_category(),msg);
1136 if(h.code==10221) throw ::std::system_error(h.error_code,::std::system_category(),msg);
1137 if(h.code==10222) throw ::std::system_error(h.error_code,::std::iostream_category(),msg);
1138 if(h.code==10223) throw ::std::system_error(h.error_code,::std::future_category(),msg);
1139 #endif
1140 if(h.code>=10230 && h.code<10240) {
1141 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1142 // These cases are probably useless as it looks like this should always be std::iostream_category
1143 if(h.code==10230) throw ::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::generic_category()));
1144 if(h.code==10231) throw ::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::system_category()));
1145 if(h.code==10232) throw ::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::iostream_category()));
1146 if(h.code==10233) throw ::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::future_category()));
1147 #endif
1148 throw ::std::ios_base::failure(msg);
1149 }
1150 throw ::std::runtime_error(msg);
1151 }
1152 /* "bad" errors */
1153 if(h.code>=11000 && h.code<11100) throw Plumed::std_bad_typeid(msg);
1154 if(h.code>=11100 && h.code<11200) throw Plumed::std_bad_cast(msg);
1155 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1156 if(h.code>=11200 && h.code<11300) throw Plumed::std_bad_weak_ptr(msg);
1157 if(h.code>=11300 && h.code<11400) throw Plumed::std_bad_function_call(msg);
1158 #endif
1159 if(h.code>=11400 && h.code<11500) {
1160 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1161 if(h.code>=11410 && h.code<11420) throw Plumed::std_bad_array_new_length(msg);
1162 #endif
1163 throw Plumed::std_bad_alloc(msg);
1164 }
1165 if(h.code>=11500 && h.code<11600) throw Plumed::std_bad_exception(msg);
1166 /* lepton error */
1167 if(h.code>=19900 && h.code<20000) throw Plumed::LeptonException(msg);
1168 /* plumed exceptions */
1169 if(h.code>=20000 && h.code<30000) {
1170 /* debug - only raised with debug options */
1171 if(h.code>=20100 && h.code<20200) throw Plumed::ExceptionDebug(msg);
1172 /* error - runtime check */
1173 if(h.code>=20200 && h.code<20300) throw Plumed::ExceptionError(msg);
1174 throw Plumed::Exception(msg);
1175 }
1176 /* fallback for any other exception */
1177 throw Plumed::std_exception(msg);
1178 }
1179
1180 /**
1181 Rethrow the current exception.
1182
1183 This is useful in order to handle an exception thrown by a kernel <=2.4.
1184 Only std exceptions are handled, though some of them are thrown as special
1185 Plumed exceptions in order to be attached a message.
1186 */
rethrow()1187 static void rethrow() {
1188 try {
1189 throw;
1190 } catch(const ::std::bad_exception & e) {
1191 throw Plumed::std_bad_exception(e.what());
1192 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1193 } catch(const ::std::bad_array_new_length & e) {
1194 throw Plumed::std_bad_array_new_length(e.what());
1195 #endif
1196 } catch(const ::std::bad_alloc & e) {
1197 throw Plumed::std_bad_alloc(e.what());
1198 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1199 } catch(const ::std::bad_function_call & e) {
1200 throw Plumed::std_bad_function_call(e.what());
1201 } catch(const ::std::bad_weak_ptr & e) {
1202 throw Plumed::std_bad_weak_ptr(e.what());
1203 #endif
1204 } catch(const ::std::bad_cast & e) {
1205 throw Plumed::std_bad_cast(e.what());
1206 } catch(const ::std::bad_typeid & e) {
1207 throw Plumed::std_bad_typeid(e.what());
1208 // not implemented yet: std::regex_error
1209 // we do not allow regex yet due to portability problems with gcc 4.8
1210 // as soon as we transition to using <regex> it should be straightforward to add
1211 } catch(const ::std::ios_base::failure & e) {
1212 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1213 throw ::std::ios_base::failure(e.what(),e.code());
1214 #else
1215 throw ::std::ios_base::failure(e.what());
1216 #endif
1217 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1218 } catch(const ::std::system_error & e) {
1219 throw ::std::system_error(e.code(),e.what());
1220 #endif
1221 } catch(const ::std::underflow_error &e) {
1222 throw ::std::underflow_error(e.what());
1223 } catch(const ::std::overflow_error &e) {
1224 throw ::std::overflow_error(e.what());
1225 } catch(const ::std::range_error &e) {
1226 throw ::std::range_error(e.what());
1227 } catch(const ::std::runtime_error & e) {
1228 throw ::std::runtime_error(e.what());
1229 // not implemented yet: std::future_error
1230 // not clear how useful it would be.
1231 } catch(const ::std::out_of_range & e) {
1232 throw ::std::out_of_range(e.what());
1233 } catch(const ::std::length_error & e) {
1234 throw ::std::length_error(e.what());
1235 } catch(const ::std::domain_error & e) {
1236 throw ::std::domain_error(e.what());
1237 } catch(const ::std::invalid_argument & e) {
1238 throw ::std::invalid_argument(e.what());
1239 } catch(const ::std::logic_error & e) {
1240 throw ::std::logic_error(e.what());
1241 } catch(const ::std::exception & e) {
1242 throw Plumed::std_exception(e.what());
1243 } catch(...) {
1244 throw Plumed::std_bad_exception("plumed could not translate exception");
1245 }
1246 }
1247
1248 public:
1249
1250 /**
1251 Base class used to rethrow PLUMED exceptions.
1252 */
1253
1254 class Exception :
1255 public ::std::exception
1256 {
1257 ::std::string msg;
1258 public:
Exception(const char * msg)1259 __PLUMED_WRAPPER_CXX_EXPLICIT Exception(const char* msg): msg(msg) {}
what()1260 const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
1261 #if ! (__cplusplus > 199711L)
1262 /* Destructor should be declared in order to have the correct throw() before C++11 */
1263 /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
throw()1264 ~Exception() throw() {}
1265 #endif
1266 };
1267
1268 /**
1269 Used to rethrow a PLMD::ExceptionError
1270 */
1271
1272 class ExceptionError :
1273 public Exception {
1274 public:
ExceptionError(const char * msg)1275 __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionError(const char* msg): Exception(msg) {}
1276 #if ! (__cplusplus > 199711L)
1277 /* Destructor should be declared in order to have the correct throw() before C++11 */
1278 /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
throw()1279 ~ExceptionError() throw() {}
1280 #endif
1281 };
1282
1283 /**
1284 Used to rethrow a PLMD::ExceptionDebug
1285 */
1286
1287 class ExceptionDebug :
1288 public Exception {
1289 public:
ExceptionDebug(const char * msg)1290 __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionDebug(const char* msg): Exception(msg) {}
1291 #if ! (__cplusplus > 199711L)
1292 /* Destructor should be declared in order to have the correct throw() before C++11 */
1293 /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
throw()1294 ~ExceptionDebug() throw() {}
1295 #endif
1296 };
1297
1298 /**
1299 Thrown when trying to access an invalid plumed object
1300 */
1301
1302 class Invalid :
1303 public Exception {
1304 public:
Invalid(const char * msg)1305 __PLUMED_WRAPPER_CXX_EXPLICIT Invalid(const char* msg): Exception(msg) {}
1306 #if ! (__cplusplus > 199711L)
1307 /* Destructor should be declared in order to have the correct throw() before C++11 */
1308 /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
throw()1309 ~Invalid() throw() {}
1310 #endif
1311 };
1312
1313 /**
1314 Class used to rethrow Lepton exceptions.
1315 */
1316
1317 class LeptonException :
1318 public ::std::exception
1319 {
1320 ::std::string msg;
1321 public:
LeptonException(const char * msg)1322 __PLUMED_WRAPPER_CXX_EXPLICIT LeptonException(const char* msg): msg(msg) {}
what()1323 const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
1324 #if ! (__cplusplus > 199711L)
1325 /* Destructor should be declared in order to have the correct throw() before C++11 */
1326 /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
throw()1327 ~LeptonException() throw() {}
1328 #endif
1329 };
1330
1331 private:
1332 /*
1333 These exceptions are declared as private as they are not supposed to be
1334 catched by value. they only exist to allow a buffer to be attached to
1335 the std::exceptions that do not contain it already.
1336 Notice that these exceptions are those whose constructor should never throw, and as
1337 such they use a fixed size buffer.
1338 */
1339
1340 #define __PLUMED_WRAPPER_NOSTRING_EXCEPTION(name) \
1341 class std_ ## name : \
1342 public ::std::name \
1343 { \
1344 char msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER]; \
1345 public: \
1346 __PLUMED_WRAPPER_CXX_EXPLICIT std_ ## name(const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
1347 this->msg[0]='\0'; \
1348 __PLUMED_WRAPPER_STD strncat(this->msg,msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1); \
1349 if(PlumedGetenvExceptionsDebug() && __PLUMED_WRAPPER_STD strlen(msg) > __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1) __PLUMED_WRAPPER_STD fprintf(stderr,"+++ WARNING: message will be truncated\n"); \
1350 } \
1351 std_ ## name(const std_ ## name & other) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
1352 msg[0]='\0'; \
1353 __PLUMED_WRAPPER_STD strncat(msg,other.msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1); \
1354 } \
1355 std_ ## name & operator=(const std_ ## name & other) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
1356 if(this==&other) return *this;\
1357 msg[0]='\0'; \
1358 __PLUMED_WRAPPER_STD strncat(msg,other.msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1); \
1359 return *this; \
1360 } \
1361 const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg;} \
1362 ~std_ ## name() __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {} \
1363 };
1364
__PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_typeid)1365 __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_typeid)
1366 __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_cast)
1367 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1368 __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_weak_ptr)
1369 __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_function_call)
1370 #endif
1371 __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_alloc)
1372 #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1373 __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_array_new_length)
1374 #endif
1375 __PLUMED_WRAPPER_NOSTRING_EXCEPTION(bad_exception)
1376 __PLUMED_WRAPPER_NOSTRING_EXCEPTION(exception)
1377
1378 public:
1379
1380 /**
1381 Check if plumed is installed (for runtime binding)
1382 \return true if plumed is installed, false otherwise
1383 \note Equivalent to plumed_installed() but returns a bool
1384 */
1385 static bool installed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1386 return plumed_installed();
1387 }
1388 /**
1389 Check if Plumed object is valid. Available as of PLUMED 2.5
1390 \return true if plumed is valid, false otherwise
1391 \note Equivalent to plumed_valid() but returns a bool
1392 */
valid()1393 bool valid() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
1394 return plumed_valid(main);
1395 }
1396 #if __cplusplus > 199711L
1397 /**
1398 Same as \ref valid(). Available as of PLUMED 2.5.
1399
1400 Allow code such as
1401 \verbatim
1402 Plumed p;
1403 if(!p) raise_error();
1404 p.cmd("init");
1405 \endverbatim
1406
1407 In order to avoid ambiguous conversions, this is only allowed when compiling with C++11
1408 where it is marked as explicit.
1409 */
1410 explicit
1411 operator bool() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
1412 return plumed_valid(main);
1413 }
1414 #endif
1415
1416 /**
1417 Returns the number of references to this object. Available as of PLUMED 2.5.
1418 \note Equivalent to plumed_use_count()
1419 */
useCount()1420 int useCount() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
1421 return plumed_use_count(main);
1422 }
1423
1424 #if __PLUMED_WRAPPER_GLOBAL /*{*/
1425 /**
1426 Check if global-plumed has been initialized
1427 \return true if global plumed object (see global()) is initialized (i.e. if gcreate() has been
1428 called), false otherwise.
1429 \note Equivalent to plumed_ginitialized() but returns a bool
1430 */
ginitialized()1431 static bool ginitialized() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1432 return plumed_ginitialized();
1433 }
1434 /**
1435 Check if global-plumed is valid
1436 \return true if global plumed object (see global()) is valid.
1437 \note Equivalent to plumed_gvalid() but returns a bool
1438 */
gvalid()1439 static bool gvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1440 return plumed_gvalid();
1441 }
1442 /**
1443 Initialize global-plumed.
1444 \note Equivalent to plumed_gcreate()
1445 */
gcreate()1446 static void gcreate() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1447 plumed_gcreate();
1448 }
1449 /**
1450 Send a command to global-plumed
1451 \param key The name of the command to be executed
1452 \param val The argument. It is declared as const to allow calls like gcmd("A","B"),
1453 but for some choice of key it can change the content
1454 \note Equivalent to plumed_gcmd()
1455 */
1456 static void gcmd(const char* key,const void* val=NULL) {
1457 global().cmd(key,val);
1458 }
1459 /**
1460 Finalize global-plumed
1461 */
gfinalize()1462 static void gfinalize() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1463 plumed_gfinalize();
1464 }
1465 /**
1466 Returns the Plumed global object
1467
1468 Notice that the object is copied, thus increasing the reference counter of the
1469 global object. In this manner, the global object will survive after a call to
1470 \ref gfinalize() if the resulting object is still in scope.
1471
1472 \return The Plumed global object
1473 */
global()1474 static Plumed global() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1475 return Plumed(plumed_global());
1476 }
1477 #endif /*}*/
1478 /**
1479 Constructor.
1480
1481 Notice that when using runtime binding the constructed object might be
1482 invalid. One might check it using the \ref valid() method.
1483
1484 \note Performs the same task a plumed_create()
1485 */
Plumed()1486 Plumed()__PLUMED_WRAPPER_CXX_NOEXCEPT :
1487 #if __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
1488 main(plumed_create_invalid())
1489 #else
1490 main(plumed_create())
1491 #endif
1492 {
1493 }
1494
1495 /**
1496 Clone a Plumed object from a FORTRAN char* handler.
1497
1498 \param c The FORTRAN handler (a char[32]).
1499
1500 The reference counter for the corresponding object will be increased
1501 to make sure that the object will be available after plumed_f_finalize is called
1502 if the created object is still in scope.
1503 */
Plumed(const char * c)1504 __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(const char*c)__PLUMED_WRAPPER_CXX_NOEXCEPT :
1505 main(plumed_create_reference_f(c))
1506 {
1507 }
1508
1509 /**
1510 Create a reference from a void* pointer. Available as of PLUMED 2.5.
1511 */
Plumed(void * v)1512 __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(void*v)__PLUMED_WRAPPER_CXX_NOEXCEPT :
1513 main(plumed_create_reference_v(v))
1514 {
1515 }
1516
1517 /**
1518 Clone a Plumed object from a C plumed structure
1519
1520 \param p The C plumed structure.
1521
1522 The reference counter for the corresponding object will be increased
1523 to make sure that the object will be available after plumed_finalize is called
1524 if the created object is still in scope.
1525 */
Plumed(plumed p)1526 __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(plumed p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
1527 main(plumed_create_reference(p))
1528 {
1529 }
1530
1531 /** Copy constructor.
1532
1533 Takes a reference, incrementing the reference counter of the corresponding object.
1534 */
Plumed(const Plumed & p)1535 Plumed(const Plumed& p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
1536 main(plumed_create_reference(p.main))
1537 {
1538 }
1539
1540 /** Assignment operator. Available as of PLUMED 2.5.
1541
1542 Takes a reference,incrementing the reference counter of the corresponding object.
1543 */
1544 Plumed&operator=(const Plumed&p) __PLUMED_WRAPPER_CXX_NOEXCEPT {
1545 if(this != &p) {
1546 // the check is needed to avoid calling plumed_finalize on moved objects
1547 if(main.p) decref();
1548 main=plumed_create_reference(p.main);
1549 }
1550 return *this;
1551 }
1552
1553 /*
1554 PLUMED >= 2.4 requires a C++11 compiler.
1555 Anyway, since Plumed.h file might be redistributed with other codes
1556 and it should be possible to combine it with earlier PLUMED versions,
1557 we here explicitly check if C+11 is available before enabling move semantics.
1558 */
1559 #if __cplusplus > 199711L
1560 /** Move constructor. Available as of PLUMED 2.5.
1561 Only if move semantics is enabled.
1562 */
Plumed(Plumed && p)1563 Plumed(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
1564 main(p.main)
1565 {
1566 p.main.p=nullptr;
1567 }
1568 /** Move assignment. Available as of PLUMED 2.5.
1569 Only if move semantics is enabled.
1570 */
1571 Plumed& operator=(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT {
1572 if(this != &p) {
1573 // the check is needed to avoid calling plumed_finalize on moved objects
1574 if(main.p) decref();
1575 main=p.main;
1576 p.main.p=nullptr;
1577 }
1578 return *this;
1579 }
1580 #endif
1581 /**
1582 Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
1583
1584 It returns an object created with \ref plumed_create_dlopen. The object is owned and
1585 is then finalized in the destructor. It can be used as follows:
1586 \verbatim
1587 PLMD::Plumed p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
1588 // or, equivalenty:
1589 // PLMD::Plumed p(PLMD::Plumed::dlopen("/path/to/libplumedKernel.so"));
1590 p.cmd("init");
1591 \endverbatim
1592 or, equivalently, as
1593 \verbatim
1594 auto p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
1595 p.cmd("init");
1596 \endverbatim
1597 */
dlopen(const char * path)1598 static Plumed dlopen(const char* path)__PLUMED_WRAPPER_CXX_NOEXCEPT {
1599 // use decref to remove the extra reference
1600 return Plumed(plumed_create_dlopen(path)).decref();
1601 }
1602
1603 /**
1604 Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
1605
1606 Same as \ref dlopen(const char* path), but allows a dlopen mode to be chosen explicitly.
1607 */
dlopen(const char * path,int mode)1608 static Plumed dlopen(const char* path,int mode)__PLUMED_WRAPPER_CXX_NOEXCEPT {
1609 // use decref to remove the extra reference
1610 return Plumed(plumed_create_dlopen2(path,mode)).decref();
1611 }
1612 /** Invalid constructor. Available as of PLUMED 2.5.
1613
1614 Can be used to initialize an invalid object. It might be useful to postpone
1615 the initialization of a Plumed object. Consider the following case
1616 \verbatim
1617 Plumed p;
1618 setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
1619 p.cmd("init")
1620 \endverbatim
1621 Here the `p` object will be initialized *before* the `PLUMED_KERNEL` env var has been set.
1622 This can be particularly problematic if `p` is stored in some high level class.
1623 The following case would do the job
1624 \verbatim
1625 Plumed p;
1626 setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
1627 p=Plumed();
1628 p.cmd("init")
1629 \endverbatim
1630 However, there will be some error reported related to the attempt to load the kernel
1631 when `p` is initialized. The following solution is the optimal one:
1632 \verbatim
1633 Plumed p(Plumed::makeInvalid());
1634 setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
1635 p=Plumed();
1636 p.cmd("init")
1637 \endverbatim
1638 */
makeInvalid()1639 static Plumed makeInvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1640 // use decref to remove the extra reference
1641 return Plumed(plumed_create_invalid()).decref();
1642 }
1643
1644 /**
1645 Create a valid PLMD::Plumed object.
1646
1647 Can be used to create a valid object e.g. when Plumed.h was compiled with
1648 `-D__PLUMED_WRAPPER_CXX_DEFAULT_INVALID`. For internal usage.
1649 */
1650
makeValid()1651 static Plumed makeValid()__PLUMED_WRAPPER_CXX_NOEXCEPT {
1652 // use decref to remove the extra reference
1653 return Plumed(plumed_create()).decref();
1654 }
1655
1656
1657 /**
1658 Retrieve the C plumed structure for this object.
1659
1660 Notice that the resulting plumed structure is a weak reference and
1661 should NOT be finalized, unless a new reference is explicitly added
1662 \verbatim
1663 Plumed p;
1664 plumed c=p;
1665 plumed_finalize(c); // <- this is wrong
1666 \endverbatim
1667 \verbatim
1668 Plumed p;
1669 plumed c=plumed_create_reference(p);
1670 plumed_finalize(c); // <- this is right
1671 \endverbatim
1672 */
plumed()1673 operator plumed()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
1674 return main;
1675 }
1676
1677 /**
1678 Retrieve a FORTRAN handler for this object
1679 \param c The FORTRAN handler (a char[32]).
1680 Notice that the resulting plumed structure is a weak reference and
1681 should NOT be finalized, unless a new reference is explicitly added.
1682 */
toFortran(char * c)1683 void toFortran(char*c)const __PLUMED_WRAPPER_CXX_NOEXCEPT {
1684 plumed_c2f(main,c);
1685 }
1686
1687 /**
1688 Retrieve a void* handler for this object. Available as of PLUMED 2.5.
1689 Notice that the resulting plumed structure is a weak reference and
1690 should NOT be finalized, unless a new reference is explicitly added.
1691 */
toVoid()1692 void* toVoid()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
1693 return plumed_c2v(main);
1694 }
1695
1696 /**
1697 Increase reference counter. Available as of PLUMED 2.5.
1698
1699 Using this method improperly might interfere with correct object construction
1700 and destruction.
1701 If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
1702
1703 A possible usage is to transfer the ownership of a temporary
1704 object when it is converted
1705 \verbatim
1706 plumed p=Plumed::dlopen(path).incref()
1707 // without incref(), the just constructed object will be destroyed
1708 // when the temporary object is deleted.
1709 ... do stuff ...
1710 plumed_finalize(p);
1711 \endverbatim
1712
1713 */
incref()1714 Plumed& incref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1715 plumed_create_reference(main);
1716 return *this;
1717 }
1718
1719 /**
1720 Decrease reference counter. Available as of PLUMED 2.5.
1721
1722 Using this method improperly might interfere with correct object construction
1723 and destruction.
1724 If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
1725 */
decref()1726 Plumed& decref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1727 // calling decref on a moved plumed object should give an error, so we do not check if main.p!=NULL here:
1728 plumed_finalize(main);
1729 return *this;
1730 }
1731
1732 /**
1733 Send a command to this plumed object
1734 \param key The name of the command to be executed
1735 \param val The argument. It is declared as const to allow calls like p.cmd("A","B"),
1736 but for some choice of key it can change the content
1737 \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
1738 rethrow any exception raised within PLUMED.
1739 */
1740 void cmd(const char*key,const void*val=NULL) {
1741 NothrowHandler h;
1742 h.code=0;
1743 plumed_nothrow_handler nothrow= {&h,nothrow_handler};
1744 try {
1745 plumed_cmd_nothrow(main,key,val,nothrow);
catch(...)1746 } catch (...) {
1747 /*
1748 When loading a kernel <=2.4, plumed_cmd_nothrow could throw an exception.
1749 If the exception is transmitted through the C interface and arrives here,
1750 we translate it so as to free the virtual tables of the loaded kernel.
1751 */
1752 rethrow();
1753 }
1754 if(h.code!=0) rethrow(h);
1755 }
1756
1757 /**
1758 Destructor
1759
1760 It calls \ref plumed_finalize(). Notice that this is done also if the
1761 constructor failed (that is, if it returned an invalid object). This allows
1762 declaring Plumed objects also if PLUMED is actually not available, provided
1763 one does not use the \ref cmd method.
1764
1765 Destructor is virtual so as to allow correct inheritance from Plumed object.
1766 */
1767 #if __PLUMED_WRAPPER_CXX_POLYMORPHIC
1768 virtual
1769 #endif
~Plumed()1770 ~Plumed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1771 // the check is needed to avoid calling plumed_finalize on moved objects
1772 if(main.p) decref();
1773 }
1774 };
1775
1776 /**
1777 \related Plumed
1778 Comparison operator. Available as of PLUMED 2.5.
1779 */
1780 inline
1781 bool operator==(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
1782 return a.toVoid()==b.toVoid();
1783 }
1784
1785 /**
1786 \related Plumed
1787 Comparison operator. Available as of PLUMED 2.5.
1788 */
1789 inline
1790 bool operator!=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
1791 return a.toVoid()!=b.toVoid();
1792 }
1793
1794 /**
1795 \related Plumed
1796 Comparison operator. Available as of PLUMED 2.5.
1797 */
1798 inline
1799 bool operator<=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
1800 return a.toVoid()<=b.toVoid();
1801 }
1802
1803 /**
1804 \related Plumed
1805 Comparison operator. Available as of PLUMED 2.5.
1806 */
1807 inline
1808 bool operator<(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
1809 return a.toVoid()<b.toVoid();
1810 }
1811
1812 /**
1813 \related Plumed
1814 Comparison operator. Available as of PLUMED 2.5.
1815 */
1816 inline
1817 bool operator>=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
1818 return a.toVoid()>=b.toVoid();
1819 }
1820
1821 /**
1822 \related Plumed
1823 Comparison operator. Available as of PLUMED 2.5.
1824 */
1825 inline
1826 bool operator>(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
1827 return a.toVoid()>b.toVoid();
1828 }
1829
1830 __PLUMED_WRAPPER_ANONYMOUS_END /*}*/
1831
1832 }
1833
1834 #endif /*}*/
1835
1836 #endif /*}*/
1837
1838 /* END OF DECLARATIONS */
1839
1840 /*
1841
1842 1: emit implementation
1843 0: do not emit implementation
1844
1845 Allows an implementation to be emitted together with the declarations.
1846
1847 Used to decide if definitions should be emitted. This macro could have a different
1848 value when Plumed.h is reincluded. As a consequence, we map it to a local
1849 macro (__PLUMED_WRAPPER_IMPLEMENTATION_) that is reset at the end of this file.
1850 */
1851
1852 #ifdef __PLUMED_WRAPPER_IMPLEMENTATION
1853 #define __PLUMED_WRAPPER_IMPLEMENTATION_ __PLUMED_WRAPPER_IMPLEMENTATION
1854 #else
1855 #define __PLUMED_WRAPPER_IMPLEMENTATION_ 0
1856 #endif
1857
1858 /* BEGINNING OF DEFINITIONS */
1859
1860 #if __PLUMED_WRAPPER_IMPLEMENTATION_ /*{*/
1861 #ifndef __PLUMED_wrapper_Plumed_implementation /*{*/
1862 #define __PLUMED_wrapper_Plumed_implementation
1863
1864 /*
1865 the following macros only control the implementation
1866 */
1867
1868 /*
1869 1: enable the definition of plumed_symbol_table_reexport
1870 0: does not enable the definition of plumed_symbol_table_reexport
1871
1872 This is only needed in the official plumed library to make
1873 the symbol table available. This is a hack to reexport the function table
1874 and is only needed when creating the library libplumed.so.
1875 */
1876
1877 #ifndef __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
1878 #define __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE 0
1879 #endif
1880
1881 /*
1882 1: write on stderr changes in reference counters
1883 0: do not write changes in reference counters
1884
1885 Used for debugging.
1886
1887 Only used in definitions.
1888 */
1889
1890 #ifndef __PLUMED_WRAPPER_DEBUG_REFCOUNT
1891 #define __PLUMED_WRAPPER_DEBUG_REFCOUNT 0
1892 #endif
1893
1894 /*
1895 1: emit plumed_kernel_register function (default)
1896 0: do not emit plumed_kernel_register function
1897
1898 This function is only needed to avoid an extra warning when loading old (<=2.4) kernels.
1899 We might change its default in the future.
1900
1901 Used only in definitions.
1902 */
1903
1904 #ifndef __PLUMED_WRAPPER_KERNEL_REGISTER
1905 #define __PLUMED_WRAPPER_KERNEL_REGISTER 1
1906 #endif
1907
1908 /*
1909 1: emit Fortran wrappers
1910 0: do not emit Fortran wrappers (default)
1911
1912 Used only in definitions.
1913 */
1914
1915 #ifndef __PLUMED_WRAPPER_FORTRAN
1916 #define __PLUMED_WRAPPER_FORTRAN 0
1917 #endif
1918
1919 /*
1920 With internal interface, it does not make sense to emit kernel register or fortran interfaces
1921 */
1922
1923 #if ! __PLUMED_WRAPPER_EXTERN /*{*/
1924 #undef __PLUMED_WRAPPER_KERNEL_REGISTER
1925 #define __PLUMED_WRAPPER_KERNEL_REGISTER 0
1926 #undef __PLUMED_WRAPPER_FORTRAN
1927 #define __PLUMED_WRAPPER_FORTRAN 0
1928 #endif /*}*/
1929
1930 #ifdef __PLUMED_HAS_DLOPEN
1931 #include <dlfcn.h> /* dlopen dlerror dlsym */
1932 #endif
1933
1934 #if __PLUMED_WRAPPER_CXX_STD
1935 #include <cstdio> /* fprintf */
1936 #include <cstring> /* memcpy strlen strncpy memcmp memmove strcmp memcpy */
1937 #include <cassert> /* assert */
1938 #include <cstdlib> /* getenv malloc free abort exit */
1939 #include <climits> /* CHAR_BIT */
1940 #else
1941 #include <stdio.h>
1942 #include <string.h>
1943 #include <assert.h>
1944 #include <stdlib.h>
1945 #include <limits.h>
1946 #endif
1947
1948 /**
1949 Function pointer to plumed_create
1950 */
1951
1952 typedef void*(*plumed_create_pointer)(void);
1953 /**
1954 Function pointer to plumed_cmd
1955 */
1956 typedef void(*plumed_cmd_pointer)(void*,const char*,const void*);
1957
1958 /**
1959 Function pointer to plumed_finalize
1960 */
1961 typedef void(*plumed_finalize_pointer)(void*);
1962
1963 /**
1964 Holder for plumedmain function pointers.
1965 */
1966 typedef struct {
1967 plumed_create_pointer create;
1968 plumed_cmd_pointer cmd;
1969 plumed_finalize_pointer finalize;
1970 } plumed_plumedmain_function_holder;
1971
1972 /**
1973 Holder for plumed symbol table.
1974
1975 The table contains pointers to function exported from plumed. Functions can be added increasing the version number.
1976 Notice that the default way to extend functionalities is by adding cmd strings. This is a last resort, and all new
1977 functions should be explicitly motivated. Here's the addition:
1978
1979 version=2, cmd_nothrow.
1980
1981 This function accepts an extra argument `plumed_nothrow_handler*handler`.
1982 In case an exception is thrown withint plumed, it just calls `handler->handler(handler->ptr,code,message,opt)` and return.
1983 An alternative would have been to install an error handler (with a call to cmd("setErrorHandler")). However, the cost
1984 of doing it everytime Plumed::cmd is called is too high. On the other hand, installing it only at object construction
1985 is very risky since and object created in that way would not report any error if manipulated from the C interface.
1986 So, it looks like this is the only possibility.
1987
1988 */
1989 typedef struct {
1990 /**
1991 Version number.
1992
1993 Minimum value is 1.
1994 */
1995 int version;
1996 /**
1997 Pointers to standard plumed functions (create/cmd/finalize).
1998
1999 Always available.
2000 */
2001 plumed_plumedmain_function_holder functions;
2002 /**
2003 Pointer to a cmd function guaranteed not to throw exceptions.
2004
2005 Available with version>=2.
2006 */
2007 void (*cmd_nothrow)(void*plumed,const char*key,const void*val,plumed_nothrow_handler);
2008 } plumed_symbol_table_type;
2009
2010 /* Utility to convert function pointers to pointers, just for the sake of printing them */
2011 #define __PLUMED_CONVERT_FPTR(ptr,fptr) { ptr=NULL; __PLUMED_WRAPPER_STD memcpy(&ptr,&fptr,(sizeof(fptr)>sizeof(ptr)?sizeof(ptr):sizeof(fptr))); }
2012
2013 #define __PLUMED_GETENV __PLUMED_WRAPPER_STD getenv
2014 #define __PLUMED_FPRINTF __PLUMED_WRAPPER_STD fprintf
2015 #define __PLUMED_MALLOC __PLUMED_WRAPPER_STD malloc
2016 #define __PLUMED_FREE __PLUMED_WRAPPER_STD free
2017
2018 /**
2019 Historically (PLUMED<=2.4) register for plumedmain function pointers.
2020 As of PLUMED>=2.5, this function does not do anything except for reporting the attempt to register
2021 something. It always returns NULL. The function should be here anyway to allow an incomplete
2022 libplumedKernel (<=2.4), expecting this function to be present, to be loaded correctly.
2023 */
2024 #if __PLUMED_WRAPPER_KERNEL_REGISTER
2025 /* Since it is only called from outside, it must be hardcoded to be extern */
2026 __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
2027 extern plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder*);
plumed_kernel_register(const plumed_plumedmain_function_holder * f)2028 plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder* f) {
2029 void* tmpptr;
2030 if(f) {
2031 if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) {
2032 __PLUMED_FPRINTF(stderr,"+++ Ignoring registration at %p (",(void*)f);
2033 __PLUMED_CONVERT_FPTR(tmpptr,f->create);
2034 __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
2035 __PLUMED_CONVERT_FPTR(tmpptr,f->cmd);
2036 __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
2037 __PLUMED_CONVERT_FPTR(tmpptr,f->finalize);
2038 __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
2039 }
2040 }
2041 return NULL;
2042 }
2043 __PLUMED_WRAPPER_EXTERN_C_END /*}*/
2044 #endif
2045
2046 #if defined( __PLUMED_HAS_DLOPEN) /*{*/
2047 /**
2048 Try to dlopen a path with a given mode.
2049 If the dlopen command fails, it tries to strip the `Kernel` part of the name.
2050
2051 This function is declared static (internal linkage) so that it is not visible from outside.
2052 It is first declared then defined to make sure it is a regular C static function.
2053 */
2054
2055 __PLUMED_WRAPPER_INTERNALS_BEGIN
plumed_attempt_dlopen(const char * path,int mode)2056 void* plumed_attempt_dlopen(const char*path,int mode) {
2057 char* pathcopy;
2058 void* p;
2059 char* pc;
2060 size_t strlenpath;
2061 FILE* fp;
2062 pathcopy=NULL;
2063 p=NULL;
2064 pc=NULL;
2065 strlenpath=0;
2066 fp=__PLUMED_WRAPPER_STD fopen(path,"r");
2067 if(!fp) {
2068 __PLUMED_FPRINTF(stderr,"+++ File %s does not exist or cannot be read\n",path);
2069 return NULL;
2070 }
2071 __PLUMED_WRAPPER_STD fclose(fp);
2072 dlerror();
2073 p=dlopen(path,mode);
2074 if(!p) {
2075 /*
2076 Something went wrong. We try to remove "Kernel" string from the PLUMED_KERNEL variable
2077 and load directly the shared library. Notice that this particular path is only expected
2078 to be necessary when using PLUMED<=2.4 and the symbols in the main executable are
2079 not visible. All the other cases (either PLUMED>=2.5 or symbols in the main executable visible)
2080 should work correctly without entering here.
2081 */
2082 __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
2083 strlenpath=__PLUMED_WRAPPER_STD strlen(path);
2084 pathcopy=(char*) __PLUMED_MALLOC(strlenpath+1);
2085 __PLUMED_WRAPPER_STD strncpy(pathcopy,path,strlenpath+1);
2086 pc=pathcopy+strlenpath-6;
2087 while(pc>=pathcopy && __PLUMED_WRAPPER_STD memcmp(pc,"Kernel",6)) pc--;
2088 if(pc>=pathcopy) {
2089 __PLUMED_WRAPPER_STD memmove(pc, pc+6, __PLUMED_WRAPPER_STD strlen(pc)-5);
2090 __PLUMED_FPRINTF(stderr,"+++ This error is expected if you are trying to load a kernel <=2.4\n");
2091 __PLUMED_FPRINTF(stderr,"+++ Trying %s +++\n",pathcopy);
2092 fp=__PLUMED_WRAPPER_STD fopen(path,"r");
2093 if(!fp) {
2094 __PLUMED_FPRINTF(stderr,"+++ File %s does not exist or cannot be read\n",pathcopy);
2095 __PLUMED_FREE(pathcopy);
2096 return NULL;
2097 }
2098 __PLUMED_WRAPPER_STD fclose(fp);
2099 dlerror();
2100 p=dlopen(pathcopy,mode);
2101 if(!p) __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
2102 }
2103 __PLUMED_FREE(pathcopy);
2104 }
2105 return p;
2106 }
2107 __PLUMED_WRAPPER_INTERNALS_END
2108
2109 /**
2110 Utility to search for a function.
2111 */
2112 #define __PLUMED_SEARCH_FUNCTION(tmpptr,handle,func,name,debug) \
2113 if(!func) { \
2114 tmpptr=dlsym(handle,name); \
2115 if(tmpptr) { \
2116 *(void **)(&func)=tmpptr; \
2117 if(debug) __PLUMED_FPRINTF(stderr,"+++ %s found at %p +++\n",name,tmpptr); \
2118 } else { \
2119 if(debug) __PLUMED_FPRINTF(stderr,"+++ Function %s not found\n",name); \
2120 } \
2121 }
2122
2123 /**
2124 Search symbols in a dlopened library.
2125
2126 This function is declared static (internal linkage) so that it is not visible from outside.
2127 */
2128 __PLUMED_WRAPPER_INTERNALS_BEGIN
plumed_search_symbols(void * handle,plumed_plumedmain_function_holder * f,plumed_symbol_table_type ** table)2129 void plumed_search_symbols(void* handle, plumed_plumedmain_function_holder* f,plumed_symbol_table_type** table) {
2130 plumed_plumedmain_function_holder functions;
2131 plumed_symbol_table_type* table_ptr;
2132 void* tmpptr;
2133 char* debug;
2134 functions.create=NULL;
2135 functions.cmd=NULL;
2136 functions.finalize=NULL;
2137 table_ptr=NULL;
2138 tmpptr=NULL;
2139 /*
2140 Notice that as of PLUMED 2.5 we ignore self registrations.
2141 Pointers are searched in the form of a single pointer to a structure, which
2142 is the standard way in PLUMED 2.5, as well as using alternative names used in
2143 PLUMED 2.0 to 2.4 (e.g. plumedmain_create) and in some intermediate versions between
2144 PLUMED 2.4 and 2.5 (e.g. plumed_plumedmain_create). The last chance is probably
2145 unnecessary and might be removed at some point.
2146 */
2147 debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
2148 table_ptr=(plumed_symbol_table_type*) dlsym(handle,"plumed_symbol_table");
2149 if(table_ptr) functions=table_ptr->functions;
2150 if(debug) {
2151 if(table_ptr) {
2152 __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table version %i found at %p +++\n",table_ptr->version,(void*)table_ptr);
2153 __PLUMED_FPRINTF(stderr,"+++ plumed_function_pointers found at %p (",(void*)&table_ptr->functions);
2154 __PLUMED_CONVERT_FPTR(tmpptr,functions.create);
2155 __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
2156 __PLUMED_CONVERT_FPTR(tmpptr,functions.cmd);
2157 __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
2158 __PLUMED_CONVERT_FPTR(tmpptr,functions.finalize);
2159 __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
2160 } else {
2161 __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table (available in PLUMED>=2.5) not found, perhaps kernel is older +++\n");
2162 }
2163 }
2164 /* only searches if they were not found already */
2165 __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumedmain_create",debug);
2166 __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumed_plumedmain_create",debug);
2167 __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumedmain_cmd",debug);
2168 __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumed_plumedmain_cmd",debug);
2169 __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumedmain_finalize",debug);
2170 __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumed_plumedmain_finalize",debug);
2171 if(functions.create && functions.cmd && functions.finalize) {
2172 if(debug) __PLUMED_FPRINTF(stderr,"+++ PLUMED was loaded correctly +++\n");
2173 *f=functions;
2174 if(table) *table=table_ptr;
2175 } else {
2176 if(!functions.create) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_create not found +++\n");
2177 if(!functions.cmd) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_cmd not found +++\n");
2178 if(!functions.finalize) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_finalize not found +++\n");
2179 f->create=NULL;
2180 f->cmd=NULL;
2181 f->finalize=NULL;
2182 if(table) *table=NULL;
2183 }
2184 }
2185 __PLUMED_WRAPPER_INTERNALS_END
2186
2187 #endif /*}*/
2188
2189
2190 #if __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
2191
2192 /*
2193 Here is the case where plumed_symbol_table is
2194 visible as extern. We first declare it (together with plumed_symbol_table_init) ...
2195 */
2196
2197 __PLUMED_WRAPPER_EXTERN_C_BEGIN
2198 extern
2199 plumed_symbol_table_type plumed_symbol_table;
2200 __PLUMED_WRAPPER_EXTERN_C_END
2201 __PLUMED_WRAPPER_EXTERN_C_BEGIN
2202 extern
2203 void plumed_symbol_table_init(void);
2204 __PLUMED_WRAPPER_EXTERN_C_END
2205
2206 /*
2207 ... and then make available a function that returns the address
2208 of the symbol table.
2209 */
2210 __PLUMED_WRAPPER_C_BEGIN
plumed_symbol_table_reexport()2211 plumed_symbol_table_type* plumed_symbol_table_reexport() {
2212 /* make sure the table is initialized */
2213 plumed_symbol_table_init();
2214 return &plumed_symbol_table;
2215 }
2216 __PLUMED_WRAPPER_C_END
2217
2218 #else
2219
2220 /*
2221 Here is the case where plumed_symbol_table is not
2222 visible as extern. We thus assume that plumed_symbol_table_reexport is
2223 available.
2224 */
2225
2226 __PLUMED_WRAPPER_EXTERN_C_BEGIN
2227 extern plumed_symbol_table_type* plumed_symbol_table_reexport();
2228 __PLUMED_WRAPPER_EXTERN_C_END
2229 #endif
2230
2231
2232 /*
2233 Returns the global pointers, either those available at link time or those
2234 found in the library loaded at PLUMED_KERNEL env var.
2235 If plumed_symbol_table_ptr is not NULL, it is used to return a pointer to the symbol table
2236 (if available).
2237 Notice that problems can be detected checking if the functions have a NULL ptr.
2238 On the other hand, the symbol table pointer might be NULL just because the plumed version is <=2.4.
2239 If handle is not NULL, it is used to return a dlopen handle that could be subsequently dlclosed.
2240 */
2241 __PLUMED_WRAPPER_INTERNALS_BEGIN
plumed_retrieve_functions(plumed_plumedmain_function_holder * functions,plumed_symbol_table_type ** plumed_symbol_table_ptr,void ** handle)2242 void plumed_retrieve_functions(plumed_plumedmain_function_holder* functions, plumed_symbol_table_type** plumed_symbol_table_ptr,void** handle) {
2243 #if ! __PLUMED_WRAPPER_LINK_RUNTIME
2244 /*
2245 Real interface, constructed using the symbol table obtained with plumed_symbol_table_reexport.
2246 This makes the symbols hardcoded and independent of a mis-set PLUMED_KERNEL variable.
2247 */
2248 plumed_symbol_table_type* ptr=plumed_symbol_table_reexport();
2249 if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=ptr;
2250 if(handle) *handle=NULL;
2251 if(functions) *functions=ptr->functions;
2252 #elif ! defined(__PLUMED_HAS_DLOPEN)
2253 /*
2254 When dlopen is not available, we hard code them to NULL
2255 */
2256 fprintf(stderr,"+++ PLUMED has been compiled without dlopen and without a static kernel +++\n");
2257 plumed_plumedmain_function_holder g= {NULL,NULL,NULL};
2258 if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=NULL;
2259 if(handle) *handle=NULL;
2260 if(functions) *functions=g;
2261 #else
2262 /*
2263 On the other hand, for runtime binding, we use dlsym to find the relevant functions.
2264 */
2265 plumed_plumedmain_function_holder g;
2266 /* search is done once and only once */
2267 const char* path;
2268 void* p;
2269 char* debug;
2270 int dlopenmode;
2271 g.create=NULL;
2272 g.cmd=NULL;
2273 g.finalize=NULL;
2274 path=__PLUMED_GETENV("PLUMED_KERNEL");
2275 p=NULL;
2276 debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
2277 dlopenmode=0;
2278 if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=NULL;
2279 if(handle) *handle=NULL;
2280 #ifdef __PLUMED_DEFAULT_KERNEL
2281 /*
2282 This variable allows a default path for the kernel to be hardcoded.
2283 Can be useful for hardcoding the predefined plumed location
2284 still allowing the user to override this choice setting PLUMED_KERNEL.
2285 The path should be chosen at compile time adding e.g.
2286 -D__PLUMED_DEFAULT_KERNEL=/opt/local/lib/libplumed.dylib
2287 */
2288 /* This is required to add quotes */
2289 #define PLUMED_QUOTE_DIRECT(name) #name
2290 #define PLUMED_QUOTE(macro) PLUMED_QUOTE_DIRECT(macro)
2291 if(! (path && (*path) )) path=PLUMED_QUOTE(__PLUMED_DEFAULT_KERNEL);
2292 #endif
2293 if(path && (*path)) {
2294 fprintf(stderr,"+++ Loading the PLUMED kernel runtime +++\n");
2295 fprintf(stderr,"+++ PLUMED_KERNEL=\"%s\" +++\n",path);
2296 if(debug) __PLUMED_FPRINTF(stderr,"+++ Loading with mode RTLD_NOW");
2297 dlopenmode=RTLD_NOW;
2298 if(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE"),"LOCAL")) {
2299 dlopenmode=dlopenmode|RTLD_LOCAL;
2300 if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_LOCAL");
2301 } else {
2302 dlopenmode=dlopenmode|RTLD_GLOBAL;
2303 if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_GLOBAL");
2304 }
2305 #ifdef RTLD_DEEPBIND
2306 if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) {
2307 dlopenmode=dlopenmode|RTLD_DEEPBIND;
2308 if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_DEEPBIND");
2309 }
2310 #endif
2311 if(debug) __PLUMED_FPRINTF(stderr," +++\n");
2312 p=plumed_attempt_dlopen(path,dlopenmode);
2313 if(p) plumed_search_symbols(p,&g,plumed_symbol_table_ptr);
2314 }
2315 if(handle) *handle=p;
2316 if(functions) *functions=g;
2317 #endif
2318 }
2319 __PLUMED_WRAPPER_INTERNALS_END
2320
2321 /**
2322 Implementation.
2323 Small object used to store pointers directly into the plumed object defined in Plumed.h.
2324 This allows avoiding the extra function call to plumed_retrieve_functions at every cmd,
2325 at the cost of an extra indirection.
2326 */
2327 typedef struct {
2328 /* allows errors with pointers to be found when debugging */
2329 char magic[6];
2330 /* reference count */
2331 int refcount;
2332 /* handler to dlopened library. NULL if there was no library opened */
2333 void* dlhandle;
2334 /* non zero if, upon destruction, the library should be dlclosed */
2335 int dlclose;
2336 /* 1 if path to kernel was taken from PLUMED_KERNEL var, 0 otherwise */
2337 int used_plumed_kernel;
2338 /* function pointers */
2339 plumed_plumedmain_function_holder functions;
2340 /* pointer to the symbol table. NULL if kernel <=2.4 */
2341 plumed_symbol_table_type* table;
2342 /* pointer to plumed object */
2343 void* p;
2344 } plumed_implementation;
2345
2346 __PLUMED_WRAPPER_INTERNALS_BEGIN
plumed_malloc_pimpl()2347 plumed_implementation* plumed_malloc_pimpl() {
2348 plumed_implementation* pimpl;
2349 /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
2350 pimpl=(plumed_implementation*) __PLUMED_MALLOC(sizeof(plumed_implementation));
2351 if(!pimpl) {
2352 __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
2353 __PLUMED_WRAPPER_STD abort();
2354 }
2355 __PLUMED_WRAPPER_STD memcpy(pimpl->magic,"pLuMEd",6);
2356 pimpl->refcount=1;
2357 #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
2358 fprintf(stderr,"refcount: new at %p\n",(void*)pimpl);
2359 #endif
2360 pimpl->dlhandle=NULL;
2361 pimpl->dlclose=0;
2362 pimpl->used_plumed_kernel=0;
2363 pimpl->functions.create=NULL;
2364 pimpl->functions.cmd=NULL;
2365 pimpl->functions.finalize=NULL;
2366 pimpl->table=NULL;
2367 pimpl->p=NULL;
2368 return pimpl;
2369 }
2370 __PLUMED_WRAPPER_INTERNALS_END
2371
2372 #ifndef NDEBUG
2373
2374 __PLUMED_WRAPPER_INTERNALS_BEGIN
plumed_check_pimpl(plumed_implementation * pimpl)2375 int plumed_check_pimpl(plumed_implementation*pimpl) {
2376 if(!pimpl) return 0;
2377 if(__PLUMED_WRAPPER_STD memcmp(pimpl->magic,"pLuMEd",6)) return 0;
2378 return 1;
2379 }
2380 __PLUMED_WRAPPER_INTERNALS_END
2381 #endif
2382
2383 /* C wrappers: */
2384
2385 __PLUMED_WRAPPER_C_BEGIN
plumed_create(void)2386 plumed plumed_create(void) {
2387 /* returned object */
2388 plumed p;
2389 /* pointer to implementation */
2390 plumed_implementation* pimpl;
2391 /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
2392 pimpl=plumed_malloc_pimpl();
2393 /* store pointers in pimpl */
2394 plumed_retrieve_functions(&pimpl->functions,&pimpl->table,&pimpl->dlhandle);
2395 #if __PLUMED_WRAPPER_LINK_RUNTIME
2396 /* note if PLUMED_KERNEL variable was used */
2397 pimpl->used_plumed_kernel=1;
2398 #endif
2399 /* note if handle should not be dlclosed */
2400 pimpl->dlclose=1;
2401 if(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE"),"no")) pimpl->dlclose=0;
2402 /* in case of failure, return */
2403 /* the resulting object should be plumed_finalized, though you cannot use plumed_cmd */
2404 if(!pimpl->functions.create) {
2405 /* store pimpl in returned object */
2406 p.p=pimpl;
2407 return p;
2408 }
2409 assert(pimpl->functions.cmd);
2410 assert(pimpl->functions.finalize);
2411 /* obtain object */
2412 pimpl->p=(*(pimpl->functions.create))();
2413 /* notice: we do not assert pimpl->p since in principle it might be nullptr */
2414 /* user might identify this using plumed_valid() */
2415 /* store pimpl in returned object */
2416 p.p=pimpl;
2417 return p;
2418 }
2419 __PLUMED_WRAPPER_C_END
2420
2421 __PLUMED_WRAPPER_C_BEGIN
plumed_create_dlopen(const char * path)2422 plumed plumed_create_dlopen(const char*path) {
2423 int dlopenmode;
2424 /* plumed_create_dlopen always uses RTLD_LOCAL and, when possible, RTLD_DEEPBIND to allow multiple versions */
2425 #ifdef __PLUMED_HAS_DLOPEN
2426 dlopenmode=RTLD_NOW|RTLD_LOCAL;
2427 #ifdef RTLD_DEEPBIND
2428 dlopenmode=dlopenmode|RTLD_DEEPBIND;
2429 #endif
2430 #else
2431 dlopenmode=0;
2432 #endif
2433 return plumed_create_dlopen2(path,dlopenmode);
2434 }
2435 __PLUMED_WRAPPER_C_END
2436
2437 __PLUMED_WRAPPER_C_BEGIN
plumed_create_dlopen2(const char * path,int mode)2438 plumed plumed_create_dlopen2(const char*path,int mode) {
2439 /* returned object */
2440 plumed p;
2441 /* pointer to implementation */
2442 plumed_implementation* pimpl;
2443 /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
2444 pimpl=plumed_malloc_pimpl();
2445 #ifdef __PLUMED_HAS_DLOPEN
2446 if(path) pimpl->dlhandle=plumed_attempt_dlopen(path,mode);
2447 /* mark this library to be dlclosed when the object is finalized */
2448 pimpl->dlclose=1;
2449 if(pimpl->dlhandle) plumed_search_symbols(pimpl->dlhandle,&pimpl->functions,&pimpl->table);
2450 #endif
2451 if(!pimpl->functions.create) {
2452 p.p=pimpl;
2453 return p;
2454 }
2455 assert(pimpl->functions.cmd);
2456 assert(pimpl->functions.finalize);
2457 /* obtain object */
2458 pimpl->p=(*(pimpl->functions.create))();
2459 /* notice: we do not assert pimpl->p since in principle it might be nullptr */
2460 /* user might identify this using plumed_valid() */
2461 /* store pimpl in returned object */
2462 p.p=pimpl;
2463 return p;
2464 }
2465 __PLUMED_WRAPPER_C_END
2466
2467 __PLUMED_WRAPPER_C_BEGIN
plumed_create_reference(plumed p)2468 plumed plumed_create_reference(plumed p) {
2469 plumed_implementation* pimpl;
2470 /* obtain pimpl */
2471 pimpl=(plumed_implementation*) p.p;
2472 assert(plumed_check_pimpl(pimpl));
2473 /* increase reference count */
2474 pimpl->refcount++;
2475 #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
2476 fprintf(stderr,"refcount: increase at %p\n",(void*)pimpl);
2477 #endif
2478 return p;
2479 }
2480 __PLUMED_WRAPPER_C_END
2481
2482 __PLUMED_WRAPPER_C_BEGIN
plumed_create_reference_v(void * v)2483 plumed plumed_create_reference_v(void*v) {
2484 return plumed_create_reference(plumed_v2c(v));
2485 }
2486 __PLUMED_WRAPPER_C_END
2487
2488 __PLUMED_WRAPPER_C_BEGIN
plumed_create_reference_f(const char * f)2489 plumed plumed_create_reference_f(const char*f) {
2490 return plumed_create_reference(plumed_f2c(f));
2491 }
2492 __PLUMED_WRAPPER_C_END
2493
2494 __PLUMED_WRAPPER_C_BEGIN
plumed_create_invalid()2495 plumed plumed_create_invalid() {
2496 plumed p;
2497 plumed_implementation* pimpl;
2498 pimpl=plumed_malloc_pimpl();
2499 p.p=pimpl;
2500 return p;
2501 }
2502 __PLUMED_WRAPPER_C_END
2503
2504 __PLUMED_WRAPPER_C_BEGIN
plumed_cmd(plumed p,const char * key,const void * val)2505 void plumed_cmd(plumed p,const char*key,const void*val) {
2506 plumed_implementation* pimpl;
2507 /* obtain pimpl */
2508 pimpl=(plumed_implementation*) p.p;
2509 assert(plumed_check_pimpl(pimpl));
2510 if(!pimpl->p) {
2511 __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
2512 if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
2513 __PLUMED_WRAPPER_STD exit(1);
2514 }
2515 assert(pimpl->functions.create);
2516 assert(pimpl->functions.cmd);
2517 assert(pimpl->functions.finalize);
2518 /* execute */
2519 (*(pimpl->functions.cmd))(pimpl->p,key,val);
2520 }
2521 __PLUMED_WRAPPER_C_END
2522
2523 __PLUMED_WRAPPER_C_BEGIN
plumed_cmd_nothrow(plumed p,const char * key,const void * val,plumed_nothrow_handler nothrow)2524 void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow) {
2525 plumed_implementation* pimpl;
2526 /* obtain pimpl */
2527 pimpl=(plumed_implementation*) p.p;
2528 assert(plumed_check_pimpl(pimpl));
2529 if(!pimpl->p) {
2530 if(pimpl->used_plumed_kernel) {
2531 nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.\nCheck your PLUMED_KERNEL environment variable.",NULL);
2532 } else {
2533 nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.",NULL);
2534 }
2535 return;
2536 }
2537 assert(pimpl->functions.create);
2538 assert(pimpl->functions.cmd);
2539 assert(pimpl->functions.finalize);
2540 /* execute */
2541 if(pimpl->table && pimpl->table->version>1) (*(pimpl->table->cmd_nothrow))(pimpl->p,key,val,nothrow);
2542 else (*(pimpl->functions.cmd))(pimpl->p,key,val);
2543 }
2544 __PLUMED_WRAPPER_C_END
2545
2546
2547
2548 __PLUMED_WRAPPER_C_BEGIN
plumed_finalize(plumed p)2549 void plumed_finalize(plumed p) {
2550 plumed_implementation* pimpl;
2551 /* obtain pimpl */
2552 pimpl=(plumed_implementation*) p.p;
2553 assert(plumed_check_pimpl(pimpl));
2554 /* decrease reference count */
2555 pimpl->refcount--;
2556 #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
2557 fprintf(stderr,"refcount: decrease at %p\n",(void*)pimpl);
2558 #endif
2559 if(pimpl->refcount>0) return;
2560 /* to allow finalizing an invalid plumed object, we only call
2561 finalize if the object is valid */
2562 if(pimpl->p) {
2563 assert(pimpl->functions.create);
2564 assert(pimpl->functions.cmd);
2565 assert(pimpl->functions.finalize);
2566 /* finalize */
2567 (*(pimpl->functions.finalize))(pimpl->p);
2568 }
2569 #ifdef __PLUMED_HAS_DLOPEN
2570 /* dlclose library */
2571 if(pimpl->dlhandle && pimpl->dlclose) {
2572 if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) fprintf(stderr,"+++ Unloading library\n");
2573 dlclose(pimpl->dlhandle);
2574 }
2575 #endif
2576 #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
2577 fprintf(stderr,"refcount: delete at %p\n",(void*)pimpl);
2578 #endif
2579 /* free pimpl space */
2580 __PLUMED_FREE(pimpl);
2581 }
2582 __PLUMED_WRAPPER_C_END
2583
2584 __PLUMED_WRAPPER_C_BEGIN
plumed_valid(plumed p)2585 int plumed_valid(plumed p) {
2586 plumed_implementation* pimpl;
2587 /* obtain pimpl */
2588 pimpl=(plumed_implementation*) p.p;
2589 assert(plumed_check_pimpl(pimpl));
2590 if(pimpl->p) return 1;
2591 else return 0;
2592 }
2593 __PLUMED_WRAPPER_C_END
2594
2595 __PLUMED_WRAPPER_C_BEGIN
plumed_use_count(plumed p)2596 int plumed_use_count(plumed p) {
2597 plumed_implementation* pimpl;
2598 /* obtain pimpl */
2599 pimpl=(plumed_implementation*) p.p;
2600 assert(plumed_check_pimpl(pimpl));
2601 return pimpl->refcount;
2602 }
2603 __PLUMED_WRAPPER_C_END
2604
2605 __PLUMED_WRAPPER_C_BEGIN
plumed_installed(void)2606 int plumed_installed(void) {
2607 plumed p;
2608 int result;
2609 p=plumed_create();
2610 result=plumed_valid(p);
2611 plumed_finalize(p);
2612 return result;
2613 }
2614 __PLUMED_WRAPPER_C_END
2615
2616 #if __PLUMED_WRAPPER_GLOBAL /*{*/
2617
2618 __PLUMED_WRAPPER_EXTERN_C_BEGIN
2619
2620 /* we declare a Plumed_g_main object here, in such a way that it is always available */
2621
2622 static plumed plumed_gmain= {NULL};
2623
plumed_global(void)2624 plumed plumed_global(void) {
2625 return plumed_gmain;
2626 }
2627
plumed_gcreate(void)2628 void plumed_gcreate(void) {
2629 /* should be created once */
2630 assert(plumed_gmain.p==NULL);
2631 plumed_gmain=plumed_create();
2632 }
2633
plumed_gcmd(const char * key,const void * val)2634 void plumed_gcmd(const char*key,const void*val) {
2635 plumed_cmd(plumed_gmain,key,val);
2636 }
2637
plumed_gfinalize(void)2638 void plumed_gfinalize(void) {
2639 plumed_finalize(plumed_gmain);
2640 plumed_gmain.p=NULL;
2641 }
2642
plumed_ginitialized(void)2643 int plumed_ginitialized(void) {
2644 if(plumed_gmain.p) return 1;
2645 else return 0;
2646 }
2647
plumed_gvalid()2648 int plumed_gvalid() {
2649 assert(plumed_gmain.p);
2650 return plumed_valid(plumed_gmain);
2651 }
2652
2653 __PLUMED_WRAPPER_EXTERN_C_END
2654
2655 #endif /*}*/
2656
2657 __PLUMED_WRAPPER_C_BEGIN
plumed_c2f(plumed p,char * c)2658 void plumed_c2f(plumed p,char*c) {
2659 unsigned i;
2660 unsigned char* cc;
2661 /*
2662 Convert the address stored in p.p into a proper FORTRAN string
2663 made of only ASCII characters. For this to work, the two following
2664 assertions should be satisfied:
2665 */
2666 assert(CHAR_BIT<=12);
2667 assert(sizeof(p.p)<=16);
2668
2669 assert(c);
2670 cc=(unsigned char*)&p.p;
2671 for(i=0; i<sizeof(p.p); i++) {
2672 /*
2673 characters will range between '0' (ASCII 48) and 'o' (ASCII 111=48+63)
2674 */
2675 c[2*i]=cc[i]/64+48;
2676 c[2*i+1]=cc[i]%64+48;
2677 }
2678 for(; i<16; i++) {
2679 c[2*i]=' ';
2680 c[2*i+1]=' ';
2681 }
2682 }
2683 __PLUMED_WRAPPER_C_END
2684
2685 __PLUMED_WRAPPER_C_BEGIN
plumed_f2c(const char * c)2686 plumed plumed_f2c(const char*c) {
2687 plumed p;
2688 unsigned i;
2689 unsigned char* cc;
2690
2691 assert(CHAR_BIT<=12);
2692 assert(sizeof(p.p)<=16);
2693
2694 assert(c);
2695
2696 /*
2697 needed to avoid cppcheck warning on uninitialized p
2698 */
2699 p.p=NULL;
2700 cc=(unsigned char*)&p.p;
2701 for(i=0; i<sizeof(p.p); i++) {
2702 assert(c[2*i]>=48 && c[2*i]<48+64);
2703 assert(c[2*i+1]>=48 && c[2*i+1]<48+64);
2704 /*
2705 perform the reversed transform
2706 */
2707 cc[i]=(c[2*i]-48)*64 + (c[2*i+1]-48);
2708 }
2709 for(; i<16; i++) {
2710 assert(c[2*i]==' ');
2711 assert(c[2*i+1]==' ');
2712 }
2713 return p;
2714 }
2715 __PLUMED_WRAPPER_C_END
2716
2717 __PLUMED_WRAPPER_C_BEGIN
plumed_c2v(plumed p)2718 void* plumed_c2v(plumed p) {
2719 assert(plumed_check_pimpl((plumed_implementation*)p.p));
2720 return p.p;
2721 }
2722 __PLUMED_WRAPPER_C_END
2723
2724 __PLUMED_WRAPPER_C_BEGIN
plumed_v2c(void * v)2725 plumed plumed_v2c(void* v) {
2726 assert(plumed_check_pimpl((plumed_implementation*)v));
2727 plumed p;
2728 p.p=v;
2729 return p;
2730 }
2731 __PLUMED_WRAPPER_C_END
2732
2733 #if __PLUMED_WRAPPER_FORTRAN /*{*/
2734
2735 /*
2736 Fortran wrappers
2737 These are just like the global C wrappers. They are
2738 just defined here and not declared since they
2739 should not be used from c/c++ anyway.
2740
2741 We use a macro that does the following:
2742 - declare a static function named NAME_static
2743 - declare a number of functions named NAME_ etc, with all possible
2744 fortran mangling schemes (zero, one, or two underscores, lower and upper case)
2745 - define the NAME_static function.
2746
2747 The static function is used basically as an inline function in a C-compatible manner.
2748 */
2749
2750 #define __PLUMED_IMPLEMENT_FORTRAN(lower,upper,arg1,arg2) \
2751 static void lower ## _static arg1; \
2752 extern void lower arg1 {lower ## _static arg2;} \
2753 extern void lower ##_ arg1 {lower ## _static arg2;} \
2754 extern void lower ##__ arg1 {lower ## _static arg2;} \
2755 extern void upper arg1 {lower ## _static arg2;} \
2756 extern void upper ##_ arg1 {lower ## _static arg2;} \
2757 extern void upper ##__ arg1 {lower ## _static arg2;} \
2758 static void lower ## _static arg1
2759
2760 /* FORTRAN wrappers would only make sense as extern "C" */
2761
2762 __PLUMED_WRAPPER_EXTERN_C_BEGIN
2763
2764 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create,PLUMED_F_CREATE,(char*c),(c)) {
2765 plumed_c2f(plumed_create(),c);
2766 }
2767
2768 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_dlopen,PLUMED_F_CREATE_DLOPEN,(char*path,char*c),(path,c)) {
2769 plumed_c2f(plumed_create_dlopen(path),c);
2770 }
2771
2772 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_reference,PLUMED_F_CREATE_REFERENCE,(char* r,char*c),(r,c)) {
2773 plumed_c2f(plumed_create_reference_f(r),c);
2774 }
2775
2776 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_invalid,PLUMED_F_CREATE_INVALID,(char* c),(c)) {
2777 plumed_c2f(plumed_create_invalid(),c);
2778 }
2779
2780 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_cmd,PLUMED_F_CMD,(char*c,char*key,void*val),(c,key,val)) {
2781 plumed_cmd(plumed_f2c(c),key,val);
2782 }
2783
2784 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_finalize,PLUMED_F_FINALIZE,(char*c),(c)) {
2785 plumed_finalize(plumed_f2c(c));
2786 }
2787
2788 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_installed,PLUMED_F_INSTALLED,(int*i),(i)) {
2789 assert(i);
2790 *i=plumed_installed();
2791 }
2792
2793 /* New in PLUMED 2.5 */
2794 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_valid,PLUMED_F_VALID,(char*c,int*i),(c,i)) {
2795 assert(i);
2796 *i=plumed_valid(plumed_f2c(c));
2797 }
2798
2799 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_use_count,PLUMED_F_USE_COUNT,(char*c,int*i),(c,i)) {
2800 assert(i);
2801 *i=plumed_use_count(plumed_f2c(c));
2802 }
2803
2804 #if __PLUMED_WRAPPER_GLOBAL /*{*/
2805
2806 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_global,PLUMED_F_GLOBAL,(char*c),(c)) {
2807 plumed_c2f(plumed_gmain,c);
2808 }
2809
2810 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_ginitialized,PLUMED_F_GINITIALIZED,(int*i),(i)) {
2811 assert(i);
2812 *i=plumed_ginitialized();
2813 }
2814
2815 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcreate,PLUMED_F_GCREATE,(void),()) {
2816 plumed_gcreate();
2817 }
2818
2819 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcmd,PLUMED_F_GCMD,(char*key,void*val),(key,val)) {
2820 plumed_gcmd(key,val);
2821 }
2822
2823 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gfinalize,PLUMED_F_GFINALIZE,(void),()) {
2824 plumed_gfinalize();
2825 }
2826
2827 /* New in PLUMED 2.5 */
2828 __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gvalid,PLUMED_F_GVALID,(int*i),(i)) {
2829 assert(i);
2830 *i=plumed_gvalid();
2831 }
2832
2833 #endif /*}*/
2834
2835 __PLUMED_WRAPPER_EXTERN_C_END
2836
2837 #endif /*}*/
2838
2839 #endif /*}*/
2840
2841 #endif /*}*/
2842
2843 /* END OF DEFINITIONS */
2844
2845 /* reset variable to allow it to be redefined upon re-inclusion */
2846
2847 #undef __PLUMED_WRAPPER_IMPLEMENTATION_
2848
2849