Example #1
0
// static
std::string File::readToString(const char *filename)
{
    // Binary mode is required on Windows to be able to determine a size
    // that can be passed to fread().
    File file(filename, "rb");
    FILE *fp = file.handle();

    if (std::fseek(fp, 0L, SEEK_END) != 0)
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Seeking to end of file failed"),
                             "fseek", errno);
    }
    long len = std::ftell(fp);
    if (len == -1)
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Reading file length failed"),
                             "ftell", errno);
    }
    if (std::fseek(fp, 0L, SEEK_SET) != 0)
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Seeking to start of file failed"),
                             "fseek", errno);
    }

    std::vector<char> data(len);
    file.readBytes(&data[0], len);
    file.close();

    std::string result(&data[0], len);
    // The below is necessary on Windows to make newlines stay as '\n' on a
    // roundtrip.
    result = replaceAll(result, "\r\n", "\n");

    return result;
}
Example #2
0
/*! \brief Get the path to the main folder storing OpenCL kernels.
 *
 * By default, this function constructs the full path to the OpenCL from
 * the known location of the binary that is running, so that we handle
 * both in-source and installed builds. The user can override this
 * behavior by defining GMX_OCL_FILE_PATH environment variable.
 *
 * \return OS-normalized path string to the main folder storing OpenCL kernels
 *
 * \throws std::bad_alloc    if out of memory.
 *         FileIOError  if GMX_OCL_FILE_PATH does not specify a readable path
 */
