Program Listing for File FileUtility.h#
↰ Return to documentation for file (src/util/StringUtility/FileUtility.h)
#ifndef ROSE_FileUtility_H
#define ROSE_FileUtility_H
#include "commandline_processing.h"
namespace Rose {
// [Robb P Matzke 2016-06-16]: These file utilities were all originally part of StringUtility. I'm leaving them here for now
// just so I don't need to make so many changes to projects that use these, but you should expect these to be moved sometime in
// the future.
namespace StringUtility {
// This part of the StringUtility API deals with file names and should be moved to some other name space. In particular, it
// provides no definitions for "path", "filename", "extension", etc. and many of these functions won't work properly on a
// non-POSIX system. Therefore, consider using Rose::FileSystem, which is mostly a thin wrapper around std::filesystem. The
// std::filesystem documentation has good definitions for what the various terms should mean and works on non-POSIX file
// systems.
enum OSType {
OS_TYPE_UNKNOWN,
OS_TYPE_LINUX,
OS_TYPE_OSX,
OS_TYPE_WINDOWS,
OS_TPYE_WINDOWSXP
};
struct StringWithLineNumber {
std::string str; // DQ (1/23/2010): this name is difficult to trace within the code.
std::string filename; // Empty string means generated code
unsigned int line;
StringWithLineNumber(const std::string& str, const std::string& filename, unsigned int line)
: str(str), filename(filename), line(line) {}
ROSE_UTIL_API std::string toString() const;
};
typedef std::vector<StringWithLineNumber> FileWithLineNumbers;
ROSE_UTIL_API OSType getOSType();
ROSE_UTIL_API void writeFile(const std::string& outputString, const std::string& fileNameString,
const std::string& directoryName);
ROSE_UTIL_API std::string readFile(const std::string& fileName);
ROSE_UTIL_API FileWithLineNumbers readFileWithPos(const std::string& fileName);
ROSE_UTIL_API void homeDir(std::string& dir);
ROSE_UTIL_API std::string stripPathFromFileName(const std::string &fileNameWithPath);
ROSE_UTIL_API std::string getPathFromFileName(const std::string &fileNameWithPath);
ROSE_UTIL_API std::string stripFileSuffixFromFileName(const std::string & fileNameWithSuffix);
ROSE_UTIL_API std::string getAbsolutePathFromRelativePath(const std::string &relativePath, bool printErrorIfAny = false);
ROSE_UTIL_API std::string fileNameSuffix(const std::string &fileName);
// [Robb Matzke 2016-05-06]: I am deprecating "findfile" because:
// 1. It appears to not be used anywhere in ROSE, projects, tests, or documentation.
// 2. The name is spelled wrong (should be "findFile")
// 3. File operations should not be in StringUtility since they have nothing to do with string manipulation
// 4. Rose::FileSystem::findNames does something similar.
//ROSE_UTIL_API std::list<std::string> findfile(std::string patternString, std::string pathString)
//SAWYER_DEPRECATED("use Rose::FileSystem functions instead"); // ROSE_DEPRECATED is not defined here
/* File name location.
*
* Files can be classified as being in one of three locations: We don't know if it's user or system It is a user (application)
* file It is a system library This file does not exist */
enum FileNameLocation {
FILENAME_LOCATION_UNKNOWN,
FILENAME_LOCATION_USER,
FILENAME_LOCATION_LIBRARY,
FILENAME_LOCATION_NOT_EXIST
};
static const std::string FILENAME_LIBRARY_UNKNOWN = "Unknown";
static const std::string FILENAME_LIBRARY_USER = "User";
static const std::string FILENAME_LIBRARY_C = "C";
static const std::string FILENAME_LIBRARY_STDCXX = "C++";
static const std::string FILENAME_LIBRARY_STL = "STL";
static const std::string FILENAME_LIBRARY_LINUX = "Linux";
static const std::string FILENAME_LIBRARY_GCC = "GCC";
static const std::string FILENAME_LIBRARY_BOOST = "Boost";
static const std::string FILENAME_LIBRARY_ROSE = "Rose";
// CH (2/16/2010): Use this typedef to avoid following changes
typedef std::string FileNameLibrary;
/* This is the return type of classifyFileName, which provides all the details it infers */
class FileNameClassification {
private:
FileNameLocation location;
// CH (2/12/2010): Change 'library' type from enum to string to let user set it
FileNameLibrary library;
int distance;
public:
FileNameClassification(FileNameLocation loc, const FileNameLibrary& lib, int dist)
: location(loc), library(lib), distance(dist) {}
FileNameClassification()
: location(FILENAME_LOCATION_UNKNOWN), library("Unknown"), distance(0) {}
/* Return the FileNameLocation which is described above with the definition of the enum */
FileNameLocation getLocation() const {
return location;
}
/* Return the FileNameLibrary which is described above with the definition of the enum */
FileNameLibrary getLibrary() const {
return library;
}
/* Return the "distance" of the filename from the appPath that was supplied during the call. The distance is defined as
* the number of cd's that only move up or down one directory that it would take to move from the directory of the filename
* to the directory that was given by appPath. This is intended as a heuristic to gage whether or not one believes that
* the filename is related to the source (appPath) directory. Examples:
*
* Between /a/b/c/file.h and /a/b/d/e/ the distance is 3 because one must cd ..; cd d; cd e; to get to appPath
*
* *EXCEPTION*: if the appPath is an ancestor of filename then the distance will be 0. The idea being that this filename
* is "in" the appPath somewhere and thus part of the application. */
int getDistanceFromSourceDirectory() const {
return distance;
}
bool isUserCode() const {
return location == FILENAME_LOCATION_USER;
}
bool isLibraryCode() const {
return location == FILENAME_LOCATION_LIBRARY;
}
/* Return a string name for the library indicated by getLibrary() */
std::string getLibraryName() const {
return library;
}
};
ROSE_UTIL_API FileNameClassification classifyFileName(const std::string& fileName, const std::string& appPath);
ROSE_UTIL_API FileNameClassification classifyFileName(const std::string& fileName, const std::string& appPath, OSType os);
ROSE_UTIL_API FileNameClassification classifyFileName(const std::string& fileName, const std::string& appPath,
const std::map<std::string, std::string>& libPathCollection);
ROSE_UTIL_API FileNameClassification classifyFileName(const std::string& fileName, const std::string& appPath,
const std::map<std::string, std::string>& libPathCollection,
OSType os);
ROSE_UTIL_API const std::string stripDotsFromHeaderFileName(const std::string& name);
ROSE_UTIL_API int directoryDistance(const std::string& left, const std::string& right);
ROSE_UTIL_API std::vector<std::string> readWordsInFile(std::string filename);
// popen_wrapper is defined in sage_support.cpp
bool popen_wrapper(const std::string &command, std::vector<std::string> &result);
inline std::ostream& operator<<(std::ostream& os, const StringWithLineNumber& s) {
os << s.toString();
return os;
}
ROSE_UTIL_API std::string toString(const FileWithLineNumbers& strings, const std::string& filename = "<unknown>", int line = 1);
inline FileWithLineNumbers& operator+=(FileWithLineNumbers& a, const FileWithLineNumbers& b) {
a.insert(a.end(), b.begin(), b.end());
return a;
}
inline FileWithLineNumbers operator+(const FileWithLineNumbers& a, const FileWithLineNumbers& b) {
FileWithLineNumbers f = a;
f += b;
return f;
}
inline FileWithLineNumbers& operator<<(FileWithLineNumbers& f, const std::string& str) {
if (!f.empty() && f.back().filename == "") {
f.back().str += str;
} else {
f.push_back(StringWithLineNumber(str, "", 1));
}
return f;
}
inline FileWithLineNumbers& operator<<(FileWithLineNumbers& f, const char* str) {
f << std::string(str);
return f;
}
ROSE_UTIL_API std::string copyEdit(const std::string& inputString, const std::string & oldToken, const std::string & newToken);
ROSE_UTIL_API FileWithLineNumbers copyEdit(const FileWithLineNumbers& inputString, const std::string& oldToken,
const std::string& newToken);
ROSE_UTIL_API FileWithLineNumbers copyEdit(const FileWithLineNumbers& inputString, const std::string& oldToken,
const FileWithLineNumbers& newToken);
} // namespace
} // namespace
#endif