Skip to content

Commit 0698a5f

Browse files
author
Daniel Kroening
authored
Merge pull request #2673 from diffblue/goto-cl-Fo
goto-cl: /Fo can set an output directory
2 parents effb01b + 4df2187 commit 0698a5f

File tree

13 files changed

+141
-21
lines changed

13 files changed

+141
-21
lines changed

buildspec-windows.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ phases:
6363
- |
6464
$env:Path = "C:\tools\cygwin\bin;$env:Path"
6565
cmd /c 'call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 && bash -c "make -C regression test BUILD_ENV=MSVC" '
66+
cmd /c 'call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 && bash -c "make -C regression/goto-cl test BUILD_ENV=MSVC" '
6667
6768
- |
6869
$env:Path = "C:\tools\cygwin\bin;$env:Path"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
3+
--verbosity 10 /c main1.c main2.c /Fo dir
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
^CONVERSION ERROR$

regression/goto-cl/Fo/dir/dummy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// blank

regression/goto-cl/Fo/main1.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// blank

regression/goto-cl/Fo/main2.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// blank

regression/goto-cl/Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
default: tests.log
2+
3+
test:
4+
@../test.pl -p -c ../../../src/goto-cc/goto-cl
5+
6+
tests.log: ../test.pl
7+
@../test.pl -p -c ../../../src/goto-cc/goto-cl
8+
9+
show:
10+
@for dir in *; do \
11+
if [ -d "$$dir" ]; then \
12+
vim -o "$$dir/*.c" "$$dir/*.out"; \
13+
fi; \
14+
done;
15+
16+
clean:
17+
find -name '*.out' -execdir $(RM) '{}' \;
18+
find -name '*.gb' -execdir $(RM) '{}' \;
19+
find -name '*.obj' -execdir $(RM) '{}' \;
20+
find -name '*.goto-cc-saved' -execdir $(RM) '{}' \;
21+
$(RM) tests.log

src/goto-cc/compile.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,17 @@ bool compilet::compile()
421421
std::string cfn;
422422

423423
if(output_file_object=="")
424-
cfn=get_base_name(file_name, true)+"."+object_file_extension;
424+
{
425+
const std::string file_name_with_obj_ext =
426+
get_base_name(file_name, true) + "." + object_file_extension;
427+
428+
if(!output_directory_object.empty())
429+
cfn = concat_dir_file(output_directory_object, file_name_with_obj_ext);
430+
else
431+
cfn = file_name_with_obj_ext;
432+
}
425433
else
426-
cfn=output_file_object;
434+
cfn = output_file_object;
427435

428436
if(write_object_file(cfn, symbol_table, compiled_functions))
429437
return true;

src/goto-cc/compile.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ class compilet:public language_uit
4545
std::list<irep_idt> seen_modes;
4646

4747
std::string object_file_extension;
48-
std::string output_file_object, output_file_executable;
48+
std::string output_file_executable;
49+
50+
// the two options below are mutually exclusive -- use either or
51+
std::string output_file_object, output_directory_object;
4952

5053
compilet(cmdlinet &_cmdline, ui_message_handlert &mh, bool Werror);
5154

src/goto-cc/ms_cl_mode.cpp

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,24 @@ Author: CM Wintersteiger, 2006
2121

2222
#include <iostream>
2323

24-
#include <util/message.h>
25-
#include <util/prefix.h>
2624
#include <util/config.h>
25+
#include <util/file_util.h>
2726
#include <util/get_base_name.h>
27+
#include <util/message.h>
28+
#include <util/prefix.h>
2829

2930
#include "compile.h"
3031

31-
/// does it.
32-
static bool is_directory(const std::string &s)
32+
static bool has_directory_suffix(const std::string &path)
3333
{
34-
if(s.empty())
35-
return false;
36-
char last_char=s[s.size()-1];
37-
// Visual CL recognizes both
38-
return last_char=='\\' || last_char=='/';
34+
// MS CL decides whether a parameter is a directory on the
35+
// basis of the / or \\ suffix; it doesn't matter
36+
// whether the directory actually exists.
37+
return path.empty() ? false :
38+
path.back()=='/' || path.back()=='\\';
3939
}
4040