static std::string
getKernelRootPath()
{
    std::string kernelRootPath;
    /* Use GMX_OCL_FILE_PATH if the user has defined it */
    const char *gmxOclFilePath = getenv("GMX_OCL_FILE_PATH");

    if (gmxOclFilePath == nullptr)
    {
        /* Normal way of getting ocl_root_dir. First get the right
           root path from the path to the binary that is running. */
        InstallationPrefixInfo      info           = getProgramContext().installationPrefix();
        std::string                 dataPathSuffix = (info.bSourceLayout ?
                                                      "src/gromacs/mdlib/nbnxn_ocl" :
                                                      OCL_INSTALL_DIR);
        kernelRootPath = Path::join(info.path, dataPathSuffix);
    }
    else
    {
        if (!Directory::exists(gmxOclFilePath))
        {
            GMX_THROW(FileIOError(formatString("GMX_OCL_FILE_PATH must point to the directory where OpenCL"
                                               "kernels are found, but '%s' does not exist", gmxOclFilePath)));
        }
        kernelRootPath = gmxOclFilePath;
    }

    // Make sure we return an OS-correct path format
    return Path::normalize(kernelRootPath);
}
Example #3
0
bool File::readLine(std::string *line)
{
    line->clear();
    const size_t bufsize = 256;
    std::string result;
    char buf[bufsize];
    buf[0] = '\0';
    FILE *fp = handle();
    while (fgets(buf, bufsize, fp) != NULL)
    {
        size_t length = std::strlen(buf);
        result.append(buf, length);
        if (length < bufsize - 1 || buf[length - 1] == '\n')
        {
            break;
        }
    }
    if (ferror(fp))
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
                             "fgets", errno);
    }
    *line = result;
    return !result.empty() || !feof(fp);
}
Example #4
0
EnergyFrameReaderPtr
openEnergyFileToReadFields(const std::string              &filename,
                           const std::vector<std::string> &namesOfRequiredEnergyFields)
{
    ener_file_ptr energyFile(open_enx(filename.c_str(), "r"));

    if (!energyFile)
    {
        GMX_THROW(FileIOError("Could not open energy file " + filename + " for reading"));
    }

    /* Read in the names of energy fields used in this file. The
     * resulting data structure would leak if an exception was thrown,
     * so transfer the contents that we actually need to a map we can
     * keep.
     *
     * TODO Technically, the insertions into the map could throw
     * std::bad_alloc and we could leak memory allocated by
     * do_enxnms(), but there's nothing we can do about this right
     * now. */
    std::map<std::string, int> indicesOfEnergyFields;
    {
        int          numEnergyTerms;
        gmx_enxnm_t *energyNames = nullptr;
        do_enxnms(energyFile.get(), &numEnergyTerms, &energyNames);
        for (int i = 0; i != numEnergyTerms; ++i)
        {
            const char *name           = energyNames[i].name;
            auto        requiredEnergy = std::find_if(std::begin(namesOfRequiredEnergyFields),
                                                      std::end(namesOfRequiredEnergyFields),
                                                      [name](const std::string &n){
                                                          return 0 == n.compare(name);
                                                      });
            if (requiredEnergy != namesOfRequiredEnergyFields.end())
            {
                indicesOfEnergyFields[name] = i;
            }
        }
        // Clean up old data structures
        free_enxnms(numEnergyTerms, energyNames);
    }

    // Throw if we failed to find the fields we need
    if (indicesOfEnergyFields.size() != namesOfRequiredEnergyFields.size())
    {
        std::string requiredEnergiesNotFound = "Did not find the following required energies in mdrun output:\n";
        for (auto &name : namesOfRequiredEnergyFields)
        {
            auto possibleIndex = indicesOfEnergyFields.find(name);
            if (possibleIndex == indicesOfEnergyFields.end())
            {
                requiredEnergiesNotFound += name + "\n";
            }
        }
        GMX_THROW(APIError(requiredEnergiesNotFound));
    }

    return EnergyFrameReaderPtr(new EnergyFrameReader(indicesOfEnergyFields, energyFile.release()));
}
Example #5
0
void File::writeString(const char *str)
{
    if (fprintf(handle(), "%s", str) < 0)
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Writing to file failed"),
                             "fprintf", errno);
    }
}
Example #6
0
void File::throwOnError(const NotFoundInfo &info)
{
    if (info.wasError)
    {
        const std::string message
            = formatString("Failed to access file '%s'.\n%s",
                           info.filename, info.message);
        GMX_THROW_WITH_ERRNO(FileIOError(message), info.call, info.err);
    }
}
Example #7
0
std::vector<DataFileInfo>
DataFileFinder::enumerateFiles(const DataFileOptions &options) const
{
    // TODO: Consider if not being able to list one of the directories should
    // really be a fatal error. Or alternatively, check somewhere else that
    // paths in GMXLIB are valid.
    std::vector<DataFileInfo>                result;
    std::vector<std::string>::const_iterator i;
    if (options.bCurrentDir_)
    {
        std::vector<std::string> files
            = DirectoryEnumerator::enumerateFilesWithExtension(
                        ".", options.filename_, false);
        for (i = files.begin(); i != files.end(); ++i)
        {
            result.emplace_back(".", *i, false);
        }
    }
    if (impl_ != nullptr)
    {
        std::vector<std::string>::const_iterator j;
        for (j = impl_->searchPath_.begin(); j != impl_->searchPath_.end(); ++j)
        {
            std::vector<std::string> files
                = DirectoryEnumerator::enumerateFilesWithExtension(
                            j->c_str(), options.filename_, false);
            for (i = files.begin(); i != files.end(); ++i)
            {
                result.emplace_back(*j, *i, false);
            }
        }
    }
    const std::string &defaultPath = Impl::getDefaultPath();
    if (!defaultPath.empty())
    {
        std::vector<std::string> files
            = DirectoryEnumerator::enumerateFilesWithExtension(
                        defaultPath.c_str(), options.filename_, false);
        for (i = files.begin(); i != files.end(); ++i)
        {
            result.emplace_back(defaultPath, *i, true);
        }
    }
    if (result.empty() && options.bThrow_)
    {
        // TODO: Print the search path as is done in findFile().
        std::string message(
                formatString("Could not find any files ending on '%s' in the "
                             "current directory or the GROMACS library search path",
                             options.filename_));
        GMX_THROW(FileIOError(message));
    }
    return result;
}
Example #8
0
// static
FILE *File::openRawHandle(const char *filename, const char *mode)
{
    FILE *fp = fopen(filename, mode);
    if (fp == NULL)
    {
        GMX_THROW_WITH_ERRNO(
                FileIOError(formatString("Could not open file '%s'", filename)),
                "fopen", errno);
    }
    return fp;
}
void
IntegrationTestFixture::redirectStringToStdin(const char* theString)
{
    std::string fakeStdin("fake-stdin");
    gmx::File::writeFileFromString(fakeStdin, theString);
    if (NULL == std::freopen(fakeStdin.c_str(), "r", stdin))
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Failed to redirect a string to stdin"),
                             "freopen",
                             errno);
    }
}
Example #10
0
void File::open(const char *filename, const char *mode)
{
    GMX_RELEASE_ASSERT(impl_->fp_ == NULL,
                       "Attempted to open the same file object twice");
    // TODO: Port all necessary functionality from ffopen() here.
    impl_->fp_ = fopen(filename, mode);
    if (impl_->fp_ == NULL)
    {
        GMX_THROW_WITH_ERRNO(
                FileIOError(formatString("Could not open file '%s'", filename)),
                "fopen", errno);
    }
}
Example #11
0
void File::close()
{
    GMX_RELEASE_ASSERT(impl_->fp_ != NULL,
                       "Attempted to close a file object that is not open");
    GMX_RELEASE_ASSERT(impl_->bClose_,
                       "Attempted to close a file object that should not be");
    bool bOk = (fclose(impl_->fp_) == 0);
    impl_->fp_ = NULL;
    if (!bOk)
    {
        GMX_THROW_WITH_ERRNO(
                FileIOError("Error while closing file"), "fclose", errno);
    }
}
Example #12
0
void File::readBytes(void *buffer, size_t bytes)
{
    errno = 0;
    FILE *fp = handle();
    // TODO: Retry based on errno or something else?
    size_t bytesRead = std::fread(buffer, 1, bytes, fp);
    if (bytesRead != bytes)
    {
        if (feof(fp))
        {
            GMX_THROW(FileIOError(
                        formatString("Premature end of file\n"
                                     "Attempted to read: %d bytes\n"
                                     "Successfully read: %d bytes",
                                     static_cast<int>(bytes),
                                     static_cast<int>(bytesRead))));
        }
        else
        {
            GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
                                 "fread", errno);
        }
    }
}
Example #13
0
void HttpClient::loadResponse() {

	if (request == null) {
		throw FileIOError(THISLOCATION, 1, "Can't read response without request");
	}

	if (!request->isOutputClosed()) request->closeOutput();

	if (response == null) {
		createResponse(true);
	} else {
		response->readHeaders();
	}


	while (response->canContinue()) {
		response->waitAfterContinue(HttpResponse::readHeadersNow);
	}

	request = null;
}
Example #14
0
bool
TrajectoryFrameReader::readNextFrame()
{
    if (haveProbedForNextFrame_)
    {
        if (nextFrameExists_)
        {
            GMX_THROW(APIError("This frame has already been probed for, it should be used before probing again."));
        }
        else
        {
            GMX_THROW(APIError("This frame has already been probed for, it doesn't exist, so there should not be subsequent attempts to probe for it."));
        }
    }
    haveProbedForNextFrame_ = true;
    // If there's a next frame, read it into trxframe_, and report the result.
    if (!haveReadFirstFrame_)
    {
        t_trxstatus *trajectoryFile;
        int          flags = TRX_READ_X | TRX_READ_V | TRX_READ_F;
        nextFrameExists_ = read_first_frame(oenvGuard_.get(),
                                            &trajectoryFile,
                                            filename_.c_str(),
                                            trxframeGuard_.get(),
                                            flags);
        if (!trajectoryFile)
        {
            GMX_THROW(FileIOError("Could not open trajectory file " + filename_ + " for reading"));
        }
        trajectoryFileGuard_.reset(trajectoryFile);
        haveReadFirstFrame_ = true;
    }
    else
    {
        nextFrameExists_ = read_next_frame(oenvGuard_.get(),
                                           trajectoryFileGuard_.get(),
                                           trxframeGuard_.get());
    }
    return nextFrameExists_;
}
Example #15
0
cl_program
compileProgram(FILE              *fplog,
               const std::string &kernelBaseFilename,
               const std::string &extraDefines,
               cl_context         context,
               cl_device_id       deviceId,
               ocl_vendor_id_t    deviceVendorId)
{
    cl_int      cl_error;
    std::string kernelRootPath = getKernelRootPath();

    GMX_RELEASE_ASSERT(fplog != nullptr, "Need a valid log file for building OpenCL programs");

    /* Load OpenCL source files */
    std::string kernelFilename = Path::join(kernelRootPath,
                                            kernelBaseFilename);

    /* Make the build options */
    std::string preprocessorOptions = makePreprocessorOptions(kernelRootPath,
                                                              getWarpSize(context, deviceId),
                                                              deviceVendorId,
                                                              extraDefines);

    bool        buildCacheWasRead = false;

    std::string cacheFilename;
    if (useBuildCache)
    {
        cacheFilename = makeBinaryCacheFilename(kernelBaseFilename, deviceId);
    }

    /* Create OpenCL program */
    cl_program program = nullptr;
    if (useBuildCache)
    {
        if (File::exists(cacheFilename, File::returnFalseOnError))
        {
            /* Check if there's a valid cache available */
            try
            {
                program           = makeProgramFromCache(cacheFilename, context, deviceId);
                buildCacheWasRead = true;
            }
            catch (FileIOError &e)
            {
                // Failing to read from the cache is not a critical error
                formatExceptionMessageToFile(fplog, e);
            }
        }
        else
        {
            fprintf(fplog, "No OpenCL binary cache file was present, so will compile kernels normally.\n");
        }
    }
    if (program == nullptr)
    {
        // Compile OpenCL program from source
        std::string kernelSource = TextReader::readFileToString(kernelFilename);
        if (kernelSource.empty())
        {
            GMX_THROW(FileIOError("Error loading OpenCL code " + kernelFilename));
        }
        const char *kernelSourcePtr  = kernelSource.c_str();
        size_t      kernelSourceSize = kernelSource.size();
        /* Create program from source code */
        program = clCreateProgramWithSource(context,
                                            1,
                                            &kernelSourcePtr,
                                            &kernelSourceSize,
                                            &cl_error);
        if (cl_error != CL_SUCCESS)
        {
            GMX_THROW(InternalError("Could not create OpenCL program, error was " + ocl_get_error_string(cl_error)));
        }
    }

    /* Build the OpenCL program, keeping the status to potentially
       write to the simulation log file. */
    cl_int buildStatus = clBuildProgram(program, 0, NULL, preprocessorOptions.c_str(), NULL, NULL);

    /* Write log first, and then throw exception that the user know what is
       the issue even if the build fails. */
    writeOclBuildLog(fplog,
                     program,
                     deviceId,
                     kernelFilename,
                     preprocessorOptions,
                     buildStatus != CL_SUCCESS);

    if (buildStatus != CL_SUCCESS)
    {
        GMX_THROW(InternalError("Could not build OpenCL program, error was " + ocl_get_error_string(buildStatus)));
    }

    if (useBuildCache)
    {
        if (!buildCacheWasRead)
        {
            /* If OpenCL caching is ON, but the current cache is not
               valid => update it */
            try
            {
                writeBinaryToCache(program, cacheFilename);
            }
            catch (GromacsException &e)
            {
                // Failing to write the cache is not a critical error
                formatExceptionMessageToFile(fplog, e);
            }
        }
    }
    if ((OCL_VENDOR_NVIDIA == deviceVendorId) && getenv("GMX_OCL_DUMP_INTERM_FILES"))
    {
        /* If dumping intermediate files has been requested and this is an NVIDIA card
           => write PTX to file */
        char buffer[STRLEN];

        cl_error = clGetDeviceInfo(deviceId, CL_DEVICE_NAME, sizeof(buffer), buffer, NULL);
        if (cl_error != CL_SUCCESS)
        {
            GMX_THROW(InternalError("Could not get OpenCL device info, error was " + ocl_get_error_string(cl_error)));
        }
        std::string ptxFilename = buffer;
        ptxFilename += ".ptx";

        try
        {
            writeBinaryToCache(program, ptxFilename);
        }
        catch (GromacsException &e)
        {
            // Failing to write the cache is not a critical error
            formatExceptionMessageToFile(fplog, e);
        }
    }

    return program;
}
Example #16
0
void
TrajectoryAnalysisRunnerCommon::Impl::initFirstFrame()
{
    // Return if we have already initialized the trajectory.
    if (fr != NULL)
    {
        return;
    }
    time_unit_t time_unit
        = static_cast<time_unit_t>(settings_.timeUnit() + 1);
    output_env_init(&oenv_, getProgramContext(), time_unit, FALSE, exvgNONE, 0);

    int frflags = settings_.frflags();
    frflags |= TRX_NEED_X;

    snew(fr, 1);

    if (hasTrajectory())
    {
        if (!read_first_frame(oenv_, &status_, trjfile_.c_str(), fr, frflags))
        {
            GMX_THROW(FileIOError("Could not read coordinates from trajectory"));
        }
        bTrajOpen_ = true;

        if (topInfo_.hasTopology())
        {
            const int topologyAtomCount = topInfo_.topology()->atoms.nr;
            if (fr->natoms > topologyAtomCount)
            {
                const std::string message
                    = formatString("Trajectory (%d atoms) does not match topology (%d atoms)",
                                   fr->natoms, topologyAtomCount);
                GMX_THROW(InconsistentInputError(message));
            }
        }
    }
    else
    {
        // Prepare a frame from topology information.
        // TODO: Initialize more of the fields.
        if (frflags & (TRX_NEED_V))
        {
            GMX_THROW(NotImplementedError("Velocity reading from a topology not implemented"));
        }
        if (frflags & (TRX_NEED_F))
        {
            GMX_THROW(InvalidInputError("Forces cannot be read from a topology"));
        }
        fr->natoms = topInfo_.topology()->atoms.nr;
        fr->bX     = TRUE;
        snew(fr->x, fr->natoms);
        memcpy(fr->x, topInfo_.xtop_,
               sizeof(*fr->x) * fr->natoms);
        fr->bBox   = TRUE;
        copy_mat(topInfo_.boxtop_, fr->box);
    }

    set_trxframe_ePBC(fr, topInfo_.ePBC());
    if (topInfo_.hasTopology() && settings_.hasRmPBC())
    {
        gpbc_ = gmx_rmpbc_init(&topInfo_.topology()->idef, topInfo_.ePBC(),
                               fr->natoms);
    }
}
Example #17
0
void
TrajectoryAnalysisRunnerCommon::initFirstFrame()
{
    // Return if we have already initialized the trajectory.
    if (impl_->fr)
    {
        return;
    }
    time_unit_t time_unit
        = static_cast<time_unit_t>(impl_->settings_.timeUnit() + 1);
    output_env_init(&impl_->oenv_, 0, NULL, time_unit, FALSE, exvgNONE, 0, 0);

    int frflags = impl_->settings_.frflags();
    frflags |= TRX_NEED_X;

    snew(impl_->fr, 1);

    const TopologyInformation &top = impl_->topInfo_;
    if (hasTrajectory())
    {
        if (!read_first_frame(impl_->oenv_, &impl_->status_,
                              impl_->trjfile_.c_str(), impl_->fr, frflags))
        {
            GMX_THROW(FileIOError("Could not read coordinates from trajectory"));
        }
        impl_->bTrajOpen_ = true;

        if (top.hasTopology() && impl_->fr->natoms > top.topology()->atoms.nr)
        {
            GMX_THROW(InconsistentInputError(formatString(
                                                     "Trajectory (%d atoms) does not match topology (%d atoms)",
                                                     impl_->fr->natoms, top.topology()->atoms.nr)));
        }
        // Check index groups if they have been initialized based on the topology.
        /*
           if (top)
           {
            for (int i = 0; i < impl_->sel->nr(); ++i)
            {
                gmx_ana_index_check(impl_->sel->sel(i)->indexGroup(),
                                    impl_->fr->natoms);
            }
           }
         */
    }
    else
    {
        // Prepare a frame from topology information.
        // TODO: Initialize more of the fields.
        if (frflags & (TRX_NEED_V))
        {
            GMX_THROW(NotImplementedError("Velocity reading from a topology not implemented"));
        }
        if (frflags & (TRX_NEED_F))
        {
            GMX_THROW(InvalidInputError("Forces cannot be read from a topology"));
        }
        impl_->fr->flags  = frflags;
        impl_->fr->natoms = top.topology()->atoms.nr;
        impl_->fr->bX     = TRUE;
        snew(impl_->fr->x, impl_->fr->natoms);
        memcpy(impl_->fr->x, top.xtop_,
               sizeof(*impl_->fr->x) * impl_->fr->natoms);
        impl_->fr->bBox   = TRUE;
        copy_mat(const_cast<rvec *>(top.boxtop_), impl_->fr->box);
    }

    set_trxframe_ePBC(impl_->fr, top.ePBC());
    if (top.hasTopology() && impl_->settings_.hasRmPBC())
    {
        impl_->gpbc_ = gmx_rmpbc_init(&top.topology()->idef, top.ePBC(),
                                      impl_->fr->natoms, impl_->fr->box);
    }
}
Example #18
0
bool Path::isEquivalent(const std::string &path1, const std::string &path2)
{
    //based on boost_1_56_0/libs/filesystem/src/operations.cpp under BSL
#ifdef GMX_NATIVE_WINDOWS
    // Note well: Physical location on external media is part of the
    // equivalence criteria. If there are no open handles, physical location
    // can change due to defragmentation or other relocations. Thus handles
    // must be held open until location information for both paths has
    // been retrieved.

    // p2 is done first, so any error reported is for p1
    // FixME: #1635
    handle_wrapper h2(
            CreateFile(
                    path2.c_str(),
                    0,
                    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                    0,
                    OPEN_EXISTING,
                    FILE_FLAG_BACKUP_SEMANTICS,
                    0));

    handle_wrapper h1(
            CreateFile(
                    path1.c_str(),
                    0,
                    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                    0,
                    OPEN_EXISTING,
                    FILE_FLAG_BACKUP_SEMANTICS,
                    0));

    if (h1.handle == INVALID_HANDLE_VALUE
        || h2.handle == INVALID_HANDLE_VALUE)
    {
        // if one is invalid and the other isn't, then they aren't equivalent,
        // but if both are invalid then it is an error
        if (h1.handle == INVALID_HANDLE_VALUE
            && h2.handle == INVALID_HANDLE_VALUE)
        {
            GMX_THROW(FileIOError("Path::isEquivalent called with two invalid files"));
        }

        return false;
    }

    // at this point, both handles are known to be valid

    BY_HANDLE_FILE_INFORMATION info1, info2;

    if (!GetFileInformationByHandle(h1.handle, &info1))
    {
        GMX_THROW(FileIOError("Path::isEquivalent: GetFileInformationByHandle failed"));
    }

    if (!GetFileInformationByHandle(h2.handle, &info2))
    {
        GMX_THROW(FileIOError("Path::isEquivalent: GetFileInformationByHandle failed"));
    }

    // In theory, volume serial numbers are sufficient to distinguish between
    // devices, but in practice VSN's are sometimes duplicated, so last write
    // time and file size are also checked.
    return
        info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
        && info1.nFileIndexHigh == info2.nFileIndexHigh
        && info1.nFileIndexLow == info2.nFileIndexLow
        && info1.nFileSizeHigh == info2.nFileSizeHigh
        && info1.nFileSizeLow == info2.nFileSizeLow
        && info1.ftLastWriteTime.dwLowDateTime
        == info2.ftLastWriteTime.dwLowDateTime
        && info1.ftLastWriteTime.dwHighDateTime
        == info2.ftLastWriteTime.dwHighDateTime;
#else
    struct stat s1, s2;
    int         e2 = stat(path2.c_str(), &s2);
    int         e1 = stat(path1.c_str(), &s1);

    if (e1 != 0 || e2 != 0)
    {
        // if one is invalid and the other isn't then they aren't equivalent,
        // but if both are invalid then it is an error.
        if (e1 != 0 && e2 != 0)
        {
            GMX_THROW_WITH_ERRNO(
                    FileIOError("Path::isEquivalent called with two invalid files"),
                    "stat", errno);
        }
        return false;
    }

    // both stats now known to be valid
    return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino
           // According to the POSIX stat specs, "The st_ino and st_dev fields
           // taken together uniquely identify the file within the system."
           // Just to be sure, size and mod time are also checked.
           && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime;
#endif
}
Example #19
0
std::string DataFileFinder::findFile(const DataFileOptions &options) const
{
    if (options.bCurrentDir_ && Path::exists(options.filename_))
    {
        return options.filename_;
    }
    if (impl_ != nullptr)
    {
        std::vector<std::string>::const_iterator i;
        for (i = impl_->searchPath_.begin(); i != impl_->searchPath_.end(); ++i)
        {
            // TODO: Deal with an empty search path entry more reasonably.
            std::string testPath = Path::join(*i, options.filename_);
            // TODO: Consider skipping directories.
            if (Path::exists(testPath))
            {
                return testPath;
            }
        }
    }
    const std::string &defaultPath = Impl::getDefaultPath();
    if (!defaultPath.empty())
    {
        std::string testPath = Path::join(defaultPath, options.filename_);
        if (Path::exists(testPath))
        {
            return testPath;
        }
    }
    if (options.bThrow_)
    {
        const char *const envName   = (impl_ != nullptr ? impl_->envName_ : nullptr);
        const bool        bEnvIsSet = (impl_ != nullptr ? impl_->bEnvIsSet_ : false);
        std::string       message(
                formatString("Library file '%s' not found", options.filename_));
        if (options.bCurrentDir_)
        {
            message.append(" in current dir nor");
        }
        if (bEnvIsSet)
        {
            message.append(formatString(" in your %s path nor", envName));
        }
        message.append(" in the default directories.\nThe following paths were searched:");
        if (options.bCurrentDir_)
        {
            message.append("\n  ");
            message.append(Path::getWorkingDirectory());
            message.append(" (current dir)");
        }
        if (impl_ != nullptr)
        {
            std::vector<std::string>::const_iterator i;
            for (i = impl_->searchPath_.begin(); i != impl_->searchPath_.end(); ++i)
            {
                message.append("\n  ");
                message.append(*i);
            }
        }
        if (!defaultPath.empty())
        {
            message.append("\n  ");
            message.append(defaultPath);
            message.append(" (default)");
        }
        if (!bEnvIsSet && envName != nullptr)
        {
            message.append(
                    formatString("\nYou can set additional directories to search "
                                 "with the %s path variable.", envName));
        }
        GMX_THROW(FileIOError(message));
    }
    return std::string();
}