Skip to content

Use temporary_filet for automatic resource management #2321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 30 additions & 63 deletions src/ansi-c/c_preprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ Author: Daniel Kroening, [email protected]

#include <fstream>

#if defined(__linux__) || \
defined(__FreeBSD_kernel__) || \
defined(__GNU__) || \
defined(__unix__) || \
defined(__CYGWIN__) || \
defined(__MACH__)
#include <unistd.h>
#endif

/// quote a string for bash and CMD
static std::string shell_quote(const std::string &src)
{
Expand Down Expand Up @@ -325,11 +316,11 @@ bool c_preprocess_visual_studio(

// use Visual Studio's CL

std::string stderr_file=get_temporary_file("tmp.stderr", "");
std::string command_file_name=get_temporary_file("tmp.cl-cmd", "");
temporary_filet stderr_file("tmp.stderr", "");
temporary_filet command_file_name("tmp.cl-cmd", "");

{
std::ofstream command_file(command_file_name);
std::ofstream command_file(command_file_name());

// This marks the command file as UTF-8, which Visual Studio
// understands.
Expand Down Expand Up @@ -385,23 +376,20 @@ bool c_preprocess_visual_studio(
command_file << shell_quote(file) << "\n";
}

std::string tmpi=get_temporary_file("tmp.cl", "");
temporary_filet tmpi("tmp.cl", "");

std::string command="CL @\""+command_file_name+"\"";
command+=" > \""+tmpi+"\"";
command+=" 2> \""+stderr_file+"\"";
std::string command = "CL @\"" + command_file_name() + "\"";
command += " > \"" + tmpi() + "\"";
command += " 2> \"" + stderr_file() + "\"";

// _popen isn't very reliable on WIN32
// that's why we use system()
int result=system(command.c_str());

std::ifstream instream(tmpi);
std::ifstream instream(tmpi());

if(!instream)
{
unlink(tmpi.c_str());
unlink(stderr_file.c_str());
unlink(command_file_name.c_str());
message.error() << "CL Preprocessing failed (open failed)"
<< messaget::eom;
return true;
Expand All @@ -410,15 +398,11 @@ bool c_preprocess_visual_studio(
outstream << instream.rdbuf(); // copy

instream.close();
unlink(tmpi.c_str());
unlink(command_file_name.c_str());

// errors/warnings
std::ifstream stderr_stream(stderr_file);
std::ifstream stderr_stream(stderr_file());
error_parse(stderr_stream, result==0, message);

unlink(stderr_file.c_str());

if(result!=0)
{
message.error() << "CL Preprocessing failed" << messaget::eom;
Expand Down Expand Up @@ -477,7 +461,7 @@ bool c_preprocess_codewarrior(
// preprocessing
messaget message(message_handler);

std::string stderr_file=get_temporary_file("tmp.stderr", "");
temporary_filet stderr_file("tmp.stderr", "");

std::string command;

Expand All @@ -497,37 +481,32 @@ bool c_preprocess_codewarrior(

int result;

std::string tmpi=get_temporary_file("tmp.cl", "");
temporary_filet tmpi("tmp.cl", "");
command+=" \""+file+"\"";
command+=" -o \""+tmpi+"\"";
command+=" 2> \""+stderr_file+"\"";
command += " -o \"" + tmpi() + "\"";
command += " 2> \"" + stderr_file() + "\"";

result=system(command.c_str());

std::ifstream stream_i(tmpi);
std::ifstream stream_i(tmpi());

if(stream_i)
{
postprocess_codewarrior(stream_i, outstream);

stream_i.close();
unlink(tmpi.c_str());
}
else
{
unlink(tmpi.c_str());
unlink(stderr_file.c_str());
message.error() << "Preprocessing failed (fopen failed)"
<< messaget::eom;
return true;
}

// errors/warnings
std::ifstream stderr_stream(stderr_file);
std::ifstream stderr_stream(stderr_file());
error_parse(stderr_stream, result==0, message);

unlink(stderr_file.c_str());

if(result!=0)
{
message.error() << "Preprocessing failed" << messaget::eom;
Expand All @@ -551,7 +530,7 @@ bool c_preprocess_gcc_clang(
// preprocessing
messaget message(message_handler);

std::string stderr_file=get_temporary_file("tmp.stderr", "");
temporary_filet stderr_file("tmp.stderr", "");

std::string command;

Expand Down Expand Up @@ -651,39 +630,35 @@ bool c_preprocess_gcc_clang(
#endif

#ifdef _WIN32
std::string tmpi=get_temporary_file("tmp.gcc", "");
temporary_filet tmpi("tmp.gcc", "");
command+=" \""+file+"\"";
command+=" -o \""+tmpi+"\"";
command+=" 2> \""+stderr_file+"\"";
command += " -o \"" + tmpi() + "\"";
command += " 2> \"" + stderr_file() + "\"";

// _popen isn't very reliable on WIN32
// that's why we use system() and a temporary file
result=system(command.c_str());

std::ifstream instream(tmpi);
std::ifstream instream(tmpi());

// errors/warnings
std::ifstream stderr_stream(stderr_file);
std::ifstream stderr_stream(stderr_file());
error_parse(stderr_stream, result==0, message);

unlink(stderr_file.c_str());

if(instream)
{
outstream << instream.rdbuf();
instream.close();
unlink(tmpi.c_str());
}
else
{
unlink(tmpi.c_str());
message.error() << "GCC preprocessing failed (open failed)"
<< messaget::eom;
result=1;
}
#else
command+=" \""+file+"\"";
command+=" 2> \""+stderr_file+"\"";
command += " 2> \"" + stderr_file() + "\"";

FILE *stream=popen(command.c_str(), "r");

Expand All @@ -703,11 +678,9 @@ bool c_preprocess_gcc_clang(
}

// errors/warnings
std::ifstream stderr_stream(stderr_file);
std::ifstream stderr_stream(stderr_file());
error_parse(stderr_stream, result==0, message);

unlink(stderr_file.c_str());

#endif

if(result!=0)
Expand All @@ -732,7 +705,7 @@ bool c_preprocess_arm(
// preprocessing using armcc
messaget message(message_handler);

std::string stderr_file=get_temporary_file("tmp.stderr", "");
temporary_filet stderr_file("tmp.stderr", "");

std::string command;

Expand Down Expand Up @@ -770,34 +743,31 @@ bool c_preprocess_arm(
int result;

#ifdef _WIN32
std::string tmpi=get_temporary_file("tmp.cl", "");
temporary_filet tmpi("tmp.cl", "");
command+=" \""+file+"\"";
command+=" > \""+tmpi+"\"";
command+=" 2> \""+stderr_file+"\"";
command += " > \"" + tmpi() + "\"";
command += " 2> \"" + stderr_file() + "\"";

// _popen isn't very reliable on WIN32
// that's why we use system() and a temporary file
result=system(command.c_str());

std::ifstream instream(tmpi);
std::ifstream instream(tmpi());

if(!instream)
{
outstream << instream.rdbuf(); // copy
instream.close();
unlink(tmpi.c_str());
}
else
{
unlink(tmpi.c_str());
unlink(stderr_file.c_str());
message.error() << "ARMCC preprocessing failed (fopen failed)"
<< messaget::eom;
return true;
}
#else
command+=" \""+file+"\"";
command+=" 2> \""+stderr_file+"\"";
command += " 2> \"" + stderr_file() + "\"";

FILE *stream=popen(command.c_str(), "r");

Expand All @@ -811,19 +781,16 @@ bool c_preprocess_arm(
}
else
{
unlink(stderr_file.c_str());
message.error() << "ARMCC preprocessing failed (popen failed)"
<< messaget::eom;
return true;
}
#endif

// errors/warnings
std::ifstream stderr_stream(stderr_file);
std::ifstream stderr_stream(stderr_file());
error_parse(stderr_stream, result==0, message);

unlink(stderr_file.c_str());

if(result!=0)
{
message.error() << "ARMCC preprocessing failed" << messaget::eom;
Expand Down
57 changes: 19 additions & 38 deletions src/goto-programs/read_goto_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@ Module: Read Goto Programs

#include "read_goto_binary.h"

#if defined(__linux__) || \
defined(__FreeBSD_kernel__) || \
defined(__GNU__) || \
defined(__unix__) || \
defined(__CYGWIN__) || \
defined(__MACH__)
#include <unistd.h>
#endif

#include <fstream>
#include <unordered_set>

Expand Down Expand Up @@ -105,41 +96,31 @@ bool read_goto_binary(
}
else if(is_osx_fat_magic(hdr))
{
std::string tempname;
messaget message(message_handler);

// Mach-O universal binary
// This _may_ have a goto binary as hppa7100LC architecture
try
osx_fat_readert osx_fat_reader(in);

if(osx_fat_reader.has_gb())
{
osx_fat_readert osx_fat_reader(in);
temporary_filet tempname("tmp.goto-binary", ".gb");
osx_fat_reader.extract_gb(filename, tempname());

if(osx_fat_reader.has_gb())
{
tempname=get_temporary_file("tmp.goto-binary", ".gb");
osx_fat_reader.extract_gb(filename, tempname);

std::ifstream temp_in(tempname, std::ios::binary);
if(!temp_in)
messaget(message_handler).error() << "failed to read temp binary"
<< messaget::eom;
const bool read_err=read_bin_goto_object(
temp_in, filename, symbol_table, goto_functions, message_handler);
temp_in.close();

unlink(tempname.c_str());
return read_err;
}

// architecture not found
messaget(message_handler).error() <<
"failed to find goto binary in Mach-O file" << messaget::eom;
}
std::ifstream temp_in(tempname(), std::ios::binary);
if(!temp_in)
message.error() << "failed to read temp binary" << messaget::eom;

catch(const char *s)
{
if(!tempname.empty())
unlink(tempname.c_str());
messaget(message_handler).error() << s << messaget::eom;
const bool read_err = read_bin_goto_object(
temp_in, filename, symbol_table, goto_functions, message_handler);
temp_in.close();

return read_err;
}

// architecture not found
message.error() << "failed to find goto binary in Mach-O file"
<< messaget::eom;
}
else
{
Expand Down