Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
fmt
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
fmt
Commits
eaa89e23
Commit
eaa89e23
authored
Jun 09, 2014
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Put File, BufferedFile & ErrorCode in the fmt namespace.
parent
b692ab58
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
80 additions
and
60 deletions
+80
-60
CMakeLists.txt
CMakeLists.txt
+13
-12
posix.cc
posix.cc
+13
-24
posix.h
posix.h
+40
-21
test/format-test.cc
test/format-test.cc
+3
-0
test/gtest-extra-test.cc
test/gtest-extra-test.cc
+4
-0
test/gtest-extra.cc
test/gtest-extra.cc
+1
-1
test/gtest-extra.h
test/gtest-extra.h
+2
-2
test/posix-test.cc
test/posix-test.cc
+4
-0
No files found.
CMakeLists.txt
View file @
eaa89e23
...
...
@@ -46,7 +46,18 @@ if (FMT_SHARED)
set
(
shared SHARED
)
endif
()
add_library
(
format
${
shared
}
format.cc format.h
)
include
(
CheckSymbolExists
)
if
(
WIN32
)
check_symbol_exists
(
open io.h HAVE_OPEN
)
else
()
check_symbol_exists
(
open fcntl.h HAVE_OPEN
)
endif
()
if
(
HAVE_OPEN
)
add_definitions
(
-DFMT_USE_FILE_DESCRIPTORS=1
)
set
(
FMT_POSIX_SRC posix.cc posix.h
)
endif
()
add_library
(
format
${
shared
}
format.cc format.h
${
FMT_POSIX_SRC
}
)
if
(
CMAKE_COMPILER_IS_GNUCXX
)
set_target_properties
(
format PROPERTIES COMPILE_FLAGS
"-Wall -Wextra -pedantic"
)
...
...
@@ -55,7 +66,7 @@ if (CPP11_FLAG AND FMT_EXTRA_TESTS)
set_target_properties
(
format PROPERTIES COMPILE_FLAGS
${
CPP11_FLAG
}
)
# Test compilation with default flags.
file
(
GLOB src RELATIVE
${
CMAKE_CURRENT_SOURCE_DIR
}
test/*.cc test/*.h
)
add_library
(
testformat format.cc
${
src
}
)
add_library
(
testformat format.cc
${
FMT_POSIX_SRC
}
${
src
}
)
endif
()
add_subdirectory
(
doc
)
...
...
@@ -77,16 +88,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_definitions
(
-DGTEST_USE_OWN_TR1_TUPLE=1
)
endif
()
include
(
CheckSymbolExists
)
if
(
WIN32
)
check_symbol_exists
(
open io.h HAVE_OPEN
)
else
()
check_symbol_exists
(
open fcntl.h HAVE_OPEN
)
endif
()
if
(
HAVE_OPEN
)
add_definitions
(
-DFMT_USE_FILE_DESCRIPTORS=1
)
endif
()
enable_testing
()
include_directories
(
.
)
...
...
posix.cc
View file @
eaa89e23
...
...
@@ -27,7 +27,6 @@
#include "posix.h"
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
...
...
@@ -44,16 +43,6 @@
#endif // _WIN32
// Retries the expression while it evaluates to -1 and error equals to EINTR.
#ifndef _WIN32
# define FMT_RETRY(result, expression) \
do { \
result = (expression); \
} while (result == -1 && errno == EINTR)
#else
# define FMT_RETRY(result, expression) result = (expression)
#endif
namespace
{
#ifdef _WIN32
// On Windows the count argument to read and write is unsigned, so convert
...
...
@@ -66,12 +55,12 @@ inline std::size_t ConvertRWCount(std::size_t count) { return count; }
#endif
}
BufferedFile
::~
BufferedFile
()
FMT_NOEXCEPT
(
true
)
{
fmt
::
BufferedFile
::~
BufferedFile
()
FMT_NOEXCEPT
(
true
)
{
if
(
file_
&&
FMT_SYSTEM
(
fclose
(
file_
))
!=
0
)
fmt
::
ReportSystemError
(
errno
,
"cannot close file"
);
}
void
BufferedFile
::
close
()
{
void
fmt
::
BufferedFile
::
close
()
{
if
(
!
file_
)
return
;
int
result
=
FMT_SYSTEM
(
fclose
(
file_
));
...
...
@@ -80,14 +69,14 @@ void BufferedFile::close() {
fmt
::
ThrowSystemError
(
errno
,
"cannot close file"
);
}
int
BufferedFile
::
fileno
()
const
{
int
fmt
::
BufferedFile
::
fileno
()
const
{
int
fd
=
FMT_POSIX_CALL
(
fileno
(
file_
));
if
(
fd
==
-
1
)
fmt
::
ThrowSystemError
(
errno
,
"cannot get file descriptor"
);
return
fd
;
}
File
::
File
(
const
char
*
path
,
int
oflag
)
{
fmt
::
File
::
File
(
const
char
*
path
,
int
oflag
)
{
int
mode
=
S_IRUSR
|
S_IWUSR
;
#ifdef _WIN32
fd_
=
-
1
;
...
...
@@ -99,14 +88,14 @@ File::File(const char *path, int oflag) {
fmt
::
ThrowSystemError
(
errno
,
"cannot open file {}"
)
<<
path
;
}
File
::~
File
()
FMT_NOEXCEPT
(
true
)
{
fmt
::
File
::~
File
()
FMT_NOEXCEPT
(
true
)
{
// Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
if
(
fd_
!=
-
1
&&
FMT_POSIX_CALL
(
close
(
fd_
))
!=
0
)
fmt
::
ReportSystemError
(
errno
,
"cannot close file"
);
}
void
File
::
close
()
{
void
fmt
::
File
::
close
()
{
if
(
fd_
==
-
1
)
return
;
// Don't retry close in case of EINTR!
...
...
@@ -117,7 +106,7 @@ void File::close() {
fmt
::
ThrowSystemError
(
errno
,
"cannot close file"
);
}
std
::
streamsize
File
::
read
(
void
*
buffer
,
std
::
size_t
count
)
{
std
::
streamsize
fmt
::
File
::
read
(
void
*
buffer
,
std
::
size_t
count
)
{
std
::
streamsize
result
=
0
;
FMT_RETRY
(
result
,
FMT_POSIX_CALL
(
read
(
fd_
,
buffer
,
ConvertRWCount
(
count
))));
if
(
result
==
-
1
)
...
...
@@ -125,7 +114,7 @@ std::streamsize File::read(void *buffer, std::size_t count) {
return
result
;
}
std
::
streamsize
File
::
write
(
const
void
*
buffer
,
std
::
size_t
count
)
{
std
::
streamsize
fmt
::
File
::
write
(
const
void
*
buffer
,
std
::
size_t
count
)
{
std
::
streamsize
result
=
0
;
FMT_RETRY
(
result
,
FMT_POSIX_CALL
(
write
(
fd_
,
buffer
,
ConvertRWCount
(
count
))));
if
(
result
==
-
1
)
...
...
@@ -133,7 +122,7 @@ std::streamsize File::write(const void *buffer, std::size_t count) {
return
result
;
}
File
File
::
dup
(
int
fd
)
{
fmt
::
File
fmt
::
File
::
dup
(
int
fd
)
{
// Don't retry as dup doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
int
new_fd
=
FMT_POSIX_CALL
(
dup
(
fd
));
...
...
@@ -142,7 +131,7 @@ File File::dup(int fd) {
return
File
(
new_fd
);
}
void
File
::
dup2
(
int
fd
)
{
void
fmt
::
File
::
dup2
(
int
fd
)
{
int
result
=
0
;
FMT_RETRY
(
result
,
FMT_POSIX_CALL
(
dup2
(
fd_
,
fd
)));
if
(
result
==
-
1
)
{
...
...
@@ -151,14 +140,14 @@ void File::dup2(int fd) {
}
}
void
File
::
dup2
(
int
fd
,
ErrorCode
&
ec
)
FMT_NOEXCEPT
(
true
)
{
void
fmt
::
File
::
dup2
(
int
fd
,
ErrorCode
&
ec
)
FMT_NOEXCEPT
(
true
)
{
int
result
=
0
;
FMT_RETRY
(
result
,
FMT_POSIX_CALL
(
dup2
(
fd_
,
fd
)));
if
(
result
==
-
1
)
ec
=
ErrorCode
(
errno
);
}
void
File
::
pipe
(
File
&
read_end
,
File
&
write_end
)
{
void
fmt
::
File
::
pipe
(
File
&
read_end
,
File
&
write_end
)
{
// Close the descriptors first to make sure that assignments don't throw
// and there are no leaks.
read_end
.
close
();
...
...
@@ -181,7 +170,7 @@ void File::pipe(File &read_end, File &write_end) {
write_end
=
File
(
fds
[
1
]);
}
BufferedFile
File
::
fdopen
(
const
char
*
mode
)
{
fmt
::
BufferedFile
fmt
::
File
::
fdopen
(
const
char
*
mode
)
{
// Don't retry as fdopen doesn't return EINTR.
FILE
*
f
=
FMT_POSIX_CALL
(
fdopen
(
fd_
,
mode
));
if
(
!
f
)
{
...
...
posix.h
View file @
eaa89e23
...
...
@@ -28,12 +28,15 @@
#ifndef FMT_POSIX_H
#define FMT_POSIX_H
#include <
stdi
o.h>
#include <
errn
o.h>
#include <fcntl.h>
#include <stdio.h>
#include <cstddef>
#include <ios>
#include "format.h"
#ifndef FMT_POSIX
# ifdef _WIN32
// Fix warnings about deprecated symbols.
...
...
@@ -56,29 +59,41 @@
# endif
#endif
// Retries the expression while it evaluates to -1 and error equals to EINTR.
#ifndef _WIN32
# define FMT_RETRY(result, expression) \
do { \
result = (expression); \
} while (result == -1 && errno == EINTR)
#else
# define FMT_RETRY(result, expression) result = (expression)
#endif
namespace
fmt
{
// An error code.
class
ErrorCode
{
private:
private:
int
value_
;
public:
explicit
ErrorCode
(
int
value
=
0
)
FMT_NOEXCEPT
(
true
)
:
value_
(
value
)
{}
public:
explicit
ErrorCode
(
int
value
=
0
)
FMT_NOEXCEPT
(
true
)
:
value_
(
value
)
{
}
int
get
()
const
FMT_NOEXCEPT
(
true
)
{
return
value_
;
}
};
// A buffered file.
class
BufferedFile
{
private:
private:
FILE
*
file_
;
friend
class
File
;
explicit
BufferedFile
(
FILE
*
f
)
:
file_
(
f
)
{}
explicit
BufferedFile
(
FILE
*
f
)
:
file_
(
f
)
{
}
public:
public:
// Constructs a BufferedFile object which doesn't represent any file.
BufferedFile
()
FMT_NOEXCEPT
(
true
)
:
file_
(
0
)
{}
BufferedFile
()
FMT_NOEXCEPT
(
true
)
:
file_
(
0
)
{
}
// Destroys the object closing the file it represents if any.
~
BufferedFile
()
FMT_NOEXCEPT
(
true
);
...
...
@@ -87,16 +102,16 @@ class BufferedFile {
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
private:
private:
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
struct
Proxy
{
FILE
*
file
;
};
public:
public:
// A "move constructor" for moving from a temporary.
BufferedFile
(
Proxy
p
)
FMT_NOEXCEPT
(
true
)
:
file_
(
p
.
file
)
{}
BufferedFile
(
Proxy
p
)
FMT_NOEXCEPT
(
true
)
:
file_
(
p
.
file
)
{
}
// A "move constructor" for for moving from an lvalue.
BufferedFile
(
BufferedFile
&
f
)
FMT_NOEXCEPT
(
true
)
:
file_
(
f
.
file_
)
{
...
...
@@ -125,6 +140,7 @@ class BufferedFile {
file_
=
0
;
return
p
;
}
#else
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
BufferedFile
);
...
...
@@ -158,22 +174,22 @@ class BufferedFile {
// than an exception. You can get standard behavior by overriding the
// invalid parameter handler with _set_invalid_parameter_handler.
class
File
{
private:
private:
int
fd_
;
// File descriptor.
// Constructs a File object with a given descriptor.
explicit
File
(
int
fd
)
:
fd_
(
fd
)
{}
explicit
File
(
int
fd
)
:
fd_
(
fd
)
{
}
public:
public:
// Possible values for the oflag argument to the constructor.
enum
{
RDONLY
=
FMT_POSIX
(
O_RDONLY
),
// Open for reading only.
WRONLY
=
FMT_POSIX
(
O_WRONLY
),
// Open for writing only.
RDWR
=
FMT_POSIX
(
O_RDWR
)
// Open for reading and writing.
RDWR
=
FMT_POSIX
(
O_RDWR
)
// Open for reading and writing.
};
// Constructs a File object which doesn't represent any file.
File
()
FMT_NOEXCEPT
(
true
)
:
fd_
(
-
1
)
{}
File
()
FMT_NOEXCEPT
(
true
)
:
fd_
(
-
1
)
{
}
// Opens a file and constructs a File object representing this file.
File
(
const
char
*
path
,
int
oflag
);
...
...
@@ -182,16 +198,16 @@ class File {
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
private:
private:
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
struct
Proxy
{
int
fd
;
};
public:
public:
// A "move constructor" for moving from a temporary.
File
(
Proxy
p
)
FMT_NOEXCEPT
(
true
)
:
fd_
(
p
.
fd
)
{}
File
(
Proxy
p
)
FMT_NOEXCEPT
(
true
)
:
fd_
(
p
.
fd
)
{
}
// A "move constructor" for for moving from an lvalue.
File
(
File
&
other
)
FMT_NOEXCEPT
(
true
)
:
fd_
(
other
.
fd_
)
{
...
...
@@ -220,6 +236,7 @@ class File {
fd_
=
-
1
;
return
p
;
}
#else
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
File
);
...
...
@@ -273,11 +290,13 @@ class File {
BufferedFile
fdopen
(
const
char
*
mode
);
};
}
#if !FMT_USE_RVALUE_REFERENCES
namespace
std
{
// For compatibility with C++98.
inline
BufferedFile
&
move
(
BufferedFile
&
f
)
{
return
f
;
}
inline
File
&
move
(
File
&
f
)
{
return
f
;
}
inline
fmt
::
BufferedFile
&
move
(
fmt
::
BufferedFile
&
f
)
{
return
f
;
}
inline
fmt
::
File
&
move
(
fmt
::
File
&
f
)
{
return
f
;
}
}
#endif
...
...
test/format-test.cc
View file @
eaa89e23
...
...
@@ -1466,6 +1466,9 @@ TEST(FormatterTest, OutputNotWrittenOnError) {
#if FMT_USE_FILE_DESCRIPTORS
using
fmt
::
BufferedFile
;
using
fmt
::
File
;
TEST
(
FormatterTest
,
FileSink
)
{
File
read_end
,
write_end
;
File
::
pipe
(
read_end
,
write_end
);
...
...
test/gtest-extra-test.cc
View file @
eaa89e23
...
...
@@ -356,6 +356,10 @@ TEST(UtilTest, FormatSystemErrorMessage) {
#if FMT_USE_FILE_DESCRIPTORS
using
fmt
::
BufferedFile
;
using
fmt
::
ErrorCode
;
using
fmt
::
File
;
// Checks if the file is open by reading one character from it.
bool
IsOpen
(
int
fd
)
{
char
buffer
;
...
...
test/gtest-extra.cc
View file @
eaa89e23
...
...
@@ -29,7 +29,7 @@
#if FMT_USE_FILE_DESCRIPTORS
#include "posix.cc"
using
fmt
::
File
;
void
OutputRedirect
::
Flush
()
{
#if EOF != -1
...
...
test/gtest-extra.h
View file @
eaa89e23
...
...
@@ -99,8 +99,8 @@ std::string FormatSystemErrorMessage(int error_code, fmt::StringRef message);
class
OutputRedirect
{
private:
FILE
*
file_
;
File
original_
;
// Original file passed to redirector.
File
read_end_
;
// Read end of the pipe where the output is redirected.
fmt
::
File
original_
;
// Original file passed to redirector.
fmt
::
File
read_end_
;
// Read end of the pipe where the output is redirected.
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
OutputRedirect
);
...
...
test/posix-test.cc
View file @
eaa89e23
...
...
@@ -37,6 +37,10 @@
#include "gtest-extra.h"
using
fmt
::
BufferedFile
;
using
fmt
::
ErrorCode
;
using
fmt
::
File
;
namespace
{
int
open_count
;
int
close_count
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment