refactor how error output is created and only print input and parsed line if they differ in text

This commit is contained in:
Axel Kohlmeyer
2025-01-17 18:06:31 -05:00
parent 9b443c9a4d
commit e350f28e26
5 changed files with 63 additions and 55 deletions

View File

@ -121,16 +121,9 @@ void Error::all(const std::string &file, int line, int failed, const std::string
std::string lastcmd = "(unknown)";
std::string mesg = "ERROR: " + str + fmt::format(" ({}:{})\n", truncpath(file), line);
if (input && input->line) lastcmd = input->line;
// add text about the input following the error message
if (failed > NOLASTLINE) {
try {
mesg += fmt::format("Last input line: {}\n", lastcmd);
if (failed > NOPOINTER) mesg += utils::point_to_error(input, failed);
} catch (fmt::format_error &) {
; // do nothing
}
}
if (failed > NOLASTLINE) mesg += utils::point_to_error(input, failed);
if (comm->me == 0) utils::logmesg(lmp,mesg);
// allow commands if an exception was caught in a run
@ -153,23 +146,11 @@ void Error::all(const std::string &file, int line, int failed, const std::string
void Error::one(const std::string &file, int line, int failed, const std::string &str)
{
int me;
std::string lastcmd = "(unknown)";
MPI_Comm_rank(world,&me);
if (input && input->line) lastcmd = input->line;
std::string mesg;
try {
if (failed == NOLASTLINE) {
mesg = fmt::format("ERROR on proc {}: {} ({}:{})\n", me, str, truncpath(file), line);
} else {
mesg = fmt::format("ERROR on proc {}: {} ({}:{})\nLast input line: {}\n",
me, str, truncpath(file), line, lastcmd);
}
if (failed > NOPOINTER) mesg += utils::point_to_error(input, failed);
} catch (fmt::format_error &) {
; // do nothing
}
std::string mesg = fmt::format("ERROR on proc {}: {} ({}:{})\n", comm->me, str,
truncpath(file), line);
if (failed > NOPOINTER) mesg += utils::point_to_error(input, failed);
utils::logmesg(lmp,mesg);
if (universe->nworlds > 1)

View File

@ -1075,7 +1075,7 @@ void FixAveTime::options(int iarg, int narg, char **arg)
if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time mode", error);
if (strcmp(arg[iarg+1],"scalar") == 0) mode = SCALAR;
else if (strcmp(arg[iarg+1],"vector") == 0) mode = VECTOR;
else error->all(FLERR,"Unknown fix ave/time mode {}", arg[iarg+1]);
else error->all(FLERR,iarg+1,"Unknown fix ave/time mode {}", arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"off") == 0) {
if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "fix ave/time off", error);

View File

@ -26,6 +26,7 @@ class Input : protected Pointers {
friend class Error;
friend class Deprecated;
friend class SimpleCommandsTest_Echo_Test;
friend std::string utils::point_to_error(Input *input, int failed);
public:
char *command; // ptr to current command

View File

@ -158,39 +158,65 @@ void utils::missing_cmd_args(const std::string &file, int line, const std::strin
std::string utils::point_to_error(Input *input, int failed)
{
if (input) {
std::string cmdline = "--> parsed line: ";
int indicator = cmdline.size(); // error indicator points to command by default
cmdline += input->command;
cmdline += ' ';
std::string lastline = input->line;
std::string lastargs = input->command;
std::string cmdline = "Last input line: ";
// assemble pre-processed command line and update error indicator position, if needed.
for (int i = 0; i < input->narg; ++i) {
std::string inputarg = input->arg[i];
if (i == failed) indicator = cmdline.size();
// extended output
if (failed > Error::NOPOINTER) {
// argument contains whitespace. add quotes. check which type of quotes, too
if (inputarg.find_first_of(" \t\n") != std::string::npos) {
if (inputarg.find_first_of('"') != std::string::npos) {
cmdline += "'";
cmdline += inputarg;
cmdline += "'";
} else {
cmdline += '"';
cmdline += inputarg;
cmdline += '"';
}
} else
cmdline += inputarg;
cmdline += ' ';
// indicator points to command by default
int indicator = 0;
int quoted = 0;
lastargs += ' ';
// assemble pre-processed command line and update error indicator position, if needed.
for (int i = 0; i < input->narg; ++i) {
std::string inputarg = input->arg[i];
if (i == failed) indicator = lastargs.size();
// argument contains whitespace. add quotes. check which type of quotes, too
if (inputarg.find_first_of(" \t\n") != std::string::npos) {
if (i == failed) quoted = 2;
if (inputarg.find_first_of('"') != std::string::npos) {
lastargs += "'";
lastargs += inputarg;
lastargs += "'";
} else {
lastargs += '"';
lastargs += inputarg;
lastargs += '"';
}
} else
lastargs += inputarg;
lastargs += ' ';
}
indicator += cmdline.size();
// the string is unchanged by substitution (ignoring whitespace), print output only once
if (utils::strsame(lastline, lastargs)) {
cmdline += lastargs;
} else {
cmdline += lastline;
cmdline += '\n';
// must have the same number of chars as "Last input line: " used in the previous line
cmdline += "--> parsed line: ";
cmdline += lastargs;
}
// construct and append error indicator line
cmdline += '\n';
cmdline += std::string(indicator, ' ');
cmdline += std::string(strlen(input->arg[failed]) + quoted, '^');
cmdline += '\n';
} else {
cmdline += input->line;
cmdline += '\n';
}
// construct and append error indicator line
cmdline += '\n';
cmdline += std::string(indicator, ' ');
cmdline += std::string(strlen(input->arg[failed]), '^');
cmdline += '\n';
return cmdline;
} else
return std::string("(Failed command line text not available)");
return std::string("(Failed input line text not available)");
}
/* specialization for the case of just a single string argument */

View File

@ -68,7 +68,7 @@ namespace utils {
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
/*! Create string with last command and optionally pointing to arg with error
*
* This function is a helper function for error messages. It creates
*
@ -349,7 +349,7 @@ namespace utils {
template <typename TYPE>
void bounds(const char *file, int line, const std::string &str, bigint nmin, bigint nmax,
TYPE &nlo, TYPE &nhi, Error *error, int failed = -2); // -2 = Error::NOPOINTER
TYPE &nlo, TYPE &nhi, Error *error, int failed = -2); // -2 = Error::NOPOINTER
/*! Same as utils::bounds(), but string may be a typelabel
*