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