On 2021-03-22 19:26, edgar wrote: > On 2021-03-22 18:26, John Peterson
wrote: >> The main reason that libmesh_error_msg() and friends are
macros is that >> they use the __FILE__ and __LINE__ preprocessor
defines to help direct the >> user to the exact place in the code where
the error was triggered. I’m not >> sure if it is possible to do this
same trick with inline functions, IIRC it >> will always report the line
where the inline function is defined in the >> source rather than the
line where it is called.  > > Thank you very much, John

Dear John,

I checked the C++ documentation. It seems that both `__FILE__' and
`__LINE__' should show up anywhere. They are also usable by functions as
well.

I was not planning to give more attention to this subject, but it came
back to bite me when I tried to use the macro in a `void' function .
So, this works: it reports the line number of the calling file, and
allows the functionality that `libmesh_example_requires' and
`libmesh_error_msg' provide in functions which may not be of `int' type.

Again, if it convenient to have this in libMesh, I can modify
`libmesh_common.h' in my local copy of the repo and push it onto
<https://www.notabug.org/broncodev/libmesh> or send it to you as a diff
file (the mailing list would not take attachments).

┌────
│ #include "../include/libmesh_macro_handler.h"
│ #include "libmesh/libmesh.h"
│ #include "libmesh/mesh.h"
│ #include <iostream>
│
│ using namespace libMesh;
│
│ int main (int argc, char * argv[]) {
│   libMesh::LibMeshInit
│     init (argc, argv);
│
│   libmesh_example_requires_fun(bool (0),
│                                "TESTME",
│                                __FILE__,
│                                __LINE__);
│   // This works too (comment previous function to test)
│   libmesh_error_msg_fun("FOUL");
│
│   printf("Not to be shown");
│
│   return 0;
│ }
└────
Listing 1: Main function

┌────
│ #ifndef LIBMESH_MACRO_HANDLER_H
│ #define LIBMESH_MACRO_HANDLER_H
│
│ #include <iostream>
│ #include "libmesh/libmesh.h"
│ #include "libmesh/libmesh_common.h"
│
│ /**
│  * @brief      Turns =libmesh_error_msg= into a function
│  *
│  * @details    =libmesh_error_msg= is a macro. To use
│  *             it inside a function, the function needs
│  *             to be of =int= type. This function just
│  *             captures the result of the macro,
│  *
│  * @param      msg: (std::string) message to show
│  *
│  * @return     int
│  */
│ int
│ libmesh_error_msg_fun(const std::string msg);
│
│ /**
│ * @brief Function which is equivalent to libmesh_example_requires
│  *
│ * @details This function allows to have the same functionality as libmesh_example_requires, but does not have a return value. Since it is not a macro, it can be called from within functions which are not of int type
│  *
│ * @param condition: (const bool. Ex: bool(0)) condition which needs to occur to trigger the exception handling │ * msg: (const char *. Ex: "--enable-lib") The functionality which the example requires
│  *             file: (const char *. Ex: __FILE__) Name of calling file
│ * line: (const int. Ex: __LINE__) Line from where the exception happened in file
│  *
│  * @return     void
│  */
│ void
│ libmesh_example_requires_fun (const bool condition,
│                               const char *msg,
│                               const char *file,
│                               const int line) {
│
│     // // This would not work, because of the =void= type:
│     // libmesh_example_requires (condition, option);
│
│     if (!condition) {
│         do {
│
│             libMesh::out
│               << "Configuring libMesh with " << msg
│               << " is required to run this example."
│               << std::endl;
│             std::stringstream msg_stream;
│             msg_stream << msg;
│             libMesh::MacroFunctions::report_error (
│               file, line, LIBMESH_DATE, LIBMESH_TIME);
│             LIBMESH_THROW (
│               libMesh::LogicError (msg_stream.str ()));
│         } while (0);
│   }
│ }
│
│ #endif /* LIBMESH_MACRO_HANDLER_H */
└────
Listing 2: header file (libmesh_macro_handle.h). Note that
`libmesh_example_requires_fun' could have also been `int', but I
modified it to show a stack trace too.

┌────
│ #include <stdio.h>
│ #include <iostream>
│ #include "libmesh/libmesh.h"
│ #include "libmesh/libmesh_common.h"
│ #include "../include/libmesh_macro_handler.h"
│
│ int
│ libmesh_error_msg_fun(const std::string msg) {
│   libmesh_error_msg(msg);
│
│   return 0;
│ }
└────
Listing 3: source file (libmesh_macro_handle.cpp)


_______________________________________________
Libmesh-users mailing list
Libmesh-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libmesh-users

Reply via email to