CBMC
ms_cl_mode.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Visual Studio CL Mode
4 
5 Author: CM Wintersteiger, 2006
6 
7 \*******************************************************************/
8 
11 
12 #include "ms_cl_mode.h"
13 
14 #ifdef _WIN32
15 #define EX_OK 0
16 #define EX_USAGE 64
17 #define EX_SOFTWARE 70
18 #else
19 #include <sysexits.h>
20 #endif
21 
22 #include <iostream>
23 
24 #include <util/config.h>
25 #include <util/file_util.h>
26 #include <util/get_base_name.h>
27 #include <util/message.h>
28 
29 #include "compile.h"
30 #include "ms_cl_version.h"
31 
32 static bool has_directory_suffix(const std::string &path)
33 {
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()=='\\';
39 }
40 
43 {
44  if(cmdline.isset('?') ||
45  cmdline.isset("help"))
46  {
47  help();
48  return EX_OK;
49  }
50 
51  compilet compiler(cmdline, message_handler, cmdline.isset("WX"));
52 
53  #if 0
54  bool act_as_ld=
55  has_prefix(base_name, "link") ||
56  has_prefix(base_name, "goto-link");
57  #endif
58 
59  const auto verbosity = messaget::eval_verbosity(
61 
62  ms_cl_versiont ms_cl_version;
63  ms_cl_version.get("cl.exe");
64 
66  log.debug() << "Visual Studio mode " << ms_cl_version << messaget::eom;
67 
68  // model validation
69  compiler.validate_goto_model = cmdline.isset("validate-goto-model");
70 
71  // get configuration
73 
74  if(ms_cl_version.target == ms_cl_versiont::targett::x86)
76  else if(ms_cl_version.target == ms_cl_versiont::targett::ARM)
78  else if(ms_cl_version.target == ms_cl_versiont::targett::x86)
80 
82  compiler.object_file_extension="obj";
83 
84  // determine actions to be undertaken
85 
86  if(cmdline.isset('E') || cmdline.isset('P'))
88  else if(cmdline.isset('c'))
90  else
92 
93  if(cmdline.isset("std"))
94  {
95  const std::string std_string = cmdline.get_value("std");
96 
97  if(
98  std_string == ":c++14" || std_string == "=c++14" ||
99  std_string == ":c++17" || std_string == "=c++17" ||
100  std_string == ":c++latest" || std_string == "=c++latest")
101  {
102  // we don't have any newer version at the moment
103  config.cpp.set_cpp14();
104  }
105  else if(std_string == ":c++11" || std_string == "=c++11")
106  {
107  // this isn't really a Visual Studio variant, we just do this for GCC
108  // command-line compatibility
109  config.cpp.set_cpp11();
110  }
111  else
112  {
113  log.warning() << "unknown language standard " << std_string
114  << messaget::eom;
115  }
116  }
117  else
118  config.cpp.set_cpp14();
119 
120  compiler.echo_file_name=true;
121 
122  if(cmdline.isset("Fo"))
123  {
124  std::string Fo_value = cmdline.get_value("Fo");
125 
126  // this could be a directory or a file name
127  if(has_directory_suffix(Fo_value))
128  {
129  compiler.output_directory_object = Fo_value;
130 
131  if(!is_directory(Fo_value))
132  log.warning() << "not a directory: " << Fo_value << messaget::eom;
133  }
134  else
135  compiler.output_file_object = Fo_value;
136  }
137 
138  if(
139  compiler.mode == compilet::COMPILE_ONLY &&
140  cmdline.args.size() > 1 &&
141  compiler.output_directory_object.empty())
142  {
143  log.error() << "output directory required for /c with multiple input files"
144  << messaget::eom;
145  return EX_USAGE;
146  }
147 
148  if(cmdline.isset("Fe"))
149  {
151 
152  // this could be a directory
153  if(
155  cmdline.args.size() >= 1)
156  {
157  if(!is_directory(compiler.output_file_executable))
158  {
159  log.warning() << "not a directory: " << compiler.output_file_executable
160  << messaget::eom;
161  }
162 
163  compiler.output_file_executable+=
164  get_base_name(cmdline.args[0], true) + ".exe";
165  }
166  }
167  else
168  {
169  // We need at least one argument.
170  // CL uses the first file name it gets!
171  if(cmdline.args.size()>=1)
172  compiler.output_file_executable=
173  get_base_name(cmdline.args[0], true)+".exe";
174  }
175 
176  if(cmdline.isset('J'))
178 
179  if(verbosity > messaget::M_STATISTICS)
180  {
181  std::list<std::string>::iterator it;
182 
183  std::cout << "Defines:\n";
184  for(it=config.ansi_c.defines.begin();
185  it!=config.ansi_c.defines.end();
186  it++)
187  {
188  std::cout << " " << (*it) << '\n';
189  }
190 
191  std::cout << "Undefines:\n";
192  for(it=config.ansi_c.undefines.begin();
193  it!=config.ansi_c.undefines.end();
194  it++)
195  {
196  std::cout << " " << (*it) << '\n';
197  }
198 
199  std::cout << "Preprocessor Options:\n";
200  for(it=config.ansi_c.preprocessor_options.begin();
202  it++)
203  {
204  std::cout << " " << (*it) << '\n';
205  }
206 
207  std::cout << "Include Paths:\n";
208  for(it=config.ansi_c.include_paths.begin();
209  it!=config.ansi_c.include_paths.end();
210  it++)
211  {
212  std::cout << " " << (*it) << '\n';
213  }
214 
215  std::cout << "Library Paths:\n";
216  for(it=compiler.library_paths.begin();
217  it!=compiler.library_paths.end();
218  it++)
219  {
220  std::cout << " " << (*it) << '\n';
221  }
222 
223  std::cout << "Output file (object): "
224  << compiler.output_file_object << '\n';
225  std::cout << "Output file (executable): "
226  << compiler.output_file_executable << '\n';
227  }
228 
229  // Parse input program, convert to goto program, write output
230  return compiler.doit() ? EX_USAGE : EX_OK;
231 }
232 
235 {
236  std::cout << "goto-cl understands the options of CL plus the following.\n\n";
237 }
messaget
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:154
cmdlinet::args
argst args
Definition: cmdline.h:145
ms_cl_modet::help_mode
virtual void help_mode()
display command line help
Definition: ms_cl_mode.cpp:234
get_base_name
std::string get_base_name(const std::string &in, bool strip_suffix)
cleans a filename from path and extension
Definition: get_base_name.cpp:16
configt::ansi_ct::defines
std::list< std::string > defines
Definition: config.h:250
compilet::echo_file_name
bool echo_file_name
Definition: compile.h:34
cmdlinet::isset
virtual bool isset(char option) const
Definition: cmdline.cpp:30
file_util.h
configt::ansi_ct::include_paths
std::list< std::string > include_paths
Definition: config.h:253
messaget::M_STATISTICS
@ M_STATISTICS
Definition: message.h:171
configt::ansi_ct::flavourt::VISUAL_STUDIO
@ VISUAL_STUDIO
configt::ansi_ct::set_32
void set_32()
Definition: config.cpp:32
configt::ansi_ct::set_64
void set_64()
Definition: config.cpp:37
compilet::doit
bool doit()
reads and source and object files, compiles and links them into goto program objects.
Definition: compile.cpp:60
goto_cc_modet::base_name
const std::string base_name
Definition: goto_cc_mode.h:39
ms_cl_modet::message_handler
cl_message_handlert message_handler
Definition: ms_cl_mode.h:37
messaget::eom
static eomt eom
Definition: message.h:297
configt::ansi_ct::undefines
std::list< std::string > undefines
Definition: config.h:251
configt::ansi_c
struct configt::ansi_ct ansi_c
compilet::validate_goto_model
bool validate_goto_model
Definition: compile.h:35
ms_cl_modet::doit
virtual int doit()
does it.
Definition: ms_cl_mode.cpp:42
configt::cppt::set_cpp14
void set_cpp14()
Definition: config.h:307
compilet::output_file_object
std::string output_file_object
Definition: compile.h:54
compilet::mode
enum compilet::@3 mode
has_prefix
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
compilet::COMPILE_LINK_EXECUTABLE
@ COMPILE_LINK_EXECUTABLE
Definition: compile.h:42
compilet::output_file_executable
std::string output_file_executable
Definition: compile.h:51
configt::cppt::set_cpp11
void set_cpp11()
Definition: config.h:303
messaget::M_ERROR
@ M_ERROR
Definition: message.h:170
cmdlinet::get_value
std::string get_value(char option) const
Definition: cmdline.cpp:48
compilet::library_paths
std::list< std::string > library_paths
Definition: compile.h:45
compile.h
is_directory
bool is_directory(const std::string &path)
Definition: file_util.cpp:187
compilet::object_file_extension
std::string object_file_extension
Definition: compile.h:50
get_base_name.h
configt::ansi_ct::preprocessor_options
std::list< std::string > preprocessor_options
Definition: config.h:252
ms_cl_versiont::targett::ARM
@ ARM
compilet::output_directory_object
std::string output_directory_object
Definition: compile.h:54
config
configt config
Definition: config.cpp:25
ms_cl_versiont
Definition: ms_cl_version.h:19
configt::ansi_ct::mode
flavourt mode
Definition: config.h:237
compilet::COMPILE_ONLY
@ COMPILE_ONLY
Definition: compile.h:38
ms_cl_versiont::targett::x86
@ x86
configt::set
bool set(const cmdlinet &cmdline)
Definition: config.cpp:798
has_directory_suffix
static bool has_directory_suffix(const std::string &path)
Definition: ms_cl_mode.cpp:32
ms_cl_modet::cmdline
ms_cl_cmdlinet & cmdline
Definition: ms_cl_mode.h:36
ms_cl_version.h
config.h
configt::ansi_ct::char_is_unsigned
bool char_is_unsigned
Definition: config.h:137
goto_cc_modet::help
void help()
display command line help
Definition: goto_cc_mode.cpp:47
compilet::PREPROCESS_ONLY
@ PREPROCESS_ONLY
Definition: compile.h:37
configt::cpp
struct configt::cppt cpp
compilet
Definition: compile.h:30
messaget::eval_verbosity
static unsigned eval_verbosity(const std::string &user_input, const message_levelt default_verbosity, message_handlert &dest)
Parse a (user-)provided string as a verbosity level and set it as the verbosity of dest.
Definition: message.cpp:105
message.h
ms_cl_mode.h
ms_cl_versiont::get
void get(const std::string &executable)
Definition: ms_cl_version.cpp:18
ms_cl_versiont::target
enum ms_cl_versiont::targett target