support that LAMMPS_POTENTIALS is a real path variable with multiple entries, not just a single folder

This commit is contained in:
Axel Kohlmeyer
2020-08-29 22:09:07 -04:00
parent 05ff352021
commit 5a22f4d7f2
3 changed files with 35 additions and 13 deletions

View File

@ -33,7 +33,7 @@ class Tokenizer {
size_t start; size_t start;
size_t ntokens; size_t ntokens;
public: public:
Tokenizer(const std::string & str, const std::string & separators = TOKENIZER_DEFAULT_SEPARATORS); Tokenizer(const std::string &str, const std::string &separators = TOKENIZER_DEFAULT_SEPARATORS);
Tokenizer(Tokenizer &&); Tokenizer(Tokenizer &&);
Tokenizer(const Tokenizer &); Tokenizer(const Tokenizer &);
Tokenizer& operator=(const Tokenizer&) = default; Tokenizer& operator=(const Tokenizer&) = default;
@ -42,7 +42,7 @@ public:
void reset(); void reset();
void skip(int n); void skip(int n);
bool has_next() const; bool has_next() const;
bool contains(const std::string & str) const; bool contains(const std::string &str) const;
std::string next(); std::string next();
size_t count(); size_t count();
@ -52,7 +52,7 @@ public:
class TokenizerException : public std::exception { class TokenizerException : public std::exception {
std::string message; std::string message;
public: public:
TokenizerException(const std::string & msg, const std::string & token); TokenizerException(const std::string &msg, const std::string &token);
~TokenizerException() throw() { ~TokenizerException() throw() {
} }
@ -64,20 +64,20 @@ public:
class InvalidIntegerException : public TokenizerException { class InvalidIntegerException : public TokenizerException {
public: public:
InvalidIntegerException(const std::string & token) : TokenizerException("Not a valid integer number", token) { InvalidIntegerException(const std::string &token) : TokenizerException("Not a valid integer number", token) {
} }
}; };
class InvalidFloatException : public TokenizerException { class InvalidFloatException : public TokenizerException {
public: public:
InvalidFloatException(const std::string & token) : TokenizerException("Not a valid floating-point number", token) { InvalidFloatException(const std::string &token) : TokenizerException("Not a valid floating-point number", token) {
} }
}; };
class ValueTokenizer { class ValueTokenizer {
Tokenizer tokens; Tokenizer tokens;
public: public:
ValueTokenizer(const std::string & str, const std::string & separators = TOKENIZER_DEFAULT_SEPARATORS); ValueTokenizer(const std::string &str, const std::string &separators = TOKENIZER_DEFAULT_SEPARATORS);
ValueTokenizer(const ValueTokenizer &); ValueTokenizer(const ValueTokenizer &);
ValueTokenizer(ValueTokenizer &&); ValueTokenizer(ValueTokenizer &&);
ValueTokenizer& operator=(const ValueTokenizer&) = default; ValueTokenizer& operator=(const ValueTokenizer&) = default;
@ -90,7 +90,7 @@ public:
double next_double(); double next_double();
bool has_next() const; bool has_next() const;
bool contains(const std::string & value) const; bool contains(const std::string &value) const;
void skip(int ntokens); void skip(int ntokens);
size_t count(); size_t count();

View File

@ -16,6 +16,7 @@
#include <cstdlib> #include <cstdlib>
#include <cerrno> #include <cerrno>
#include "lammps.h" #include "lammps.h"
#include "comm.h"
#include "compute.h" #include "compute.h"
#include "error.h" #include "error.h"
#include "fix.h" #include "fix.h"
@ -23,6 +24,7 @@
#include "modify.h" #include "modify.h"
#include "tokenizer.h" #include "tokenizer.h"
#include "text_file_reader.h" #include "text_file_reader.h"
#include "update.h"
#include "fmt/format.h" #include "fmt/format.h"
#if defined(__linux__) #if defined(__linux__)
@ -822,6 +824,11 @@ bool utils::file_is_readable(const std::string &path) {
search current directory and the LAMMPS_POTENTIALS directory if search current directory and the LAMMPS_POTENTIALS directory if
specified specified
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#if defined(_WIN32)
#define OS_PATH_VAR_SEP ";"
#else
#define OS_PATH_VAR_SEP ":"
#endif
std::string utils::get_potential_file_path(const std::string &path) { std::string utils::get_potential_file_path(const std::string &path) {
std::string filepath = path; std::string filepath = path;
@ -831,19 +838,25 @@ std::string utils::get_potential_file_path(const std::string &path) {
return filepath; return filepath;
} else { } else {
// try the environment variable directory // try the environment variable directory
const char *path = getenv("LAMMPS_POTENTIALS"); const char *var = getenv("LAMMPS_POTENTIALS");
if (path != nullptr){ if (var != nullptr){
std::string pot = utils::path_basename(filepath); Tokenizer dirs(var,OS_PATH_VAR_SEP);
filepath = utils::path_join(path, pot);
if (utils::file_is_readable(filepath)) { while (dirs.has_next()) {
return filepath; auto pot = utils::path_basename(filepath);
auto path = dirs.next();
filepath = utils::path_join(path, pot);
if (utils::file_is_readable(filepath)) {
return filepath;
}
} }
} }
} }
return ""; return "";
} }
#undef OS_PATH_VAR_SEP
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
read first line of potential file read first line of potential file

View File

@ -62,6 +62,15 @@ TEST(Tokenizer, iterate_words)
ASSERT_EQ(t.count(), 2); ASSERT_EQ(t.count(), 2);
} }
TEST(Tokenizer, no_separator_path)
{
Tokenizer t("one", ":");
ASSERT_EQ(t.has_next(), true);
ASSERT_EQ(t.count(), 1);
ASSERT_THAT(t.next(), Eq("one"));
ASSERT_EQ(t.has_next(), false);
}
TEST(Tokenizer, unix_paths) TEST(Tokenizer, unix_paths)
{ {
Tokenizer t(":one:two:three:", ":"); Tokenizer t(":one:two:three:", ":");