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