Go to the documentation of this file.
16 #include "llvm/Config/config.h"
17 #include "llvm/Config/llvm-config.h"
26 #if !defined(_MSC_VER) && !defined(__MINGW32__)
45 return LLVM_WINDOWS_PREFER_FORWARD_SLASH ? Style::windows_slash
46 : Style::windows_backslash;
49 inline const char *separators(
Style style) {
55 inline char preferred_separator(
Style style) {
56 if (real_style(style) == Style::windows)
73 if (path.
size() >= 2 &&
74 std::isalpha(
static_cast<unsigned char>(path[0])) && path[1] ==
':')
99 return str.
size() - 1;
140 size_t end_pos = filename_pos(path, style);
142 bool filename_was_sep =
146 size_t root_dir_pos = root_dir_start(path, style);
147 while (end_pos > 0 &&
152 if (end_pos == root_dir_pos && !filename_was_sep) {
155 return root_dir_pos + 1;
169 static std::error_code
180 for (
int Retries = 128; Retries > 0; --Retries) {
195 return std::error_code();
201 return std::error_code();
214 return std::error_code();
229 i.Component = find_first_component(path, style);
238 i.Position = path.
size();
243 assert(Position < Path.size() &&
"Tried to increment past end!");
246 Position += Component.size();
249 if (Position == Path.size()) {
256 bool was_net = Component.size() > 2 &&
is_separator(Component[0],
S) &&
257 Component[1] == Component[0] && !
is_separator(Component[2],
S);
265 Component = Path.substr(Position, 1);
270 while (Position != Path.size() &&
is_separator(Path[Position],
S)) {
275 if (Position == Path.size() && Component !=
"/") {
283 size_t end_pos = Path.find_first_of(separators(
S), Position);
284 Component = Path.slice(Position, end_pos);
290 return Path.begin() ==
RHS.Path.begin() && Position ==
RHS.Position;
294 return Position -
RHS.Position;
300 I.Position = Path.size();
309 I.Component = Path.substr(0, 0);
315 size_t root_dir_pos = root_dir_start(Path,
S);
318 size_t end_pos = Position;
319 while (end_pos > 0 && (end_pos - 1) != root_dir_pos &&
324 if (Position == Path.size() && !Path.empty() &&
333 size_t start_pos = filename_pos(Path.substr(0, end_pos),
S);
334 Component = Path.slice(start_pos, end_pos);
335 Position = start_pos;
340 return Path.begin() ==
RHS.Path.begin() && Component ==
RHS.Component &&
341 Position ==
RHS.Position;
345 return Position -
RHS.Position;
352 b->size() > 2 &&
is_separator((*
b)[0], style) && (*b)[1] == (*b)[0];
355 if (has_net || has_drive) {
358 return path.
substr(0,
b->size() + pos->size());
377 b->size() > 2 &&
is_separator((*
b)[0], style) && (*b)[1] == (*b)[0];
380 if (has_net || has_drive) {
394 b->size() > 2 &&
is_separator((*
b)[0], style) && (*b)[1] == (*b)[0];
397 if ((has_net || has_drive) &&
426 if (!
a.isTriviallyEmpty()) components.push_back(
a.toStringRef(a_storage));
427 if (!
b.isTriviallyEmpty()) components.push_back(
b.toStringRef(b_storage));
428 if (!
c.isTriviallyEmpty()) components.push_back(
c.toStringRef(c_storage));
429 if (!
d.isTriviallyEmpty()) components.push_back(
d.toStringRef(d_storage));
431 for (
auto &component : components) {
433 !path.empty() &&
is_separator(path[path.size() - 1], style);
436 size_t loc = component.find_first_not_of(separators(style));
444 bool component_has_sep =
445 !component.empty() &&
is_separator(component[0], style);
446 if (!component_has_sep &&
449 path.push_back(preferred_separator(style));
452 path.
append(component.begin(), component.end());
468 size_t end_pos = parent_path_end(path, style);
471 return path.
substr(0, end_pos);
475 size_t end_pos = parent_path_end(
StringRef(path.begin(), path.size()), style);
487 size_t pos =
p.find_last_of(
'.');
492 if (ext.
size() > 0 && ext[0] !=
'.')
503 if (Path.size() <
Prefix.size())
505 for (
size_t I = 0,
E =
Prefix.size();
I !=
E; ++
I) {
508 if (SepPath != SepPrefix)
510 if (!SepPath && toLower(Path[
I]) != toLower(
Prefix[
I]))
515 return Path.startswith(
Prefix);
523 StringRef OrigPath(Path.begin(), Path.size());
528 if (OldPrefix.
size() == NewPrefix.
size()) {
535 (
Twine(NewPrefix) + RelPath).toVector(NewPath);
543 "path and result are not allowed to overlap!");
554 for (
char &Ch : Path)
556 Ch = preferred_separator(style);
557 if (Path[0] ==
'~' && (Path.size() == 1 ||
is_separator(Path[1], style))) {
560 PathHome.
append(Path.begin() + 1, Path.end());
570 return std::string(path);
572 std::string
s = path.
str();
584 if ((fname.
size() == 1 && fname ==
".") ||
585 (fname.
size() == 2 && fname ==
".."))
587 return fname.
substr(0, pos);
595 if ((fname.
size() == 1 && fname ==
".") ||
596 (fname.
size() == 2 && fname ==
".."))
605 return value ==
'\\';
610 if (real_style(style) == Style::windows)
678 return rootDir && rootName;
692 if (
p.size() >= 2 && (
p[0] &&
p[1] ==
':'))
705 while (Path.size() > 2 && Path[0] ==
'.' &&
is_separator(Path[1], style)) {
706 Path = Path.substr(2);
708 Path = Path.substr(1);
717 style = real_style(style);
718 StringRef remaining(the_path.data(), the_path.size());
719 bool needs_change =
false;
724 bool absolute = !root.
empty();
730 while (!remaining.
empty()) {
731 size_t next_slash = remaining.
find_first_of(separators(style));
733 next_slash = remaining.
size();
738 if (!remaining.
empty()) {
739 needs_change |= remaining.
front() != preferred_separator(style);
743 needs_change |= remaining.
empty();
747 if (component.
empty() || component ==
".") {
749 }
else if (remove_dot_dot && component ==
"..") {
753 if (!components.empty() && components.back() !=
"..") {
754 components.pop_back();
755 }
else if (!absolute) {
756 components.push_back(component);
759 components.push_back(component);
768 if (!components.empty()) {
769 buffer += components[0];
771 buffer += preferred_separator(style);
775 the_path.
swap(buffer);
788 Result =
Status.getUniqueID();
789 return std::error_code();
795 Model.toVector(ModelStorage);
803 ModelStorage.
swap(TDir);
807 ResultPath = ModelStorage;
808 ResultPath.push_back(0);
809 ResultPath.pop_back();
812 for (
unsigned i = 0,
e = ModelStorage.size();
i !=
e; ++
i) {
813 if (ModelStorage[
i] ==
'%')
837 static std::error_code
844 "Model must be a simple filename.");
850 static std::error_code
854 const char *Middle = Suffix.
empty() ?
"-%%%%%%" :
"-%%%%%%.";
915 current_directory.
toVector(current_dir);
918 if (!rootName && !rootDirectory) {
922 path.
swap(current_dir);
926 if (!rootName && rootDirectory) {
931 path.
swap(curDirRootName);
935 if (rootName && !rootDirectory) {
942 path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
988 const size_t BufSize = 4096;
989 char *Buf =
new char[BufSize];
990 int BytesRead = 0, BytesWritten = 0;
992 BytesRead =
read(ReadFD, Buf, BufSize);
996 BytesWritten =
write(WriteFD, Buf, BytesRead);
997 if (BytesWritten < 0)
999 BytesRead -= BytesWritten;
1001 if (BytesWritten < 0)
1006 if (BytesRead < 0 || BytesWritten < 0)
1007 return std::error_code(errno, std::generic_category());
1008 return std::error_code();
1013 int ReadFD, WriteFD;
1016 if (std::error_code EC =
1046 constexpr
size_t BufSize = 4096;
1047 std::vector<uint8_t> Buf(BufSize);
1050 BytesRead =
read(FD, Buf.data(), BufSize);
1057 return std::error_code(errno, std::generic_category());
1078 return s.type() != file_type::status_error;
1083 if (
status(Path, st, Follow))
1084 return file_type::status_error;
1089 return status.type() == file_type::directory_file;
1094 if (std::error_code ec =
status(path, st))
1097 return std::error_code();
1101 return status.type() == file_type::regular_file;
1106 if (std::error_code ec =
status(path, st))
1109 return std::error_code();
1113 return status.type() == file_type::symlink_file;
1118 if (std::error_code ec =
status(path, st,
false))
1121 return std::error_code();
1132 if (std::error_code EC =
status(Path, FileStatus))
1135 return std::error_code();
1142 this->Path = std::string(PathStr.
str());
1152 return Status.permissions();
1156 assert(Mapping &&
"Mapping failed but used anyway!");
1160 char *mapped_file_region::data()
const {
1161 assert(Mapping &&
"Mapping failed but used anyway!");
1162 return reinterpret_cast<char *
>(Mapping);
1165 const char *mapped_file_region::const_data()
const {
1166 assert(Mapping &&
"Mapping failed but used anyway!");
1167 return reinterpret_cast<const char *
>(Mapping);
1171 ssize_t ChunkSize) {
1173 size_t Size = Buffer.size();
1183 if (*ReadBytes == 0)
1194 #if defined(LLVM_ON_UNIX)
1213 RemoveOnClose =
Other.RemoveOnClose;
1214 Other.RemoveOnClose =
false;
1223 if (FD != -1 && close(FD) == -1) {
1224 std::error_code EC = std::error_code(errno, std::generic_category());
1232 bool Remove = RemoveOnClose;
1237 std::error_code RemoveEC;
1238 if (Remove && !TmpName.empty()) {
1255 auto H =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
1256 std::error_code RenameEC =
1257 RemoveOnClose ? std::error_code() : setDeleteDisposition(
H,
false);
1258 bool ShouldDelete =
false;
1260 RenameEC = rename_handle(
H,
Name);
1263 std::error_code(ERROR_NOT_SAME_DEVICE, std::system_category())) {
1265 ShouldDelete =
true;
1271 ShouldDelete =
true;
1274 setDeleteDisposition(
H,
true);
1293 if (close(FD) == -1) {
1294 std::error_code EC(errno, std::generic_category());
1307 auto H =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
1308 if (std::error_code EC = setDeleteDisposition(
H,
false))
1315 if (close(FD) == -1) {
1316 std::error_code EC(errno, std::generic_category());
1328 if (std::error_code EC =
1334 auto H =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
1335 bool SetSignalHandler =
false;
1336 if (std::error_code EC = setDeleteDisposition(
H,
true)) {
1337 Ret.RemoveOnClose =
true;
1338 SetSignalHandler =
true;
1341 bool SetSignalHandler =
true;
void createUniquePath(const Twine &Model, SmallVectorImpl< char > &ResultPath, bool MakeAbsolute)
Create a potentially unique file name but does not create it.
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp=CD_CreateAlways, OpenFlags Flags=OF_None, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
static bool starts_with(StringRef Path, StringRef Prefix, Style style=Style::native)
Represents the result of a call to directory_iterator::status().
This is an optimization pass for GlobalISel generic memory operations.
bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
bool home_directory(SmallVectorImpl< char > &result)
Get the user's home directory.
StringRef extension(StringRef path, Style style=Style::native)
Get extension.
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
static std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, llvm::SmallVectorImpl< char > &ResultPath, FSEntity Type, sys::fs::OpenFlags Flags=sys::fs::OF_None)
StringRef getSingleStringRef() const
This returns the twine as a single StringRef.
reverse_iterator rbegin(StringRef path, Style style=Style::native)
Get reverse begin iterator over path.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
StringRef remove_leading_dotslash(StringRef path, Style style=Style::native)
Remove redundant leading "./" pieces and consecutive separators.
static constexpr size_t npos
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
static ErrorSuccess success()
Create a success value.
std::error_code getUniqueID(const Twine Path, UniqueID &Result)
std::error_code getPotentiallyUniqueTempFileName(const Twine &Prefix, StringRef Suffix, SmallVectorImpl< char > &ResultPath)
Get a unique temporary file name, not currently exisiting in the filesystem.
std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None, unsigned Mode=all_read|all_write)
Create a uniquely named file.
The instances of the Type class are immutable: once they are created, they are never changed.
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
OutputIt copy(R &&Range, OutputIt Out)
@ no_such_file_or_directory
std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
Tagged union holding either a T or a Error.
bool is_regular_file(const basic_file_status &status)
Does status represent a regular file?
static void replace(Module &M, GlobalVariable *Old, GlobalVariable *New)
void consumeError(Error Err)
Consume a Error without doing anything.
the resulting code requires compare and branches when and if * p
Expected< size_t > readNativeFile(file_t FileHandle, MutableArrayRef< char > Buf)
Reads Buf.size() bytes from FileHandle into Buf.
=0.0 ? 0.0 :(a > 0.0 ? 1.0 :-1.0) a
It looks like we only need to define PPCfmarto for these because according to these instructions perform RTO on fma s result
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
void truncate(size_type N)
Like resize, but requires that N is less than size().
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
LLVM_NODISCARD size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
LLVM_NODISCARD StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
bool has_extension(const Twine &path, Style style=Style::native)
Has extension?
static unsigned GetRandomNumber()
Get the result of a process wide random number generator.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
bool has_parent_path(const Twine &path, Style style=Style::native)
Has parent path?
(vector float) vec_cmpeq(*A, *B) C
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
StringRef root_path(StringRef path, Style style=Style::native)
Get root path.
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int b
LLVM_NODISCARD detail::scope_exit< typename std::decay< Callable >::type > make_scope_exit(Callable &&F)
bool has_stem(const Twine &path, Style style=Style::native)
Has stem?
std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
file_type get_file_type(const Twine &Path, bool Follow=true)
Does status represent a directory?
file_type
An enumeration for the file system's view of the type.
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int c
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp, OpenFlags Flags, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
Error readNativeFileToEOF(file_t FileHandle, SmallVectorImpl< char > &Buffer, ssize_t ChunkSize=DefaultReadChunkSize)
Reads from FileHandle until EOF, appending to Buffer in chunks of size ChunkSize.
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
constexpr bool is_style_posix(Style S)
Check if S uses POSIX path rules.
void append(StringRef RHS)
Append from a StringRef.
bool is_other(const basic_file_status &status)
Does this status represent something that exists but is not a directory or regular file?
Represents the result of a call to sys::fs::status().
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
bool isSingleStringRef() const
Return true if this twine can be dynamically accessed as a single StringRef value with getSingleStrin...
bool exists(const basic_file_status &status)
Does file exist?
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
std::error_code getPotentiallyUniqueFileName(const Twine &Model, SmallVectorImpl< char > &ResultPath)
Get a unique name, not currently exisiting in the filesystem.
StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
StringRef root_directory(StringRef path, Style style=Style::native)
Get root directory.
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
multiplies can be turned into SHL s
@ OF_Delete
The returned handle can be used for deleting the file.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
LLVM_NODISCARD char front() const
front - Get the first character in the string.
bool status_known(const basic_file_status &s)
Is status available?
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
bool is_symlink_file(const basic_file_status &status)
Does status represent a symlink file?
bool operator==(uint64_t V1, const APInt &V2)
void make_absolute(const Twine ¤t_directory, SmallVectorImpl< char > &path)
Make path an absolute path.
std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
@ CD_CreateAlways
CD_CreateAlways - When opening a file:
bool has_filename(const Twine &path, Style style=Style::native)
Has filename?
bool has_relative_path(const Twine &path, Style style=Style::native)
Has relative path?
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ErrorOr< perms > getPermissions(const Twine &Path)
Get file permissions.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
std::error_code rename(const Twine &from, const Twine &to)
Rename from to to.
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
StringRef root_name(StringRef path, Style style=Style::native)
Get root name.
void swap(SmallVectorImpl &RHS)
LLVM_NODISCARD StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
Lightweight error class with error context and mandatory checking.
bool has_root_name(const Twine &path, Style style=Style::native)
Has root name?
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl< char > &result)
Get the typical temporary directory for the system, e.g., "/var/tmp" or "C:/TEMP".
bool is_directory(const basic_file_status &status)
Does status represent a directory?
StringRef str() const
Explicit conversion to StringRef.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
bool has_root_path(const Twine &path, Style style=Style::native)
Has root path?
void DontRemoveFileOnSignal(StringRef Filename)
This function removes a file from the list of files to be removed on signal delivery.
Error takeError()
Take ownership of the stored error.
bool is_absolute_gnu(const Twine &path, Style style=Style::native)
Is path absolute using GNU rules?
bool is_separator(char value, Style style=Style::native)
Check whether the given char is a path separator on the host OS.
ErrorOr< MD5::MD5Result > md5_contents(int FD)
Compute an MD5 hash of a file's contents.
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
constexpr bool is_style_windows(Style S)
Check if S uses Windows path rules.
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
Represents either an error or a value T.
void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
reverse_iterator rend(StringRef path)
Get reverse end iterator over path.
@ operation_not_permitted
bool has_root_directory(const Twine &path, Style style=Style::native)
Has root directory?
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
@ CD_CreateNew
CD_CreateNew - When opening a file:
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, bool MakeAbsolute, FSEntity Type, sys::fs::OpenFlags Flags=sys::fs::OF_None, unsigned Mode=0)
MutableArrayRef< T > makeMutableArrayRef(T &OneElt)
Construct a MutableArrayRef from a single element.
Represents a temporary file.
BlockVerifier::State From
StringRef relative_path(StringRef path, Style style=Style::native)
Get relative path.
static std::error_code copy_file_internal(int ReadFD, int WriteFD)
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int int d
bool RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg=nullptr)
This function registers signal handlers to ensure that if a signal gets delivered that the named file...
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
StringRef stem(StringRef path, Style style=Style::native)
Get stem.
std::error_code openFileForRead(const Twine &Name, int &ResultFD, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
Optional< std::vector< StOtherPiece > > Other