CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ms_link_cmdline.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: A special command line object for LINK options
4
5Author: Daniel Kroening
6
7\*******************************************************************/
8
11
12#include "ms_link_cmdline.h"
13
14#include <util/unicode.h>
15
16#include <fstream> // IWYU pragma: keep
17#include <iostream>
18
22const char *non_ms_link_options[]=
23{
24 "--help",
25 "--verbosity"
26};
27
28bool ms_link_cmdlinet::parse(const std::vector<std::string> &arguments)
29{
30 for(std::size_t i = 0; i < arguments.size(); i++)
31 {
32 // is it a non-link option?
33 if(std::string(arguments[i], 0, 2) == "--")
34 {
35 process_non_link_option(arguments[i]);
36
37 if(arguments[i] == "--verbosity")
38 {
39 if(i < arguments.size() - 1)
40 {
41 set(arguments[i], arguments[i + 1]);
42 i++; // skip ahead
43 }
44 }
45 }
46 else if(!arguments[i].empty() && arguments[i][0] == '@')
47 {
48 // potentially recursive
49 process_response_file(std::string(arguments[i], 1, std::string::npos));
50 }
51 else
52 process_link_option(arguments[i]);
53 }
54
55 return false;
56}
57
61bool ms_link_cmdlinet::parse(int argc, const char **argv)
62{
63 // should really use "wide" argv from wmain()
64
65 std::vector<std::string> arguments;
66
67 // skip argv[0]
68 for(int i = 1; i < argc; i++)
69 arguments.push_back(argv[i]);
70
71 return parse(arguments);
72}
73
74static std::istream &my_wgetline(std::istream &in, std::wstring &dest)
75{
76 // We should support this properly,
77 // but will just strip right now.
78 dest.clear();
79
80 while(in)
81 {
82 char ch1, ch2;
83 in.get(ch1);
84 in.get(ch2);
85
86 if(!in)
87 {
88 if(!dest.empty())
89 in.clear();
90 break;
91 }
92
93 if(ch1 == '\r')
94 {
95 // ignore
96 }
97 else if(ch1 == '\n')
98 {
99 in.clear();
100 break; // line end
101 }
102 else
103 dest += wchar_t(ch1 + (ch2 << 8));
104 }
105
106 return in;
107}
108
109void ms_link_cmdlinet::process_response_file(const std::string &file)
110{
111 std::ifstream infile(file);
112
113 if(!infile)
114 {
115 std::cerr << "failed to open response file '" << file << "'\n";
116 return;
117 }
118
119 // these may be Unicode -- which is indicated by 0xff 0xfe
120 std::string line;
121 getline(infile, line);
122 if(
123 line.size() >= 2 && line[0] == static_cast<char>(0xff) &&
124 line[1] == static_cast<char>(0xfe))
125 {
126 // Unicode, UTF-16 little endian
127
128#if 1
129 // Re-open -- should be using wifstream,
130 // but this isn't available everywhere.
131 std::ifstream infile2(file, std::ios::binary);
132 infile2.seekg(2);
133 std::wstring wline;
134
135 while(my_wgetline(infile2, wline))
136 process_response_file_line(narrow(wline)); // we UTF-8 it
137
138#else
139
140 std::wifstream infile2(file, std::ios::binary);
141 std::wstring wline;
142
143 while(std::getline(infile2, wline))
144 process_response_file_line(narrow(wline)); // we UTF-8 it
145
146#endif
147 }
148 else if(
149 line.size() >= 3 && line[0] == static_cast<char>(0xef) &&
150 line[1] == static_cast<char>(0xbb) && line[2] == static_cast<char>(0xbf))
151 {
152 // This is the UTF-8 BOM. We can proceed as usual, since
153 // we use UTF-8 internally.
154 infile.seekg(3);
155
156 while(getline(infile, line))
158 }
159 else
160 {
161 // normal ASCII
162 infile.seekg(0);
163 while(getline(infile, line))
165 }
166}
167
169{
170 // In a response file, multiple compiler options and source-code files can
171 // appear on one line. A single compiler-option specification must appear
172 // on one line (cannot span multiple lines). Response files can have
173 // comments that begin with the # symbol.
174
175 if(line.empty())
176 return;
177 if(line[0] == '#')
178 return; // comment
179
180 std::vector<std::string> arguments;
181 std::string option;
182 bool in_quotes = false;
183 for(std::size_t i = 0; i < line.size(); i++)
184 {
185 char ch = line[i];
186
187 if(ch == ' ' && !in_quotes)
188 {
189 if(!option.empty())
190 arguments.push_back(option);
191 option.clear();
192 }
193 else if(ch == '"')
194 {
196 }
197 else
198 option += ch;
199 }
200
201 if(!option.empty())
202 arguments.push_back(option);
203
204 parse(arguments);
205}
206
208{
209 set(s);
210
211 for(const auto & opt : non_ms_link_options)
212 if(s == opt)
213 return;
214
215 // unrecognized option
216 std::cout << "Warning: uninterpreted non-LINK option '" << s << "'\n";
217}
218
219const char *ms_link_options[] = {
220 "ALIGN",
221 "ALLOWBIND",
222 "ALLOWISOLATION",
223 "APPCONTAINER",
224 "ASSEMBLYDEBUG",
225 "ASSEMBLYLINKRESOURCE",
226 "ASSEMBLYMODULE",
227 "ASSEMBLYRESOURCE",
228 "BASE",
229 "CLRIMAGETYPE",
230 "CLRLOADEROPTIMIZATION",
231 "CLRSUPPORTLASTERROR",
232 "CLRTHREADATTRIBUTE",
233 "CLRUNMANAGEDCODECHECK",
234 "DEBUG",
235 "DEF",
236 "DEFAULTLIB",
237 "DELAY",
238 "DELAYLOAD",
239 "DELAYSIGN",
240 "DLL",
241 "DRIVER",
242 "DYNAMICBASE",
243 "ENTRY",
244 "ERRORREPORT",
245 "EXPORT",
246 "EXPORTPADMIN",
247 "FASTGENPROFILE",
248 "FIXED",
249 "FORCE",
250 "FUNCTIONPADMIN",
251 "GUARD",
252 "GENPROFILE",
253 "HEAP",
254 "HIGHENTROPYVA",
255 "IDLOUT",
256 "IGNORE",
257 "IGNOREIDL",
258 "IMPLIB",
259 "INCLUDE",
260 "INCREMENTAL",
261 "INTEGRITYCHECK",
262 "KERNEL",
263 "KEYCONTAINER",
264 "KEYFILE",
265 "LARGEADDRESSAWARE",
266 "LIBPATH",
267 "LTCG",
268 "MACHINE",
269 "MANIFEST",
270 "MANIFESTDEPENDENCY",
271 "MANIFESTFILE",
272 "MANIFESTINPUT",
273 "MANIFESTUAC",
274 "MAP",
275 "MAPINFO",
276 "MERGE",
277 "MIDL",
278 "NOASSEMBLY",
279 "NODEFAULTLIB",
280 "NOENTRY",
281 "NOIMPLIB",
282 "NOLOGO",
283 "NXCOMPAT",
284 "OPT",
285 "ORDER",
286 "OUT",
287 "PDB",
288 "PDBSTRIPPED",
289 "PROFILE",
290 "RELEASE",
291 "SAFESEH",
292 "SECTION",
293 "STACK",
294 "STUB",
295 "SUBSYSTEM",
296 "SWAPRUN",
297 "TLBID",
298 "TLBOUT",
299 "TIME",
300 "TSAWARE",
301 "USEPROFILE",
302 "VERBOSE",
303 "VERSION",
304 "WINMD",
305 "WINMDDELAYSIGN",
306 "WINMDFILE",
307 "WINMDKEYCONTAINER",
308 "WINMDKEYFILE",
309 "WHOLEARCHIVE",
310 "WX"
311};
312
313static std::string to_upper_string(const std::string &s)
314{
315 std::string result = s;
316 transform(result.begin(), result.end(), result.begin(), toupper);
317 return result;
318}
319
321{
322 if(s.empty())
323 return;
324
325 if(s[0] != '/' && s[0] != '-')
326 {
327 args.push_back(s);
328 return;
329 }
330
331 for(const std::string ms_link_option : ms_link_options)
332 {
333 // These are case insensitive.
334 if(
335 to_upper_string(std::string(s, 1, std::string::npos)) == ms_link_option ||
336 to_upper_string(std::string(s, 1, ms_link_option.size() + 1)) == ms_link_option + ':')
337 {
338 std::optional<std::size_t> optnr = getoptnr(ms_link_option);
339
340 if(!optnr.has_value())
341 {
342 cmdlinet::optiont option;
343 option.islong = true;
344 option.optstring = ms_link_option;
345 option.optchar = 0;
346 options.push_back(option);
347 optnr = options.size() - 1;
348 }
349
350 options[*optnr].isset = true;
351
352 if(s.size() > ms_link_option.size() + 1)
353 options[*optnr].values.push_back(
354 std::string(s, ms_link_option.size() + 2, std::string::npos));
355
356 return;
357 }
358 }
359
360 // unrecognized option
361 std::cout << "Warning: uninterpreted LINK option '" << s << "'\n";
362}
static abstract_object_pointert transform(const exprt &expr, const std::vector< abstract_object_pointert > &operands, const abstract_environmentt &environment, const namespacet &ns)
virtual void clear()
Reset the abstract state.
Definition ai.h:265
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
std::optional< std::size_t > getoptnr(char option) const
Definition cmdline.cpp:145
argst args
Definition cmdline.h:154
std::vector< optiont > options
Definition cmdline.h:193
void set(const std::string &opt, const char *value) override
Set option option to value.
int toupper(int c)
Definition ctype.c:134
static std::istream & my_wgetline(std::istream &in, std::wstring &dest)
output_type narrow(input_type input)
Run-time checked narrowing cast.
Definition narrow.h:34
std::string optstring
Definition cmdline.h:170