diff --git a/src/atom.cpp b/src/atom.cpp index 145c744a06..2dc6819978 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -1643,19 +1643,11 @@ void Atom::data_bodies(int n, char *buf, AtomVec *avec_body, tagint id_offset) ninteger = utils::inumeric(FLERR,values[1],false,lmp); ndouble = utils::inumeric(FLERR,values[2],false,lmp); - if (tagdata <= 0 || tagdata > map_tag_max) - error->one(FLERR,"Invalid atom ID in Bodies section of data file"); - if (unique_tags->find(tagdata) == unique_tags->end()) unique_tags->insert(tagdata); else error->one(FLERR,"Duplicate atom ID in Bodies section of data file"); - if (ninteger < 0) - error->one(FLERR,"Invalid number of integers in Bodies section of data file"); - if (ndouble < 0) - error->one(FLERR,"Invalid number of doubles in Bodies section of data file"); - buf = next + 1; m = map(tagdata); if (m >= 0) { diff --git a/src/read_data.cpp b/src/read_data.cpp index 67eadc313c..d789d205f8 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -35,6 +35,7 @@ #include "molecule.h" #include "pair.h" #include "special.h" +#include "tokenizer.h" #include "update.h" #include @@ -1658,12 +1659,12 @@ void ReadData::bonus(bigint nbonus, AtomVec *ptr, const char *type) read all body data variable amount of info per body, described by ninteger and ndouble to find atoms, must build atom map if not a molecular system - if not firstpass, just read past data, but no processing of data + if not firstpass, just read past body data and only process body header ------------------------------------------------------------------------- */ void ReadData::bodies(int firstpass, AtomVec *ptr) { - int m,nchunk,nline,nmax,ninteger,ndouble,nword,ncount,onebody,tmp,rv; + int m,nchunk,nline,nmax,ninteger,ndouble,nword,ncount,onebody; char *eof; int mapflag = 0; @@ -1690,11 +1691,25 @@ void ReadData::bodies(int firstpass, AtomVec *ptr) while (nchunk < nmax && nline <= CHUNK-MAXBODY) { eof = utils::fgets_trunc(&buffer[m],MAXLINE,fp); + const char *buf = &buffer[m]; if (eof == nullptr) error->one(FLERR,"Unexpected end of data file"); - rv = sscanf(&buffer[m],"%d %d %d",&tmp,&ninteger,&ndouble); - if (rv != 3) - error->one(FLERR,"Incorrect format in Bodies section of data file"); - m += strlen(&buffer[m]); + try { + auto values = ValueTokenizer(utils::trim_comment(buf)); + tagint tagdata = values.next_tagint() + id_offset; + ninteger = values.next_int(); + ndouble = values.next_double(); + if (tagdata <= 0 || tagdata > atom->map_tag_max) + throw TokenizerException("Invalid atom ID in body header", utils::trim(buf)); + if (ninteger < 0) + throw TokenizerException("Invalid number of integers", utils::trim(buf)); + if (ndouble < 0) + throw TokenizerException("Invalid number of doubles", utils::trim(buf)); + if (values.has_next()) + throw TokenizerException("Too many tokens in body header", utils::trim(buf)); + } catch (TokenizerException &e) { + error->one(FLERR,std::string(e.what()) + " while reading Bodies section of data file"); + } + m += strlen(buf); // read lines one at a time into buffer and count words // count to ninteger and ndouble until have enough lines