Hi Edgar,

I don't think this mailing list --8<-- accept{s} attachments.

I live in a bubble :P .

Second best would be to paste a diff into
the body of an email (assuming it's not too long, in which case the first
option should be used).

Third best: create a fork on notabug.org or GNU Savannah and send you the link to the corresponding branch, right? ;D

In any case, below is the original suggestion. Let me know if you like the idea, and I will create the branch on notabug.org :D .

  Hello,

I would kindly and respectfully like to suggest turning some macros in =libmesh_common.h= into functions. As I was exploring libMesh, I naïvely tried this:

  #+CAPTION: Using the =libmesh_error_msg= macro
#+begin_src cpp :libs $(libmesh-config --cxxflags --include --ldflags --libs)
    #include <stdio.h>
    #include <iostream>
    #include "libmesh/libmesh.h"
    #include "libmesh/mesh.h"

    int main (int argc, char * argv[]){
      libMesh::LibMeshInit init(argc, argv);

      if (argc < 4){
        libMesh::libmesh_error_msg("Usage: ");
      }

    }
  #+end_src

  #+caption: Result from using =libmesh_error_msg= (does not compile).
  #+begin_example
    In file included from /usr/include/libmesh/libmesh.h:25,
                     from /tmp/babel-hlBzed/C-src-YQnbkN.cpp:3:
/tmp/babel-hlBzed/C-src-YQnbkN.cpp: In function 'int main(int, char**)': /tmp/babel-hlBzed/C-src-YQnbkN.cpp:15:14: error: expected unqualified-id before 'do'
       15 |     libMesh::libmesh_error_msg("Usage: " // << argv[0] <<
          |              ^~~~~~~~~~~~~~~~~
  #+end_example

This does not work, because =libmesh_error_msg= is actually a macro defined in =libmesh_common.h=, and does not need =libMesh::=.

  If, however, the macro is replaced with the code, it should produce:
  #+caption: Using the raw text from =libmesh_error_msg=
#+begin_src cpp :libs $(libmesh-config --cxxflags --include --ldflags --libs)
    #include <stdio.h>
    #include <iostream>
    #include "libmesh/libmesh.h"
    #include "libmesh/mesh.h"

    int main (int argc, char * argv[]){
      libMesh::LibMeshInit init(argc, argv);

      if (argc < 4){
        char msg[] = "Usage: ";
        do {
          libMesh::err << msg << 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);
      }

    }
  #+end_src

#+caption: Expected output (error message from libMesh) with raw text from =libmesh_error_msg=
  #+begin_example
    Usage:
    Stack frames: 5
    0: libMesh::print_trace(std::ostream&)
1: libMesh::MacroFunctions::report_error(char const*, int, char const*, char const*)
    2: /tmp/babel-hlBzed/C-bin-tb49Ls(+0xcdee) [0x563818bc5dee]
    3: __libc_start_main
    4: /tmp/babel-hlBzed/C-bin-tb49Ls(+0xceae) [0x563818bc5eae]
[0] /tmp/babel-hlBzed/C-src-APc5Dz.cpp, line 22, compiled Mar 18 2021 at 17:20:53 --------------------------------------------------------------------------
    MPI_ABORT was invoked on rank 0 in communicator MPI_COMM_WORLD
    with errorcode 1.

    NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes.
    You may or may not see output from other processes, depending on
    exactly when Open MPI kills them.
--------------------------------------------------------------------------
  #+end_example

This makes me think that we can have a function (or a template) like this:
  #+caption: Fuction to replace =libmesh_error_msg= macro
#+begin_src cpp :libs $(libmesh-config --cxxflags --include --ldflags --libs)
    #include <stdio.h>
    #include <iostream>
    #include "libmesh/libmesh.h"
    #include "libmesh/mesh.h"

    void libmesh_error_msg_fun(std::string &msg) {
      do {
        libMesh::err << msg << 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);
    }

    template<typename X, typename Y>
    int libmesh_example_requires(X condition, Y option){
      do {
        if (!(condition)) {
          libMesh::out <<
            "Configuring libMesh with " <<
            option <<
            " is required to run this example." << std::endl;
          return 77;
        }
      } while (0);
    }

    int main (int argc, char * argv[]){
      libMesh::LibMeshInit init(argc, argv);

      if (argc < 4){
        std::string msg = {"Usage: "};
        libmesh_error_msg_fun(msg);
      }
    }
  #+end_src

  #+RESULTS:

  #+begin_example
    Usage:
    Stack frames: 6
    0: libMesh::print_trace(std::ostream&)
1: libMesh::MacroFunctions::report_error(char const*, int, char const*, char const*)
    2: /tmp/babel-CpgWD6/C-bin-mEeZoe(+0xcf4f) [0x55567f87ef4f]
    3: /tmp/babel-CpgWD6/C-bin-mEeZoe(+0xcd76) [0x55567f87ed76]
    4: __libc_start_main
    5: /tmp/babel-CpgWD6/C-bin-mEeZoe(+0xcdbe) [0x55567f87edbe]
[0] /tmp/babel-CpgWD6/C-src-HfTgSq.cpp, line 18, compiled Mar 18 2021 at 20:48:30 --------------------------------------------------------------------------
    MPI_ABORT was invoked on rank 0 in communicator MPI_COMM_WORLD
    with errorcode 1.

    NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes.
    You may or may not see output from other processes, depending on
    exactly when Open MPI kills them.
--------------------------------------------------------------------------
  #+end_example

I was expecting =libMesh::= to work as well, because =libmesh_*_msg= look very much like functions, and they are inside a =namespace=. I am sure that there is a solid reason for which they were kept as macros, and that is why this is a humble suggestion. Thank you.


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

Reply via email to