41+
/// does it.
4142
int ms_cl_modet::doit()
4243
{
4344
if(cmdline.isset('?') ||
@@ -103,24 +104,36 @@ int ms_cl_modet::doit()
103104

104105
if(cmdline.isset("Fo"))
105106
{
106-
compiler.output_file_object=cmdline.get_value("Fo");
107+
std::string Fo_value = cmdline.get_value("Fo");
107108

108-
// this could be a directory
109-
if(is_directory(compiler.output_file_object) &&
110-
cmdline.args.size()>=1)
111-
compiler.output_file_object+=
112-
get_base_name(cmdline.args[0], true)+".obj";
109+
// this could be a directory or a file name
110+
if(has_directory_suffix(Fo_value))
111+
{
112+
compiler.output_directory_object = Fo_value;
113+
114+
if(!is_directory(Fo_value))
115+
warning() << "not a directory: " << Fo_value << eom;
116+
}
117+
else
118+
compiler.output_file_object = Fo_value;
113119
}
114120

115121
if(cmdline.isset("Fe"))
116122
{
117123
compiler.output_file_executable=cmdline.get_value("Fe");
118124

119125
// this could be a directory
120-
if(is_directory(compiler.output_file_executable) &&
121-
cmdline.args.size()>=1)
126+
if(
127+
has_directory_suffix(compiler.output_file_executable) &&
128+
cmdline.args.size() >= 1)
129+
{
130+
if(!is_directory(compiler.output_file_executable))
131+
warning() << "not a directory: "
132+
<< compiler.output_file_executable << eom;
133+
122134
compiler.output_file_executable+=
123-
get_base_name(cmdline.args[0], true)+".exe";
135+
get_base_name(cmdline.args[0], true) + ".exe";
136+
}
124137
}
125138
else
126139
{

src/util/file_util.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,28 @@ std::string concat_dir_file(
145145
file_name : directory+"/"+file_name;
146146
#endif
147147
}
148+
149+
bool is_directory(const std::string &path)
150+
{
151+
if(path.empty())
152+
return false;
153+
154+
#ifdef _WIN32
155+
156+
auto attributes = ::GetFileAttributesW(widen(path).c_str());
157+
if (attributes == INVALID_FILE_ATTRIBUTES)
158+
return false;
159+
else
160+
return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
161+
162+
#else
163+
164+
struct stat buf;
165+
166+
if(stat(path.c_str(), &buf)!=0)
167+
return false;
168+
else
169+
return (buf.st_mode & S_IFDIR) != 0;
170+
171+
#endif
172+
}

src/util/file_util.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ std::string get_current_working_directory();
1919
std::string concat_dir_file(const std::string &directory,
2020
const std::string &file_name);
2121

22+
// C++17 will allow us to use std::filesystem::is_directory()
23+
bool is_directory(const std::string &path);
24+
2225
#endif // CPROVER_UTIL_FILE_UTIL_H

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ SRC += unit_tests.cpp \
2828
solvers/refinement/string_refinement/union_find_replace.cpp \
2929
util/expr.cpp \
3030
util/expr_cast/expr_cast.cpp \
31+
util/file_util.cpp \
3132
util/get_base_name.cpp \
3233
util/graph.cpp \
3334
util/irep.cpp \

unit/util/file_util.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for file_util.h
4+
5+
Author: Daniel Kroening
6+
7+
\*******************************************************************/
8+
9+
#include <testing-utils/catch.hpp>
10+
11+
#include <util/file_util.h>
12+
#include <util/tempdir.h>
13+
#include <util/unicode.h>
14+
15+
#include <fstream>
16+
17+
TEST_CASE("is_directory functionality", "[core][util][file_util]")
18+
{
19+
temp_dirt temp_dir("testXXXXXX");
20+
21+
#ifdef _WIN32
22+
std::ofstream outfile(widen(temp_dir("file")));
23+
#else
24+
std::ofstream outfile(temp_dir("file"));
25+
#endif
26+
27+
outfile.close();
28+
29+
REQUIRE(is_directory(temp_dir.path));
30+
REQUIRE(is_directory(temp_dir.path+"/"));
31+
REQUIRE(!is_directory(temp_dir("whatnot")));
32+
REQUIRE(!is_directory(temp_dir("file")));
33+
REQUIRE(!is_directory(""));
34+
}

0 commit comments

Comments
 (0)