cprover
Toggle main menu visibility
Loading...
Searching...
No Matches
ms_link_cmdline.cpp
Go to the documentation of this file.
1
/*******************************************************************\
2
3
Module: A special command line object for LINK options
4
5
Author: 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
22
const
char
*
non_ms_link_options
[]=
23
{
24
"--help"
,
25
"--verbosity"
26
};
27
28
bool
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
61
bool
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
74
static
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
109
void
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))
157
process_response_file_line
(line);
158
}
159
else
160
{
161
// normal ASCII
162
infile.seekg(0);
163
while
(getline(infile, line))
164
process_response_file_line
(line);
165
}
166
}
167
168
void
ms_link_cmdlinet::process_response_file_line
(
const
std::string &line)
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
{
195
in_quotes = !in_quotes;
196
}
197
else
198
option += ch;
199
}
200
201
if
(!option.empty())
202
arguments.push_back(option);
203
204
parse
(arguments);
205
}
206
207
void
ms_link_cmdlinet::process_non_link_option
(
const
std::string &s)
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
219
const
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
313
static
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
320
void
ms_link_cmdlinet::process_link_option
(
const
std::string &s)
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
}
transform
static abstract_object_pointert transform(const exprt &expr, const std::vector< abstract_object_pointert > &operands, const abstract_environmentt &environment, const namespacet &ns)
Definition
abstract_value_object.cpp:159
cmdlinet::getoptnr
std::optional< std::size_t > getoptnr(char option) const
Definition
cmdline.cpp:145
cmdlinet::args
argst args
Definition
cmdline.h:154
cmdlinet::options
std::vector< optiont > options
Definition
cmdline.h:193
goto_cc_cmdlinet::set
void set(const std::string &opt, const char *value) override
Set option option to value.
Definition
goto_cc_cmdline.h:33
ms_link_cmdlinet::parse
virtual bool parse(int, const char **)
parses the command line options into a cmdlinet
Definition
ms_link_cmdline.cpp:61
ms_link_cmdlinet::process_non_link_option
void process_non_link_option(const std::string &s)
Definition
ms_link_cmdline.cpp:207
ms_link_cmdlinet::process_response_file_line
void process_response_file_line(const std::string &line)
Definition
ms_link_cmdline.cpp:168
ms_link_cmdlinet::process_response_file
void process_response_file(const std::string &file)
Definition
ms_link_cmdline.cpp:109
ms_link_cmdlinet::process_link_option
void process_link_option(const std::string &s)
Definition
ms_link_cmdline.cpp:320
my_wgetline
static std::istream & my_wgetline(std::istream &in, std::wstring &dest)
Definition
ms_cl_cmdline.cpp:137
my_wgetline
static std::istream & my_wgetline(std::istream &in, std::wstring &dest)
Definition
ms_link_cmdline.cpp:74
ms_link_options
const char * ms_link_options[]
Definition
ms_link_cmdline.cpp:219
to_upper_string
static std::string to_upper_string(const std::string &s)
Definition
ms_link_cmdline.cpp:313
non_ms_link_options
const char * non_ms_link_options[]
parses the command line options into a cmdlinet
Definition
ms_link_cmdline.cpp:22
ms_link_cmdline.h
A special command line object for LINK options.
narrow
output_type narrow(input_type input)
Run-time checked narrowing cast.
Definition
narrow.h:34
cmdlinet::optiont
Definition
cmdline.h:165
cmdlinet::optiont::optchar
char optchar
Definition
cmdline.h:169
cmdlinet::optiont::optstring
std::string optstring
Definition
cmdline.h:170
cmdlinet::optiont::islong
bool islong
Definition
cmdline.h:168
file
Definition
kdev_t.h:19
unicode.h
goto-cc
ms_link_cmdline.cpp
Generated by
1.17.0