cprover
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 #include <util/prefix.h>
29 
30 #include "compile.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 = eval_verbosity(
61 
62  debug() << "Visual Studio mode" << eom;
63 
64  // get configuration
66 
68  compiler.object_file_extension="obj";
69 
70  // determine actions to be undertaken
71 
72  if(cmdline.isset('E') || cmdline.isset('P'))
73  compiler.mode=compilet::PREPROCESS_ONLY;
74  else if(cmdline.isset('c'))
75  compiler.mode=compilet::COMPILE_ONLY;
76  else
78 
79  if(cmdline.isset("std"))
80  {
81  const std::string std_string = cmdline.get_value("std");
82 
83  if(
84  std_string == ":c++14" || std_string == "=c++14" ||
85  std_string == ":c++17" || std_string == "=c++17" ||
86  std_string == ":c++latest" || std_string == "=c++latest")
87  {
88  // we don't have any newer version at the moment
90  }
91  else if(std_string == ":c++11" || std_string == "=c++11")
92  {
93  // this isn't really a Visual Studio variant, we just do this for GCC
94  // command-line compatibility
96  }
97  else
98  warning() << "unknown language standard " << std_string << eom;
99  }
100  else
101  config.cpp.set_cpp14();
102 
103  compiler.echo_file_name=true;
104 
105  if(cmdline.isset("Fo"))
106  {
107  std::string Fo_value = cmdline.get_value("Fo");
108 
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;
119  }
120 
121  if(
122  compiler.mode == compilet::COMPILE_ONLY &&
123  cmdline.args.size() > 1 &&
124  compiler.output_directory_object.empty())
125  {
126  error() << "output directory required for /c with multiple input files"
127  << eom;
128  return EX_USAGE;
129  }
130 
131  if(cmdline.isset("Fe"))
132  {
133  compiler.output_file_executable=cmdline.get_value("Fe");
134 
135  // this could be a directory
136  if(
137  has_directory_suffix(compiler.output_file_executable) &&
138  cmdline.args.size() >= 1)
139  {
140  if(!is_directory(compiler.output_file_executable))
141  warning() << "not a directory: "
142  << compiler.output_file_executable << eom;
143 
144  compiler.output_file_executable+=
145  get_base_name(cmdline.args[0], true) + ".exe";
146  }
147  }
148  else
149  {
150  // We need at least one argument.
151  // CL uses the first file name it gets!
152  if(cmdline.args.size()>=1)
153  compiler.output_file_executable=
154  get_base_name(cmdline.args[0], true)+".exe";
155  }
156 
157  if(cmdline.isset('J'))
159 
160  if(verbosity > messaget::M_STATISTICS)
161  {
162  std::list<std::string>::iterator it;
163 
164  std::cout << "Defines:\n";
165  for(it=config.ansi_c.defines.begin();
166  it!=config.ansi_c.defines.end();
167  it++)
168  {
169  std::cout << " " << (*it) << '\n';
170  }
171 
172  std::cout << "Undefines:\n";
173  for(it=config.ansi_c.undefines.begin();
174  it!=config.ansi_c.undefines.end();
175  it++)
176  {
177  std::cout << " " << (*it) << '\n';
178  }
179 
180  std::cout << "Preprocessor Options:\n";
181  for(it=config.ansi_c.preprocessor_options.begin();
183  it++)
184  {
185  std::cout << " " << (*it) << '\n';
186  }
187 
188  std::cout << "Include Paths:\n";
189  for(it=config.ansi_c.include_paths.begin();
190  it!=config.ansi_c.include_paths.end();
191  it++)
192  {
193  std::cout << " " << (*it) << '\n';
194  }
195 
196  std::cout << "Library Paths:\n";
197  for(it=compiler.library_paths.begin();
198  it!=compiler.library_paths.end();
199  it++)
200  {
201  std::cout << " " << (*it) << '\n';
202  }
203 
204  std::cout << "Output file (object): "
205  << compiler.output_file_object << '\n';
206  std::cout << "Output file (executable): "
207  << compiler.output_file_executable << '\n';
208  }
209 
210  // Parse input program, convert to goto program, write output
211  return compiler.doit() ? EX_USAGE : EX_OK;
212 }
213 
216 {
217  std::cout << "goto-cl understands the options of CL plus the following.\n\n";
218 }
struct configt::ansi_ct ansi_c
ms_cl_cmdlinet & cmdline
Definition: ms_cl_mode.h:37
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:78
std::list< std::string > defines
Definition: config.h:120
std::string get_value(char option) const
Definition: cmdline.cpp:45
std::list< std::string > undefines
Definition: config.h:121
virtual void help_mode()
display command line help
Definition: ms_cl_mode.cpp:215
static mstreamt & eom(mstreamt &m)
Definition: message.h:272
configt config
Definition: config.cpp:23
std::string get_base_name(const std::string &in, bool strip_suffix)
cleans a filename from path and extension
Visual Studio CL Mode.
mstreamt & warning() const
Definition: message.h:307
void set_cpp14()
Definition: config.h:142
bool set(const cmdlinet &cmdline)
Definition: config.cpp:738
argst args
Definition: cmdline.h:37
virtual bool isset(char option) const
Definition: cmdline.cpp:27
flavourt mode
Definition: config.h:114
mstreamt & error() const
Definition: message.h:302
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
bool char_is_unsigned
Definition: config.h:43
Compile and link source and object files.
struct configt::cppt cpp
void set_cpp11()
Definition: config.h:141
virtual void help()
display command line help
virtual int doit()
does it.
Definition: ms_cl_mode.cpp:42
console_message_handlert message_handler
Definition: ms_cl_mode.h:38
mstreamt & debug() const
Definition: message.h:332
bool is_directory(const std::string &path)
Definition: file_util.cpp:147
std::list< std::string > preprocessor_options
Definition: config.h:122
static bool has_directory_suffix(const std::string &path)
Definition: ms_cl_mode.cpp:32
const std::string base_name
Definition: goto_cc_mode.h:38
std::list< std::string > include_paths
Definition: config.h:123