add overloads for Error::all() and Error::one() that can point out the location of a faulty argument
This commit is contained in:
@ -103,7 +103,7 @@ void CreateAtoms::command(int narg, char **arg)
|
|||||||
style = REGION;
|
style = REGION;
|
||||||
if (narg < 3) utils::missing_cmd_args(FLERR, "create_atoms region", error);
|
if (narg < 3) utils::missing_cmd_args(FLERR, "create_atoms region", error);
|
||||||
region = domain->get_region_by_id(arg[2]);
|
region = domain->get_region_by_id(arg[2]);
|
||||||
if (!region) error->all(FLERR, "Create_atoms region {} does not exist", arg[2]);
|
if (!region) error->all(FLERR, 2, "Create_atoms region {} does not exist", arg[2]);
|
||||||
region->init();
|
region->init();
|
||||||
region->prematch();
|
region->prematch();
|
||||||
iarg = 3;
|
iarg = 3;
|
||||||
@ -127,7 +127,7 @@ void CreateAtoms::command(int narg, char **arg)
|
|||||||
region = nullptr;
|
region = nullptr;
|
||||||
else {
|
else {
|
||||||
region = domain->get_region_by_id(arg[4]);
|
region = domain->get_region_by_id(arg[4]);
|
||||||
if (!region) error->all(FLERR, "Create_atoms region {} does not exist", arg[4]);
|
if (!region) error->all(FLERR, 4, "Create_atoms region {} does not exist", arg[4]);
|
||||||
region->init();
|
region->init();
|
||||||
region->prematch();
|
region->prematch();
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ void CreateAtoms::command(int narg, char **arg)
|
|||||||
meshfile = arg[2];
|
meshfile = arg[2];
|
||||||
iarg = 3;
|
iarg = 3;
|
||||||
} else
|
} else
|
||||||
error->all(FLERR, "Unknown create_atoms command option {}", arg[1]);
|
error->all(FLERR, 1, "Unknown create_atoms command option {}", arg[1]);
|
||||||
|
|
||||||
// process optional keywords
|
// process optional keywords
|
||||||
|
|
||||||
|
|||||||
@ -114,7 +114,7 @@ void Error::universe_warn(const std::string &file, int line, const std::string &
|
|||||||
force MPI_Abort if running in multi-partition mode
|
force MPI_Abort if running in multi-partition mode
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Error::all(const std::string &file, int line, const std::string &str)
|
void Error::all(const std::string &file, int line, int failed, const std::string &str)
|
||||||
{
|
{
|
||||||
MPI_Barrier(world);
|
MPI_Barrier(world);
|
||||||
|
|
||||||
@ -125,9 +125,11 @@ void Error::all(const std::string &file, int line, const std::string &str)
|
|||||||
|
|
||||||
if (me == 0) {
|
if (me == 0) {
|
||||||
std::string mesg = "ERROR: " + str;
|
std::string mesg = "ERROR: " + str;
|
||||||
|
|
||||||
if (input && input->line) lastcmd = input->line;
|
if (input && input->line) lastcmd = input->line;
|
||||||
try {
|
try {
|
||||||
mesg += fmt::format(" ({}:{})\nLast command: {}\n", truncpath(file),line,lastcmd);
|
mesg += fmt::format(" ({}:{})\nLast command: {}\n", truncpath(file),line,lastcmd);
|
||||||
|
if (failed > NOPOINTER) mesg += utils::point_to_error(input, failed);
|
||||||
} catch (fmt::format_error &) {
|
} catch (fmt::format_error &) {
|
||||||
; // do nothing
|
; // do nothing
|
||||||
}
|
}
|
||||||
@ -140,6 +142,7 @@ void Error::all(const std::string &file, int line, const std::string &str)
|
|||||||
if (update) update->whichflag = 0;
|
if (update) update->whichflag = 0;
|
||||||
|
|
||||||
std::string msg = fmt::format("ERROR: {} ({}:{})\n", str, truncpath(file), line);
|
std::string msg = fmt::format("ERROR: {} ({}:{})\n", str, truncpath(file), line);
|
||||||
|
if (failed > NOPOINTER) msg += utils::point_to_error(input, failed);
|
||||||
|
|
||||||
if (universe->nworlds > 1)
|
if (universe->nworlds > 1)
|
||||||
throw LAMMPSAbortException(msg, universe->uworld);
|
throw LAMMPSAbortException(msg, universe->uworld);
|
||||||
@ -154,15 +157,21 @@ void Error::all(const std::string &file, int line, const std::string &str)
|
|||||||
forces abort of entire world (and universe) if any proc in world calls
|
forces abort of entire world (and universe) if any proc in world calls
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Error::one(const std::string &file, int line, const std::string &str)
|
void Error::one(const std::string &file, int line, int failed, const std::string &str)
|
||||||
{
|
{
|
||||||
int me;
|
int me;
|
||||||
std::string lastcmd = "(unknown)";
|
std::string lastcmd = "(unknown)";
|
||||||
MPI_Comm_rank(world,&me);
|
MPI_Comm_rank(world,&me);
|
||||||
|
|
||||||
if (input && input->line) lastcmd = input->line;
|
if (input && input->line) lastcmd = input->line;
|
||||||
std::string mesg = fmt::format("ERROR on proc {}: {} ({}:{})\nLast command: {}\n",
|
std::string mesg;
|
||||||
me,str,truncpath(file),line,lastcmd);
|
try {
|
||||||
|
mesg = fmt::format("ERROR on proc {}: {} ({}:{})\nLast command: {}\n",
|
||||||
|
me,str,truncpath(file),line,lastcmd);
|
||||||
|
if (failed > NOPOINTER) mesg += utils::point_to_error(input, failed);
|
||||||
|
} catch (fmt::format_error &) {
|
||||||
|
; // do nothing
|
||||||
|
}
|
||||||
utils::logmesg(lmp,mesg);
|
utils::logmesg(lmp,mesg);
|
||||||
|
|
||||||
if (universe->nworlds > 1)
|
if (universe->nworlds > 1)
|
||||||
@ -177,27 +186,27 @@ void Error::one(const std::string &file, int line, const std::string &str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
forward vararg version to single string version
|
forward vararg versions to single string version
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Error::_all(const std::string &file, int line, fmt::string_view format,
|
void Error::_all(const std::string &file, int line, int failed, fmt::string_view format,
|
||||||
fmt::format_args args)
|
fmt::format_args args)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
all(file,line,fmt::vformat(format, args));
|
all(file, line, failed, fmt::vformat(format, args));
|
||||||
} catch (fmt::format_error &e) {
|
} catch (fmt::format_error &e) {
|
||||||
all(file,line,e.what());
|
all(file, line, NOPOINTER, e.what());
|
||||||
}
|
}
|
||||||
exit(1); // to trick "smart" compilers into believing this does not return
|
exit(1); // to trick "smart" compilers into believing this does not return
|
||||||
}
|
}
|
||||||
|
|
||||||
void Error::_one(const std::string &file, int line, fmt::string_view format,
|
void Error::_one(const std::string &file, int line, int failed, fmt::string_view format,
|
||||||
fmt::format_args args)
|
fmt::format_args args)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
one(file,line,fmt::vformat(format, args));
|
one(file, line, failed, fmt::vformat(format, args));
|
||||||
} catch (fmt::format_error &e) {
|
} catch (fmt::format_error &e) {
|
||||||
one(file,line,e.what());
|
one(file, line, NOPOINTER, e.what());
|
||||||
}
|
}
|
||||||
exit(1); // to trick "smart" compilers into believing this does not return
|
exit(1); // to trick "smart" compilers into believing this does not return
|
||||||
}
|
}
|
||||||
|
|||||||
49
src/error.h
49
src/error.h
@ -27,18 +27,49 @@ class Error : protected Pointers {
|
|||||||
[[noreturn]] void universe_one(const std::string &, int, const std::string &);
|
[[noreturn]] void universe_one(const std::string &, int, const std::string &);
|
||||||
void universe_warn(const std::string &, int, const std::string &);
|
void universe_warn(const std::string &, int, const std::string &);
|
||||||
|
|
||||||
[[noreturn]] void all(const std::string &, int, const std::string &);
|
static constexpr int NOPOINTER = -2;
|
||||||
template <typename... Args>
|
|
||||||
[[noreturn]] void all(const std::string &file, int line, const std::string &format, Args &&...args)
|
// regular error calls
|
||||||
|
|
||||||
|
[[noreturn]] void all(const std::string &file, int line, const std::string &str)
|
||||||
{
|
{
|
||||||
_all(file, line, format, fmt::make_format_args(args...));
|
all(file, line, NOPOINTER, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void one(const std::string &, int, const std::string &);
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
[[noreturn]] void one(const std::string &file, int line, const std::string &format, Args &&...args)
|
[[noreturn]] void all(const std::string &file, int line, const std::string &format,
|
||||||
|
Args &&...args)
|
||||||
{
|
{
|
||||||
_one(file, line, format, fmt::make_format_args(args...));
|
_all(file, line, NOPOINTER, format, fmt::make_format_args(args...));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]] void one(const std::string &file, int line, const std::string &str)
|
||||||
|
{
|
||||||
|
one(file, line, NOPOINTER, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
[[noreturn]] void one(const std::string &file, int line, const std::string &format,
|
||||||
|
Args &&...args)
|
||||||
|
{
|
||||||
|
_one(file, line, NOPOINTER, format, fmt::make_format_args(args...));
|
||||||
|
}
|
||||||
|
|
||||||
|
// overloaded error calls indicating faulty argument in command line
|
||||||
|
[[noreturn]] void all(const std::string &, int, int, const std::string &);
|
||||||
|
template <typename... Args>
|
||||||
|
[[noreturn]] void all(const std::string &file, int line, int failed, const std::string &format,
|
||||||
|
Args &&...args)
|
||||||
|
{
|
||||||
|
_all(file, line, failed, format, fmt::make_format_args(args...));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]] void one(const std::string &, int, int, const std::string &);
|
||||||
|
template <typename... Args>
|
||||||
|
[[noreturn]] void one(const std::string &file, int line, int failed, const std::string &format,
|
||||||
|
Args &&...args)
|
||||||
|
{
|
||||||
|
_one(file, line, failed, format, fmt::make_format_args(args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
void warning(const std::string &, int, const std::string &);
|
void warning(const std::string &, int, const std::string &);
|
||||||
@ -72,8 +103,8 @@ class Error : protected Pointers {
|
|||||||
|
|
||||||
int numwarn, maxwarn, allwarn;
|
int numwarn, maxwarn, allwarn;
|
||||||
// internal versions that accept explicit fmtlib arguments
|
// internal versions that accept explicit fmtlib arguments
|
||||||
[[noreturn]] void _all(const std::string &, int, fmt::string_view, fmt::format_args args);
|
[[noreturn]] void _all(const std::string &, int, int, fmt::string_view, fmt::format_args args);
|
||||||
[[noreturn]] void _one(const std::string &, int, fmt::string_view, fmt::format_args args);
|
[[noreturn]] void _one(const std::string &, int, int, fmt::string_view, fmt::format_args args);
|
||||||
void _warning(const std::string &, int, fmt::string_view, fmt::format_args args);
|
void _warning(const std::string &, int, fmt::string_view, fmt::format_args args);
|
||||||
void _message(const std::string &, int, fmt::string_view, fmt::format_args args);
|
void _message(const std::string &, int, fmt::string_view, fmt::format_args args);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -28,6 +28,7 @@ class Input : protected Pointers {
|
|||||||
friend class SimpleCommandsTest_Echo_Test;
|
friend class SimpleCommandsTest_Echo_Test;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
char *command; // ptr to current command
|
||||||
int narg; // # of command args
|
int narg; // # of command args
|
||||||
char **arg; // parsed args for command
|
char **arg; // parsed args for command
|
||||||
class Variable *variable; // defined variables
|
class Variable *variable; // defined variables
|
||||||
@ -42,7 +43,6 @@ class Input : protected Pointers {
|
|||||||
int get_jump_skip() const { return jump_skip; }
|
int get_jump_skip() const { return jump_skip; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char *command; // ptr to current command
|
|
||||||
int echo_screen; // 0 = no, 1 = yes
|
int echo_screen; // 0 = no, 1 = yes
|
||||||
int echo_log; // 0 = no, 1 = yes
|
int echo_log; // 0 = no, 1 = yes
|
||||||
|
|
||||||
|
|||||||
@ -132,6 +132,28 @@ void utils::missing_cmd_args(const std::string &file, int line, const std::strin
|
|||||||
if (error) error->all(file, line, "Illegal {} command: missing argument(s)", cmd);
|
if (error) error->all(file, line, "Illegal {} command: missing argument(s)", cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string utils::point_to_error(Input *input, int failedarg)
|
||||||
|
{
|
||||||
|
if (input) {
|
||||||
|
std::string cmdline = "Preprocessed: ";
|
||||||
|
int indicator = cmdline.size(); // error indicator points to command by default
|
||||||
|
cmdline += input->command;
|
||||||
|
cmdline += ' ';
|
||||||
|
|
||||||
|
// assemble pre-processed command line and update error indicator position, if needed.
|
||||||
|
for (int i = 0; i < input->narg; ++i) {
|
||||||
|
if (i == failedarg) indicator = cmdline.size();
|
||||||
|
cmdline += input->arg[i];
|
||||||
|
cmdline += ' ';
|
||||||
|
}
|
||||||
|
// construct and append error indicator line
|
||||||
|
cmdline += '\n';
|
||||||
|
cmdline += std::string(indicator, ' ');
|
||||||
|
cmdline += "^\n";
|
||||||
|
return cmdline;
|
||||||
|
} else return std::string("(Failed command line text not available)");
|
||||||
|
}
|
||||||
|
|
||||||
/* specialization for the case of just a single string argument */
|
/* specialization for the case of just a single string argument */
|
||||||
|
|
||||||
void utils::logmesg(LAMMPS *lmp, const std::string &mesg)
|
void utils::logmesg(LAMMPS *lmp, const std::string &mesg)
|
||||||
|
|||||||
10
src/utils.h
10
src/utils.h
@ -28,6 +28,7 @@ namespace LAMMPS_NS {
|
|||||||
|
|
||||||
// forward declarations
|
// forward declarations
|
||||||
class Error;
|
class Error;
|
||||||
|
class Input;
|
||||||
class LAMMPS;
|
class LAMMPS;
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
@ -59,6 +60,15 @@ namespace utils {
|
|||||||
|
|
||||||
void missing_cmd_args(const std::string &file, int line, const std::string &cmd, Error *error);
|
void missing_cmd_args(const std::string &file, int line, const std::string &cmd, Error *error);
|
||||||
|
|
||||||
|
/*! Create string with last command after pre-processing and pointing to arg with error
|
||||||
|
*
|
||||||
|
* This function is a helper function for error messages. It creates
|
||||||
|
*
|
||||||
|
* \param input pointer to the Input class instance (for access to last command args)
|
||||||
|
* \param failedarg index of the faulty argument (-1 to point to the command itself)
|
||||||
|
* \return string with two lines: the pre-processed command and a '^' pointing to the faulty argument */
|
||||||
|
std::string point_to_error(Input *input, int failedarg);
|
||||||
|
|
||||||
/*! Internal function handling the argument list for logmesg(). */
|
/*! Internal function handling the argument list for logmesg(). */
|
||||||
|
|
||||||
void fmtargs_logmesg(LAMMPS *lmp, fmt::string_view format, fmt::format_args args);
|
void fmtargs_logmesg(LAMMPS *lmp, fmt::string_view format, fmt::format_args args);
|
||||||
|
|||||||
Reference in New Issue
Block a user