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
dcde089b
Commit
dcde089b
authored
Nov 15, 2019
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve POSIX API detection
parent
2145a7bd
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
67 additions
and
55 deletions
+67
-55
CMakeLists.txt
CMakeLists.txt
+2
-8
include/fmt/posix.h
include/fmt/posix.h
+9
-1
src/posix.cc
src/posix.cc
+5
-1
test/CMakeLists.txt
test/CMakeLists.txt
+1
-3
test/format-test.cc
test/format-test.cc
+1
-1
test/gtest-extra-test.cc
test/gtest-extra-test.cc
+28
-26
test/gtest-extra.cc
test/gtest-extra.cc
+1
-1
test/gtest-extra.h
test/gtest-extra.h
+5
-12
test/posix-mock-test.cc
test/posix-mock-test.cc
+4
-1
test/posix-test.cc
test/posix-test.cc
+4
-0
test/printf-test.cc
test/printf-test.cc
+1
-1
test/util.cc
test/util.cc
+6
-0
No files found.
CMakeLists.txt
View file @
dcde089b
...
@@ -135,10 +135,8 @@ endif ()
...
@@ -135,10 +135,8 @@ endif ()
include
(
CheckSymbolExists
)
include
(
CheckSymbolExists
)
if
(
WIN32
)
if
(
WIN32
)
check_symbol_exists
(
open io.h HAVE_OPEN
)
check_symbol_exists
(
_strtod_l
"
${
strtod_l_headers
}
"
HAVE_STRTOD_L
)
check_symbol_exists
(
_strtod_l
"
${
strtod_l_headers
}
"
HAVE_STRTOD_L
)
else
()
else
()
check_symbol_exists
(
open fcntl.h HAVE_OPEN
)
check_symbol_exists
(
strtod_l
"
${
strtod_l_headers
}
"
HAVE_STRTOD_L
)
check_symbol_exists
(
strtod_l
"
${
strtod_l_headers
}
"
HAVE_STRTOD_L
)
endif
()
endif
()
...
@@ -152,13 +150,9 @@ endfunction()
...
@@ -152,13 +150,9 @@ endfunction()
# Define the fmt library, its includes and the needed defines.
# Define the fmt library, its includes and the needed defines.
add_headers
(
FMT_HEADERS chrono.h color.h compile.h core.h format.h format-inl.h
add_headers
(
FMT_HEADERS chrono.h color.h compile.h core.h format.h format-inl.h
locale.h ostream.h printf.h ranges.h
locale.h ostream.h p
osix.h p
rintf.h ranges.h
safe-duration-cast.h
)
safe-duration-cast.h
)
set
(
FMT_SOURCES src/format.cc
)
set
(
FMT_SOURCES src/format.cc src/posix.cc
)
if
(
HAVE_OPEN
)
add_headers
(
FMT_HEADERS posix.h
)
set
(
FMT_SOURCES
${
FMT_SOURCES
}
src/posix.cc
)
endif
()
add_library
(
fmt
${
FMT_SOURCES
}
${
FMT_HEADERS
}
README.rst ChangeLog.rst
)
add_library
(
fmt
${
FMT_SOURCES
}
${
FMT_HEADERS
}
README.rst ChangeLog.rst
)
add_library
(
fmt::fmt ALIAS fmt
)
add_library
(
fmt::fmt ALIAS fmt
)
...
...
include/fmt/posix.h
View file @
dcde089b
...
@@ -14,7 +14,6 @@
...
@@ -14,7 +14,6 @@
#endif
#endif
#include <cerrno>
#include <cerrno>
#include <fcntl.h> // for O_RDONLY
#include <clocale> // for locale_t
#include <clocale> // for locale_t
#include <cstdio>
#include <cstdio>
#include <cstdlib> // for strtod_l
#include <cstdlib> // for strtod_l
...
@@ -27,6 +26,13 @@
...
@@ -27,6 +26,13 @@
#include "format.h"
#include "format.h"
#if FMT_HAS_INCLUDE("fcntl.h")
# include <fcntl.h> // for O_RDONLY
# define FMT_USE_FCNTL 1
#else
# define FMT_USE_FCNTL 0
#endif
#ifndef FMT_POSIX
#ifndef FMT_POSIX
# if defined(_WIN32) && !defined(__MINGW32__)
# if defined(_WIN32) && !defined(__MINGW32__)
// Fix warnings about deprecated symbols.
// Fix warnings about deprecated symbols.
...
@@ -176,6 +182,7 @@ class buffered_file {
...
@@ -176,6 +182,7 @@ class buffered_file {
}
}
};
};
#if FMT_USE_FCNTL
// A file. Closed file is represented by a file object with descriptor -1.
// A file. Closed file is represented by a file object with descriptor -1.
// Methods that are not declared with FMT_NOEXCEPT may throw
// Methods that are not declared with FMT_NOEXCEPT may throw
// fmt::system_error in case of failure. Note that some errors such as
// fmt::system_error in case of failure. Note that some errors such as
...
@@ -258,6 +265,7 @@ class file {
...
@@ -258,6 +265,7 @@ class file {
// Returns the memory page size.
// Returns the memory page size.
long
getpagesize
();
long
getpagesize
();
#endif // FMT_USE_FCNTL
#ifdef FMT_LOCALE
#ifdef FMT_LOCALE
// A "C" numeric locale.
// A "C" numeric locale.
...
...
src/posix.cc
View file @
dcde089b
...
@@ -13,6 +13,8 @@
...
@@ -13,6 +13,8 @@
#include "fmt/posix.h"
#include "fmt/posix.h"
#include <climits>
#include <climits>
#if FMT_USE_FCNTL
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/types.h>
...
@@ -39,8 +41,8 @@
...
@@ -39,8 +41,8 @@
# ifdef __MINGW32__
# ifdef __MINGW32__
# define _SH_DENYNO 0x40
# define _SH_DENYNO 0x40
# endif
# endif
#endif // _WIN32
#endif // _WIN32
#endif // FMT_USE_FCNTL
#ifdef fileno
#ifdef fileno
# undef fileno
# undef fileno
...
@@ -94,6 +96,7 @@ int buffered_file::fileno() const {
...
@@ -94,6 +96,7 @@ int buffered_file::fileno() const {
return
fd
;
return
fd
;
}
}
#if FMT_USE_FCNTL
file
::
file
(
cstring_view
path
,
int
oflag
)
{
file
::
file
(
cstring_view
path
,
int
oflag
)
{
int
mode
=
S_IRUSR
|
S_IWUSR
;
int
mode
=
S_IRUSR
|
S_IWUSR
;
#if defined(_WIN32) && !defined(__MINGW32__)
#if defined(_WIN32) && !defined(__MINGW32__)
...
@@ -230,4 +233,5 @@ long getpagesize() {
...
@@ -230,4 +233,5 @@ long getpagesize() {
return
size
;
return
size
;
#endif
#endif
}
}
#endif // FMT_USE_FCNTL
FMT_END_NAMESPACE
FMT_END_NAMESPACE
test/CMakeLists.txt
View file @
dcde089b
...
@@ -47,8 +47,6 @@ target_compile_definitions(gmock
...
@@ -47,8 +47,6 @@ target_compile_definitions(gmock
set
(
TEST_MAIN_SRC test-main.cc gtest-extra.cc gtest-extra.h util.cc
)
set
(
TEST_MAIN_SRC test-main.cc gtest-extra.cc gtest-extra.h util.cc
)
add_library
(
test-main STATIC
${
TEST_MAIN_SRC
}
)
add_library
(
test-main STATIC
${
TEST_MAIN_SRC
}
)
target_compile_definitions
(
test-main PUBLIC
FMT_USE_FILE_DESCRIPTORS=$<BOOL:
${
HAVE_OPEN
}
>
)
target_include_directories
(
test-main SYSTEM PUBLIC gtest gmock
)
target_include_directories
(
test-main SYSTEM PUBLIC gtest gmock
)
target_link_libraries
(
test-main gmock fmt
)
target_link_libraries
(
test-main gmock fmt
)
...
@@ -113,7 +111,7 @@ add_fmt_test(custom-formatter-test)
...
@@ -113,7 +111,7 @@ add_fmt_test(custom-formatter-test)
add_fmt_test
(
ranges-test
)
add_fmt_test
(
ranges-test
)
add_fmt_test
(
scan-test
)
add_fmt_test
(
scan-test
)
if
(
HAVE_OPEN AND
NOT MSVC_BUILD_STATIC
)
if
(
NOT MSVC_BUILD_STATIC
)
add_fmt_executable
(
posix-mock-test
add_fmt_executable
(
posix-mock-test
posix-mock-test.cc ../src/format.cc
${
TEST_MAIN_SRC
}
)
posix-mock-test.cc ../src/format.cc
${
TEST_MAIN_SRC
}
)
target_include_directories
(
target_include_directories
(
...
...
test/format-test.cc
View file @
dcde089b
...
@@ -1819,7 +1819,7 @@ TEST(FormatIntTest, FormatInt) {
...
@@ -1819,7 +1819,7 @@ TEST(FormatIntTest, FormatInt) {
}
}
TEST
(
FormatTest
,
Print
)
{
TEST
(
FormatTest
,
Print
)
{
#if FMT_USE_F
ILE_DESCRIPTORS
#if FMT_USE_F
CNTL
EXPECT_WRITE
(
stdout
,
fmt
::
print
(
"Don't {}!"
,
"panic"
),
"Don't panic!"
);
EXPECT_WRITE
(
stdout
,
fmt
::
print
(
"Don't {}!"
,
"panic"
),
"Don't panic!"
);
EXPECT_WRITE
(
stderr
,
fmt
::
print
(
stderr
,
"Don't {}!"
,
"panic"
),
EXPECT_WRITE
(
stderr
,
fmt
::
print
(
stderr
,
"Don't {}!"
,
"panic"
),
"Don't panic!"
);
"Don't panic!"
);
...
...
test/gtest-extra-test.cc
View file @
dcde089b
...
@@ -74,14 +74,6 @@ TEST_F(SingleEvaluationTest, FailedEXPECT_SYSTEM_ERROR) {
...
@@ -74,14 +74,6 @@ TEST_F(SingleEvaluationTest, FailedEXPECT_SYSTEM_ERROR) {
EXPECT_EQ
(
s_
+
1
,
p_
);
EXPECT_EQ
(
s_
+
1
,
p_
);
}
}
// Tests that when EXPECT_WRITE fails, it evaluates its message argument
// exactly once.
TEST_F
(
SingleEvaluationTest
,
FailedEXPECT_WRITE
)
{
EXPECT_NONFATAL_FAILURE
(
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"test"
),
p_
++
),
"01234"
);
EXPECT_EQ
(
s_
+
1
,
p_
);
}
// Tests that assertion arguments are evaluated exactly once.
// Tests that assertion arguments are evaluated exactly once.
TEST_F
(
SingleEvaluationTest
,
ExceptionTests
)
{
TEST_F
(
SingleEvaluationTest
,
ExceptionTests
)
{
// successful EXPECT_THROW_MSG
// successful EXPECT_THROW_MSG
...
@@ -163,6 +155,15 @@ TEST_F(SingleEvaluationTest, SystemErrorTests) {
...
@@ -163,6 +155,15 @@ TEST_F(SingleEvaluationTest, SystemErrorTests) {
EXPECT_EQ
(
4
,
b_
);
EXPECT_EQ
(
4
,
b_
);
}
}
#if FMT_USE_FCNTL
// Tests that when EXPECT_WRITE fails, it evaluates its message argument
// exactly once.
TEST_F
(
SingleEvaluationTest
,
FailedEXPECT_WRITE
)
{
EXPECT_NONFATAL_FAILURE
(
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"test"
),
p_
++
),
"01234"
);
EXPECT_EQ
(
s_
+
1
,
p_
);
}
// Tests that assertion arguments are evaluated exactly once.
// Tests that assertion arguments are evaluated exactly once.
TEST_F
(
SingleEvaluationTest
,
WriteTests
)
{
TEST_F
(
SingleEvaluationTest
,
WriteTests
)
{
// successful EXPECT_WRITE
// successful EXPECT_WRITE
...
@@ -187,6 +188,24 @@ TEST_F(SingleEvaluationTest, WriteTests) {
...
@@ -187,6 +188,24 @@ TEST_F(SingleEvaluationTest, WriteTests) {
EXPECT_EQ
(
2
,
b_
);
EXPECT_EQ
(
2
,
b_
);
}
}
// Tests EXPECT_WRITE.
TEST
(
ExpectTest
,
EXPECT_WRITE
)
{
EXPECT_WRITE
(
stdout
,
do_nothing
(),
""
);
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"test"
),
"test"
);
EXPECT_WRITE
(
stderr
,
std
::
fprintf
(
stderr
,
"test"
),
"test"
);
EXPECT_NONFATAL_FAILURE
(
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"that"
),
"this"
),
"Expected: this
\n
"
" Actual: that"
);
}
TEST
(
StreamingAssertionsTest
,
EXPECT_WRITE
)
{
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"test"
),
"test"
)
<<
"unexpected failure"
;
EXPECT_NONFATAL_FAILURE
(
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"test"
),
"other"
)
<<
"expected failure"
,
"expected failure"
);
}
#endif // FMT_USE_FCNTL
// Tests that the compiler will not complain about unreachable code in the
// Tests that the compiler will not complain about unreachable code in the
// EXPECT_THROW_MSG macro.
// EXPECT_THROW_MSG macro.
TEST
(
ExpectThrowTest
,
DoesNotGenerateUnreachableCodeWarning
)
{
TEST
(
ExpectThrowTest
,
DoesNotGenerateUnreachableCodeWarning
)
{
...
@@ -280,16 +299,6 @@ TEST(ExpectTest, EXPECT_SYSTEM_ERROR) {
...
@@ -280,16 +299,6 @@ TEST(ExpectTest, EXPECT_SYSTEM_ERROR) {
format_system_error
(
EDOM
,
"test"
)));
format_system_error
(
EDOM
,
"test"
)));
}
}
// Tests EXPECT_WRITE.
TEST
(
ExpectTest
,
EXPECT_WRITE
)
{
EXPECT_WRITE
(
stdout
,
do_nothing
(),
""
);
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"test"
),
"test"
);
EXPECT_WRITE
(
stderr
,
std
::
fprintf
(
stderr
,
"test"
),
"test"
);
EXPECT_NONFATAL_FAILURE
(
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"that"
),
"this"
),
"Expected: this
\n
"
" Actual: that"
);
}
TEST
(
StreamingAssertionsTest
,
EXPECT_THROW_MSG
)
{
TEST
(
StreamingAssertionsTest
,
EXPECT_THROW_MSG
)
{
EXPECT_THROW_MSG
(
throw_exception
(),
std
::
exception
,
"test"
)
EXPECT_THROW_MSG
(
throw_exception
(),
std
::
exception
,
"test"
)
<<
"unexpected failure"
;
<<
"unexpected failure"
;
...
@@ -308,20 +317,13 @@ TEST(StreamingAssertionsTest, EXPECT_SYSTEM_ERROR) {
...
@@ -308,20 +317,13 @@ TEST(StreamingAssertionsTest, EXPECT_SYSTEM_ERROR) {
"expected failure"
);
"expected failure"
);
}
}
TEST
(
StreamingAssertionsTest
,
EXPECT_WRITE
)
{
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"test"
),
"test"
)
<<
"unexpected failure"
;
EXPECT_NONFATAL_FAILURE
(
EXPECT_WRITE
(
stdout
,
std
::
printf
(
"test"
),
"other"
)
<<
"expected failure"
,
"expected failure"
);
}
TEST
(
UtilTest
,
FormatSystemError
)
{
TEST
(
UtilTest
,
FormatSystemError
)
{
fmt
::
memory_buffer
out
;
fmt
::
memory_buffer
out
;
fmt
::
format_system_error
(
out
,
EDOM
,
"test message"
);
fmt
::
format_system_error
(
out
,
EDOM
,
"test message"
);
EXPECT_EQ
(
to_string
(
out
),
format_system_error
(
EDOM
,
"test message"
));
EXPECT_EQ
(
to_string
(
out
),
format_system_error
(
EDOM
,
"test message"
));
}
}
#if FMT_USE_F
ILE_DESCRIPTORS
#if FMT_USE_F
CNTL
using
fmt
::
buffered_file
;
using
fmt
::
buffered_file
;
using
fmt
::
error_code
;
using
fmt
::
error_code
;
...
...
test/gtest-extra.cc
View file @
dcde089b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
#include "gtest-extra.h"
#include "gtest-extra.h"
#if FMT_USE_F
ILE_DESCRIPTORS
#if FMT_USE_F
CNTL
using
fmt
::
file
;
using
fmt
::
file
;
...
...
test/gtest-extra.h
View file @
dcde089b
...
@@ -10,16 +10,7 @@
...
@@ -10,16 +10,7 @@
#include <string>
#include <string>
#include "gmock.h"
#include "gmock.h"
#include "fmt/posix.h"
#include "fmt/core.h"
#ifndef FMT_USE_FILE_DESCRIPTORS
# define FMT_USE_FILE_DESCRIPTORS 0
#endif
#if FMT_USE_FILE_DESCRIPTORS
# include "fmt/posix.h"
#endif
#define FMT_TEST_THROW_(statement, expected_exception, expected_message, fail) \
#define FMT_TEST_THROW_(statement, expected_exception, expected_message, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
...
@@ -65,7 +56,7 @@ std::string format_system_error(int error_code, fmt::string_view message);
...
@@ -65,7 +56,7 @@ std::string format_system_error(int error_code, fmt::string_view message);
EXPECT_THROW_MSG(statement, fmt::system_error, \
EXPECT_THROW_MSG(statement, fmt::system_error, \
format_system_error(error_code, message))
format_system_error(error_code, message))
#if FMT_USE_F
ILE_DESCRIPTORS
#if FMT_USE_F
CNTL
// Captures file output by redirecting it to a pipe.
// Captures file output by redirecting it to a pipe.
// The output it can handle is limited by the pipe capacity.
// The output it can handle is limited by the pipe capacity.
...
@@ -151,7 +142,9 @@ std::string read(fmt::file& f, std::size_t count);
...
@@ -151,7 +142,9 @@ std::string read(fmt::file& f, std::size_t count);
# define EXPECT_READ(file, expected_content) \
# define EXPECT_READ(file, expected_content) \
EXPECT_EQ(expected_content, read(file, std::strlen(expected_content)))
EXPECT_EQ(expected_content, read(file, std::strlen(expected_content)))
#endif // FMT_USE_FILE_DESCRIPTORS
#else
# define EXPECT_WRITE(file, statement, expected_output) SUCCEED()
#endif // FMT_USE_FCNTL
template
<
typename
Mock
>
struct
ScopedMock
:
testing
::
StrictMock
<
Mock
>
{
template
<
typename
Mock
>
struct
ScopedMock
:
testing
::
StrictMock
<
Mock
>
{
ScopedMock
()
{
Mock
::
instance
=
this
;
}
ScopedMock
()
{
Mock
::
instance
=
this
;
}
...
...
test/posix-mock-test.cc
View file @
dcde089b
...
@@ -30,7 +30,6 @@
...
@@ -30,7 +30,6 @@
using
fmt
::
buffered_file
;
using
fmt
::
buffered_file
;
using
fmt
::
error_code
;
using
fmt
::
error_code
;
using
fmt
::
file
;
using
testing
::
_
;
using
testing
::
_
;
using
testing
::
Return
;
using
testing
::
Return
;
...
@@ -198,6 +197,9 @@ static void write_file(fmt::cstring_view filename, fmt::string_view content) {
...
@@ -198,6 +197,9 @@ static void write_file(fmt::cstring_view filename, fmt::string_view content) {
f
.
print
(
"{}"
,
content
);
f
.
print
(
"{}"
,
content
);
}
}
#if FMT_USE_FCNTL
using
fmt
::
file
;
TEST
(
UtilTest
,
GetPageSize
)
{
TEST
(
UtilTest
,
GetPageSize
)
{
#ifdef _WIN32
#ifdef _WIN32
SYSTEM_INFO
si
=
{};
SYSTEM_INFO
si
=
{};
...
@@ -429,6 +431,7 @@ TEST(BufferedFileTest, FilenoNoRetry) {
...
@@ -429,6 +431,7 @@ TEST(BufferedFileTest, FilenoNoRetry) {
EXPECT_EQ
(
2
,
fileno_count
);
EXPECT_EQ
(
2
,
fileno_count
);
fileno_count
=
0
;
fileno_count
=
0
;
}
}
#endif // FMT_USE_FCNTL
struct
TestMock
{
struct
TestMock
{
static
TestMock
*
instance
;
static
TestMock
*
instance
;
...
...
test/posix-test.cc
View file @
dcde089b
...
@@ -19,6 +19,9 @@
...
@@ -19,6 +19,9 @@
using
fmt
::
buffered_file
;
using
fmt
::
buffered_file
;
using
fmt
::
error_code
;
using
fmt
::
error_code
;
#if FMT_USE_FCNTL
using
fmt
::
file
;
using
fmt
::
file
;
// Checks if the file is open by reading one character from it.
// Checks if the file is open by reading one character from it.
...
@@ -376,3 +379,4 @@ TEST(LocaleTest, Strtod) {
...
@@ -376,3 +379,4 @@ TEST(LocaleTest, Strtod) {
EXPECT_EQ
(
start
+
3
,
ptr
);
EXPECT_EQ
(
start
+
3
,
ptr
);
}
}
#endif
#endif
#endif // FMT_USE_FCNTL
\ No newline at end of file
test/printf-test.cc
View file @
dcde089b
...
@@ -477,7 +477,7 @@ enum E { A = 42 };
...
@@ -477,7 +477,7 @@ enum E { A = 42 };
TEST
(
PrintfTest
,
Enum
)
{
EXPECT_PRINTF
(
"42"
,
"%d"
,
A
);
}
TEST
(
PrintfTest
,
Enum
)
{
EXPECT_PRINTF
(
"42"
,
"%d"
,
A
);
}
#if FMT_USE_F
ILE_DESCRIPTORS
#if FMT_USE_F
CNTL
TEST
(
PrintfTest
,
Examples
)
{
TEST
(
PrintfTest
,
Examples
)
{
const
char
*
weekday
=
"Thursday"
;
const
char
*
weekday
=
"Thursday"
;
const
char
*
month
=
"August"
;
const
char
*
month
=
"August"
;
...
...
test/util.cc
View file @
dcde089b
...
@@ -33,11 +33,17 @@ std::string get_system_error(int error_code) {
...
@@ -33,11 +33,17 @@ std::string get_system_error(int error_code) {
const
char
*
const
FILE_CONTENT
=
"Don't panic!"
;
const
char
*
const
FILE_CONTENT
=
"Don't panic!"
;
fmt
::
buffered_file
open_buffered_file
(
FILE
**
fp
)
{
fmt
::
buffered_file
open_buffered_file
(
FILE
**
fp
)
{
#if FMT_USE_FCNTL
fmt
::
file
read_end
,
write_end
;
fmt
::
file
read_end
,
write_end
;
fmt
::
file
::
pipe
(
read_end
,
write_end
);
fmt
::
file
::
pipe
(
read_end
,
write_end
);
write_end
.
write
(
FILE_CONTENT
,
std
::
strlen
(
FILE_CONTENT
));
write_end
.
write
(
FILE_CONTENT
,
std
::
strlen
(
FILE_CONTENT
));
write_end
.
close
();
write_end
.
close
();
fmt
::
buffered_file
f
=
read_end
.
fdopen
(
"r"
);
fmt
::
buffered_file
f
=
read_end
.
fdopen
(
"r"
);
if
(
fp
)
*
fp
=
f
.
get
();
if
(
fp
)
*
fp
=
f
.
get
();
#else
fmt
::
buffered_file
f
(
"test-file"
,
"w"
);
fputs
(
FILE_CONTENT
,
f
.
get
());
if
(
fp
)
*
fp
=
f
.
get
();
#endif
return
f
;
return
f
;
}
}
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