provide more generic implementation of Comm::read_lines_from_file() in utils
This commit is contained in:
@ -225,6 +225,36 @@ void utils::sfread(const char *srcname, int srcline, void *s, size_t size,
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
/* read N lines and broadcast */
|
||||
int utils::read_lines_from_file(FILE *fp, int nlines, int maxline,
|
||||
char *buffer, int me, MPI_Comm comm)
|
||||
{
|
||||
char *ptr = buffer;
|
||||
*ptr = '\0';
|
||||
|
||||
if (me == 0) {
|
||||
if (fp) {
|
||||
for (int i = 0; i < nlines; i++) {
|
||||
ptr = fgets(ptr,maxline,fp);
|
||||
if (!ptr) break; // EOF?
|
||||
// advance ptr to end of string and append newline char if needed.
|
||||
ptr += strlen(ptr);
|
||||
if (*(--ptr) != '\n') *(++ptr) = '\n';
|
||||
// ensure buffer is null terminated. null char is start of next line.
|
||||
*(++ptr) = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int n = strlen(buffer);
|
||||
MPI_Bcast(&n,1,MPI_INT,0,comm);
|
||||
if (n == 0) return 1;
|
||||
MPI_Bcast(buffer,n+1,MPI_CHAR,0,comm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
std::string utils::check_packages_for_style(const std::string &style,
|
||||
const std::string &name,
|
||||
LAMMPS *lmp)
|
||||
|
||||
25
src/utils.h
25
src/utils.h
@ -17,9 +17,12 @@
|
||||
/*! \file utils.h */
|
||||
|
||||
#include "lmptype.h"
|
||||
|
||||
#include <mpi.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
@ -89,6 +92,26 @@ namespace LAMMPS_NS {
|
||||
void sfread(const char *srcname, int srcline, void *s, size_t size,
|
||||
size_t num, FILE *fp, const char *filename, Error *error);
|
||||
|
||||
/** Read N lines of text from file into buffer and broadcast them
|
||||
*
|
||||
* This function uses repeated calls to fread() to fill a buffer with
|
||||
* newline terminated text. If a line does not end in a newline (e.g.
|
||||
* at the end of a file), it is added. The caller has to allocate an
|
||||
* nlines by maxline sized buffer for storing the text data.
|
||||
* Reading is done by MPI rank 0 of the given communicator only, and
|
||||
* thus only MPI rank 0 needs to provide a valid file pointer.
|
||||
*
|
||||
* \param fp file pointer used by fread
|
||||
* \param nlines number of lines to be read
|
||||
* \param maxline maximum length of a single line
|
||||
* \param buffer buffer for storing the data.
|
||||
* \param me MPI rank of calling process in MPI communicator
|
||||
* \param comm MPI communicator for broadcast
|
||||
* \return 1 if the read was short, 0 if read was succesful */
|
||||
|
||||
int read_lines_from_file(FILE *fp, int nlines, int maxline,
|
||||
char *buffer, int me, MPI_Comm comm);
|
||||
|
||||
/** Report if a requested style is in a package or may have a typo
|
||||
*
|
||||
* \param style type of style that is to be checked for
|
||||
|
||||
@ -11,13 +11,13 @@
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "../testing/core.h"
|
||||
#include "info.h"
|
||||
#include "input.h"
|
||||
#include "lammps.h"
|
||||
#include "utils.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "../testing/core.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <mpi.h>
|
||||
@ -28,6 +28,7 @@ using namespace LAMMPS_NS;
|
||||
using testing::MatchesRegex;
|
||||
using testing::StrEq;
|
||||
|
||||
using utils::read_lines_from_file;
|
||||
using utils::sfgets;
|
||||
using utils::sfread;
|
||||
using utils::split_words;
|
||||
@ -124,6 +125,37 @@ TEST_F(FileOperationsTest, safe_fread)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
TEST_F(FileOperationsTest, read_lines_from_file)
|
||||
{
|
||||
char *buf = new char[MAX_BUF_SIZE];
|
||||
FILE *fp = nullptr;
|
||||
MPI_Comm world = MPI_COMM_WORLD;
|
||||
int me, rv;
|
||||
memset(buf, 0, MAX_BUF_SIZE);
|
||||
|
||||
rv = utils::read_lines_from_file(nullptr, 1, MAX_BUF_SIZE, buf, me, world);
|
||||
ASSERT_EQ(rv, 1);
|
||||
|
||||
MPI_Comm_rank(world, &me);
|
||||
if (me == 0) {
|
||||
fp = fopen("safe_file_read_test.txt", "r");
|
||||
ASSERT_NE(fp, nullptr);
|
||||
} else
|
||||
ASSERT_EQ(fp, nullptr);
|
||||
|
||||
rv = utils::read_lines_from_file(fp, 2, MAX_BUF_SIZE / 2, buf, me, world);
|
||||
ASSERT_EQ(rv, 0);
|
||||
ASSERT_THAT(buf, StrEq("one line\ntwo_lines\n"));
|
||||
|
||||
rv = utils::read_lines_from_file(fp, 2, MAX_BUF_SIZE / 2, buf, me, world);
|
||||
ASSERT_EQ(rv, 0);
|
||||
ASSERT_THAT(buf, StrEq("\nno newline\n"));
|
||||
|
||||
rv = utils::read_lines_from_file(fp, 2, MAX_BUF_SIZE / 2, buf, me, world);
|
||||
ASSERT_EQ(rv, 1);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
TEST_F(FileOperationsTest, logmesg)
|
||||
{
|
||||
char buf[8];
|
||||
|
||||
Reference in New Issue
Block a user