blob: 0e8d05350da2df33b5e0f5c92eadd02584453ba2 [file] [log] [blame]
Daniel Dunbara5677512009-01-05 19:53:30 +00001class Option(object):
2 """Root option class."""
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +00003
4 def __init__(self, name, isLinkerInput=False, noOptAsInput=False):
Daniel Dunbara5677512009-01-05 19:53:30 +00005 self.name = name
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +00006 self.isLinkerInput = isLinkerInput
7 self.noOptAsInput = noOptAsInput
Daniel Dunbara5677512009-01-05 19:53:30 +00008
9 def accept(self, index, arg, it):
10 """accept(index, arg, iterator) -> Arg or None
11
12 Accept the argument at the given index, returning an Arg, or
13 return None if the option does not accept this argument.
14
15 May raise MissingArgumentError.
16 """
17 abstract
18
19 def __repr__(self):
20 return '<%s name=%r>' % (self.__class__.__name__,
21 self.name)
22
Daniel Dunbar5039f212009-01-06 02:30:10 +000023# Dummy options
24
25class InputOption(Option):
26 def __init__(self):
27 super(InputOption, self).__init__('<input>')
28
29 def accept(self):
30 raise RuntimeError,"accept() should never be used on InputOption instance."
31
32class UnknownOption(Option):
33 def __init__(self):
34 super(UnknownOption, self).__init__('<unknown>')
35
36 def accept(self):
37 raise RuntimeError,"accept() should never be used on UnknownOption instance."
38
39# Normal options
40
Daniel Dunbara5677512009-01-05 19:53:30 +000041class FlagOption(Option):
42 """An option which takes no arguments."""
43
44 def accept(self, index, arg, it):
45 if arg == self.name:
46 return Arg(index, self)
47
48class JoinedOption(Option):
49 """An option which literally prefixes its argument."""
50
51 def accept(self, index, arg, it):
52 if arg.startswith(self.name):
53 return JoinedValueArg(index, self)
54
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +000055class CommaJoinedOption(Option):
56 """An option which literally prefixs its argument, but which
57 conceptually may have an arbitrary number of arguments which are
58 separated by commas."""
59
60 def accept(self, index, arg, it):
61 if arg.startswith(self.name):
62 return CommaJoinedValuesArg(index, self)
63
Daniel Dunbara5677512009-01-05 19:53:30 +000064class SeparateOption(Option):
65 """An option which is followed by its value."""
66
67 def accept(self, index, arg, it):
68 if arg == self.name:
69 try:
70 _,value = it.next()
71 except StopIteration:
72 raise MissingArgumentError,self
73 return SeparateValueArg(index, self)
74
75class MultiArgOption(Option):
76 """An option which takes multiple arguments."""
77
78 def __init__(self, name, numArgs):
79 assert numArgs > 1
80 super(MultiArgOption, self).__init__(name)
81 self.numArgs = numArgs
82
83 def accept(self, index, arg, it):
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +000084 if arg == self.name:
Daniel Dunbara5677512009-01-05 19:53:30 +000085 try:
86 values = [it.next()[1] for i in range(self.numArgs)]
87 except StopIteration:
88 raise MissingArgumentError,self
89 return MultipleValuesArg(index, self)
90
91class JoinedOrSeparateOption(Option):
92 """An option which either literally prefixes its value or is
93 followed by an value."""
94
95 def accept(self, index, arg, it):
96 if arg.startswith(self.name):
97 if len(arg) != len(self.name): # Joined case
98 return JoinedValueArg(index, self)
99 else:
100 try:
101 _,value = it.next()
102 except StopIteration:
103 raise MissingArgumentError,self
104 return SeparateValueArg(index, self)
105
106class JoinedAndSeparateOption(Option):
107 """An option which literally prefixes its value and is followed by
108 an value."""
109
110 def accept(self, index, arg, it):
111 if arg.startswith(self.name):
112 try:
113 _,value = it.next()
114 except StopIteration:
115 raise MissingArgumentError,self
116 return JoinedAndSeparateValuesArg(index, self)
117
118###
119
120class Arg(object):
121 """Arg - Base class for actual driver arguments."""
122 def __init__(self, index, opt):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000123 assert opt is not None
Daniel Dunbara5677512009-01-05 19:53:30 +0000124 self.index = index
125 self.opt = opt
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000126
Daniel Dunbara5677512009-01-05 19:53:30 +0000127 def __repr__(self):
128 return '<%s index=%r opt=%r>' % (self.__class__.__name__,
129 self.index,
130 self.opt)
131
132 def render(self, args):
133 """render(args) -> [str]
134
135 Map the argument into a list of actual program arguments,
136 given the source argument array."""
137 assert self.opt
138 return [self.opt.name]
139
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000140 def renderAsInput(self, args):
141 return self.render(args)
142
Daniel Dunbara5677512009-01-05 19:53:30 +0000143class ValueArg(Arg):
144 """ValueArg - An instance of an option which has an argument."""
145
146 def getValue(self, args):
147 abstract
148
Daniel Dunbar5039f212009-01-06 02:30:10 +0000149class PositionalArg(ValueArg):
150 """PositionalArg - A simple positional argument."""
Daniel Dunbara5677512009-01-05 19:53:30 +0000151
152 def getValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000153 return args.getInputString(self.index)
Daniel Dunbara5677512009-01-05 19:53:30 +0000154
155 def render(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000156 return [args.getInputString(self.index)]
Daniel Dunbara5677512009-01-05 19:53:30 +0000157
158class JoinedValueArg(ValueArg):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000159 """JoinedValueArg - A single value argument where the value is
160 joined (suffixed) to the option."""
161
Daniel Dunbara5677512009-01-05 19:53:30 +0000162 def getValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000163 return args.getInputString(self.index)[len(self.opt.name):]
Daniel Dunbara5677512009-01-05 19:53:30 +0000164
Daniel Dunbara5677512009-01-05 19:53:30 +0000165 def render(self, args):
166 return [self.opt.name + self.getValue(args)]
167
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000168 def renderAsInput(self, args):
169 if self.opt.noOptAsInput:
170 return [self.getValue(args)]
171 return self.render(args)
172
Daniel Dunbara5677512009-01-05 19:53:30 +0000173class SeparateValueArg(ValueArg):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000174 """SeparateValueArg - A single value argument where the value
175 follows the option in the argument vector."""
176
Daniel Dunbara5677512009-01-05 19:53:30 +0000177 def getValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000178 return args.getInputString(self.index, offset=1)
Daniel Dunbara5677512009-01-05 19:53:30 +0000179
Daniel Dunbara5677512009-01-05 19:53:30 +0000180 def render(self, args):
181 return [self.opt.name, self.getValue(args)]
182
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000183 def renderAsInput(self, args):
184 if self.opt.noOptAsInput:
185 return [self.getValue(args)]
186 return self.render(args)
187
Daniel Dunbara5677512009-01-05 19:53:30 +0000188class MultipleValuesArg(Arg):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000189 """MultipleValuesArg - An argument with multiple values which
190 follow the option in the argument vector."""
191
192 # FIXME: Should we unify this with SeparateValueArg?
193
Daniel Dunbara5677512009-01-05 19:53:30 +0000194 def getValues(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000195 return [args.getInputString(self.index, offset=1+i)
196 for i in range(self.opt.numArgs)]
Daniel Dunbara5677512009-01-05 19:53:30 +0000197
Daniel Dunbara5677512009-01-05 19:53:30 +0000198 def render(self, args):
199 return [self.opt.name] + self.getValues(args)
200
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000201class CommaJoinedValuesArg(Arg):
202 """CommaJoinedValuesArg - An argument with multiple values joined
203 by commas and joined (suffixed) to the option.
204
205 The key point of this arg is that it renders its values into
206 separate arguments, which allows it to be used as a generic
207 mechanism for passing arguments through to tools."""
208
209 def getValues(self, args):
210 return args.getInputString(self.index)[len(self.opt.name):].split(',')
211
212 def render(self, args):
213 return [self.opt.name + ','.join(self.getValues(args))]
214
215 def renderAsInput(self, args):
216 return self.getValues(args)
217
Daniel Dunbara5677512009-01-05 19:53:30 +0000218# FIXME: Man, this is lame. It is only used by -Xarch. Maybe easier to
219# just special case?
220class JoinedAndSeparateValuesArg(Arg):
221 """JoinedAndSeparateValuesArg - An argument with both joined and
222 separate values."""
223
224 def getJoinedValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000225 return args.getInputString(self.index)[len(self.opt.name):]
Daniel Dunbara5677512009-01-05 19:53:30 +0000226
227 def getSeparateValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000228 return args.getInputString(self.index, offset=1)
Daniel Dunbara5677512009-01-05 19:53:30 +0000229
230 def render(self, args):
231 return ([self.opt.name + self.getJoinedValue(args)] +
232 [self.getSeparateValue(args)])
233
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000234###
235
236class InputIndex:
237 def __init__(self, sourceId, pos):
238 self.sourceId = sourceId
239 self.pos = pos
240
241 def __repr__(self):
242 return 'InputIndex(%d, %d)' % (self.sourceId, self.pos)
243
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000244class ArgList:
Daniel Dunbar5039f212009-01-06 02:30:10 +0000245 """ArgList - Collect an input argument vector along with a set of parsed Args
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000246 and supporting information."""
247
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000248 def __init__(self, parser, argv):
249 self.parser = parser
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000250 self.argv = list(argv)
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000251 self.syntheticArgv = []
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000252 self.lastArgs = {}
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000253 self.args = []
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000254
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000255 def getArgs(self, option):
256 # FIXME: How efficient do we want to make this. One reasonable
257 # solution would be to embed a linked list inside each arg and
258 # automatically chain them (with pointers to head and
259 # tail). This gives us efficient access to the (first, last,
260 # all) arg(s) with little overhead.
261 for arg in self.args:
262 if arg.opt is option:
263 yield arg
264
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000265 def getLastArg(self, option):
266 return self.lastArgs.get(option)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000267
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000268 def getInputString(self, index, offset=0):
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000269 # Source 0 is argv.
270 if index.sourceId == 0:
271 return self.argv[index.pos + offset]
272
273 # Source 1 is synthetic argv.
274 if index.sourceId == 1:
275 return self.syntheticArgv[index.pos + offset]
276
277 raise RuntimeError,'Unknown source ID for index.'
278
Daniel Dunbar0fe5a4f2009-01-11 22:42:24 +0000279 def addLastArg(self, output, option):
280 """addLastArgs - Extend the given output vector with the last
281 instance of a given option."""
282 arg = self.getLastArg(option)
283 if arg:
284 output.extend(self.render(arg))
285
286 def addAllArgs(self, output, option):
287 """addAllArgs - Extend the given output vector with all
288 instances of a given option."""
289 for arg in self.getArgs(option):
290 output.extend(self.render(arg))
291
292 def addAllArgsTranslated(self, output, option, translation):
293 """addAllArgsTranslated - Extend the given output vector with
294 all instances of a given option, rendered as separate
295 arguments with the actual option name translated to a user
296 specified string. For example, '-foox' will be render as
297 ['-bar', 'x'] if '-foo' was the option and '-bar' was the
298 translation.
299
300 This routine expects that the option can only yield ValueArg
301 instances."""
302 for arg in self.getArgs(option):
303 assert isinstance(arg, ValueArg)
304 output.append(translation)
305 output.append(self.getValue(arg))
306
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000307 def makeIndex(self, *strings):
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000308 pos = len(self.syntheticArgv)
309 self.syntheticArgv.extend(strings)
310 return InputIndex(1, pos)
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000311
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000312 def makeFlagArg(self, option):
313 return Arg(self.makeIndex(option.name),
314 option)
315
316 def makeInputArg(self, string):
317 return PositionalArg(self.makeIndex(string),
318 self.parser.inputOption)
319
320 def makeUnknownArg(self, string):
321 return PositionalArg(self.makeIndex(string),
322 self.parser.unknownOption)
323
324 def makeSeparateArg(self, string, option):
325 return SeparateValueArg(self.makeIndex(option.name, string),
326 option)
327
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000328 # Support use as a simple arg list.
329
330 def __iter__(self):
331 return iter(self.args)
332
333 def append(self, arg):
334 self.args.append(arg)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000335 self.lastArgs[arg.opt] = arg
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000336
337 # Forwarding methods.
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000338 #
339 # FIXME: Clean this up once restructuring is done.
340
341 def render(self, arg):
342 return arg.render(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000343
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000344 def renderAsInput(self, arg):
345 return arg.renderAsInput(self)
346
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000347 def getValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000348 return arg.getValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000349
350 def getValues(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000351 return arg.getValues(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000352
353 def getSeparateValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000354 return arg.getSeparateValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000355
356 def getJoinedValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000357 return arg.getJoinedValue(self)
Daniel Dunbar1dd2ada2009-01-06 06:32:49 +0000358
359###
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000360
Daniel Dunbara5677512009-01-05 19:53:30 +0000361class OptionParser:
362 def __init__(self):
363 self.options = []
Daniel Dunbar5039f212009-01-06 02:30:10 +0000364 self.inputOption = InputOption()
365 self.unknownOption = UnknownOption()
366
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000367 # Driver driver options
368 self.archOption = self.addOption(SeparateOption('-arch'))
369
370 # Misc driver options
371 self.addOption(FlagOption('-pass-exit-codes'))
372 self.addOption(FlagOption('--help'))
373 self.addOption(FlagOption('--target-help'))
374
375 self.dumpspecsOption = self.addOption(FlagOption('-dumpspecs'))
376 self.dumpversionOption = self.addOption(FlagOption('-dumpversion'))
377 self.dumpmachineOption = self.addOption(FlagOption('-dumpmachine'))
378 self.printSearchDirsOption = self.addOption(FlagOption('-print-search-dirs'))
379 self.printLibgccFilenameOption = self.addOption(FlagOption('-print-libgcc-file-name'))
380 # FIXME: Hrm, where does this come from? It isn't always true that
381 # we take both - and --. For example, gcc --S ... ends up sending
382 # -fS to cc1. Investigate.
383 #
384 # FIXME: Need to implement some form of alias support inside
385 # getLastOption to handle this.
386 self.printLibgccFileNameOption2 = self.addOption(FlagOption('--print-libgcc-file-name'))
387 self.printFileNameOption = self.addOption(JoinedOption('-print-file-name='))
388 self.printProgNameOption = self.addOption(JoinedOption('-print-prog-name='))
389 self.printProgNameOption2 = self.addOption(JoinedOption('--print-prog-name='))
390 self.printMultiDirectoryOption = self.addOption(FlagOption('-print-multi-directory'))
391 self.printMultiLibOption = self.addOption(FlagOption('-print-multi-lib'))
392 self.addOption(FlagOption('-print-multi-os-directory'))
393
394 # Hmmm, who really takes this?
395 self.addOption(FlagOption('--version'))
396
397 # Pipeline control
398 self.hashHashHashOption = self.addOption(FlagOption('-###'))
399 self.EOption = self.addOption(FlagOption('-E'))
400 self.SOption = self.addOption(FlagOption('-S'))
401 self.cOption = self.addOption(FlagOption('-c'))
402 self.combineOption = self.addOption(FlagOption('-combine'))
403 self.noIntegratedCPPOption = self.addOption(FlagOption('-no-integrated-cpp'))
404 self.pipeOption = self.addOption(FlagOption('-pipe'))
405 self.saveTempsOption = self.addOption(FlagOption('-save-temps'))
406 self.saveTempsOption2 = self.addOption(FlagOption('--save-temps'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000407 # FIXME: Error out if this is used.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000408 self.addOption(JoinedOption('-specs='))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000409 # FIXME: Implement.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000410 self.addOption(FlagOption('-time'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000411 # FIXME: Implement.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000412 self.addOption(FlagOption('-v'))
413
414 # Input/output stuff
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000415 self.oOption = self.addOption(JoinedOrSeparateOption('-o', noOptAsInput=True))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000416 self.xOption = self.addOption(JoinedOrSeparateOption('-x'))
417
Daniel Dunbaree8cc262009-01-12 02:24:21 +0000418 self.ObjCOption = self.addOption(FlagOption('-ObjC'))
419 self.ObjCXXOption = self.addOption(FlagOption('-ObjC++'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000420
421 # FIXME: Weird, gcc claims this here in help but I'm not sure why;
422 # perhaps interaction with preprocessor? Investigate.
423 self.addOption(JoinedOption('-std='))
424 self.addOption(JoinedOrSeparateOption('--sysroot'))
425
426 # Version control
427 self.addOption(JoinedOrSeparateOption('-B'))
428 self.addOption(JoinedOrSeparateOption('-V'))
429 self.addOption(JoinedOrSeparateOption('-b'))
430
431 # Blanket pass-through options.
432
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000433 self.addOption(CommaJoinedOption('-Wa,'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000434 self.addOption(SeparateOption('-Xassembler'))
435
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000436 self.addOption(CommaJoinedOption('-Wp,'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000437 self.addOption(SeparateOption('-Xpreprocessor'))
438
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000439 self.addOption(CommaJoinedOption('-Wl,', isLinkerInput=True))
440 self.addOption(SeparateOption('-Xlinker', isLinkerInput=True, noOptAsInput=True))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000441
442 ####
443 # Bring on the random garbage.
444
445 self.addOption(FlagOption('-MD'))
446 self.addOption(FlagOption('-MP'))
447 self.addOption(FlagOption('-MM'))
448 self.addOption(JoinedOrSeparateOption('-MF'))
449 self.addOption(JoinedOrSeparateOption('-MT'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000450 self.MachOption = self.addOption(FlagOption('-Mach'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000451 self.addOption(FlagOption('-undef'))
452
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000453 self.wOption = self.addOption(FlagOption('-w'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000454 self.addOption(JoinedOrSeparateOption('-allowable_client'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000455 self.client_nameOption = self.addOption(JoinedOrSeparateOption('-client_name'))
456 self.compatibility_versionOption = self.addOption(JoinedOrSeparateOption('-compatibility_version'))
457 self.current_versionOption = self.addOption(JoinedOrSeparateOption('-current_version'))
458 self.dylinkerOption = self.addOption(FlagOption('-dylinker'))
459 self.dylinker_install_nameOption = self.addOption(JoinedOrSeparateOption('-dylinker_install_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000460 self.addOption(JoinedOrSeparateOption('-exported_symbols_list'))
461 self.addOption(JoinedOrSeparateOption('-idirafter'))
462 self.addOption(JoinedOrSeparateOption('-iquote'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000463 self.isysrootOption = self.addOption(JoinedOrSeparateOption('-isysroot'))
464 self.keep_private_externsOption = self.addOption(JoinedOrSeparateOption('-keep_private_externs'))
465 self.private_bundleOption = self.addOption(FlagOption('-private_bundle'))
466 self.seg1addrOption = self.addOption(JoinedOrSeparateOption('-seg1addr'))
467 self.segprotOption = self.addOption(JoinedOrSeparateOption('-segprot'))
468 self.sub_libraryOption = self.addOption(JoinedOrSeparateOption('-sub_library'))
469 self.sub_umbrellaOption = self.addOption(JoinedOrSeparateOption('-sub_umbrella'))
470 self.umbrellaOption = self.addOption(JoinedOrSeparateOption('-umbrella'))
471 self.undefinedOption = self.addOption(JoinedOrSeparateOption('-undefined'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000472 self.addOption(JoinedOrSeparateOption('-unexported_symbols_list'))
473 self.addOption(JoinedOrSeparateOption('-weak_framework'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000474 self.headerpad_max_install_namesOption = self.addOption(JoinedOption('-headerpad_max_install_names'))
475 self.twolevel_namespaceOption = self.addOption(FlagOption('-twolevel_namespace'))
476 self.twolevel_namespace_hintsOption = self.addOption(FlagOption('-twolevel_namespace_hints'))
477 self.prebindOption = self.addOption(FlagOption('-prebind'))
478 self.noprebindOption = self.addOption(FlagOption('-noprebind'))
479 self.nofixprebindingOption = self.addOption(FlagOption('-nofixprebinding'))
480 self.prebind_all_twolevel_modulesOption = self.addOption(FlagOption('-prebind_all_twolevel_modules'))
481 self.read_only_relocsOption = self.addOption(SeparateOption('-read_only_relocs'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000482 self.addOption(FlagOption('-single_module'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000483 self.nomultidefsOption = self.addOption(FlagOption('-nomultidefs'))
484 self.nostartfilesOption = self.addOption(FlagOption('-nostartfiles'))
485 self.nodefaultlibsOption = self.addOption(FlagOption('-nodefaultlibs'))
486 self.nostdlibOption = self.addOption(FlagOption('-nostdlib'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000487 self.addOption(FlagOption('-nostdinc'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000488 self.objectOption = self.addOption(FlagOption('-object'))
489 self.preloadOption = self.addOption(FlagOption('-preload'))
490 self.staticOption = self.addOption(FlagOption('-static'))
491 self.pagezero_sizeOption = self.addOption(FlagOption('-pagezero_size'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000492 self.addOption(FlagOption('-shared'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000493 self.staticLibgccOption = self.addOption(FlagOption('-static-libgcc'))
494 self.sharedLibgccOption = self.addOption(FlagOption('-shared-libgcc'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000495 self.addOption(FlagOption('-C'))
496 self.addOption(FlagOption('-CC'))
497 self.addOption(FlagOption('-R'))
498 self.addOption(FlagOption('-P'))
499 self.addOption(FlagOption('-all_load'))
500 self.addOption(FlagOption('--constant-cfstrings'))
501 self.addOption(FlagOption('-traditional'))
502 self.addOption(FlagOption('--traditional'))
503 self.addOption(FlagOption('-no_dead_strip_inits_and_terms'))
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000504 self.addOption(JoinedOption('-weak-l', isLinkerInput=True))
505 self.addOption(SeparateOption('-weak_framework', isLinkerInput=True))
506 self.addOption(SeparateOption('-weak_library', isLinkerInput=True))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000507 self.whyloadOption = self.addOption(FlagOption('-whyload'))
508 self.whatsloadedOption = self.addOption(FlagOption('-whatsloaded'))
509 self.sectalignOption = self.addOption(MultiArgOption('-sectalign', numArgs=3))
510 self.sectobjectsymbolsOption = self.addOption(MultiArgOption('-sectobjectsymbols', numArgs=2))
511 self.segcreateOption = self.addOption(MultiArgOption('-segcreate', numArgs=3))
512 self.segs_read_Option = self.addOption(JoinedOption('-segs_read_'))
513 self.seglinkeditOption = self.addOption(FlagOption('-seglinkedit'))
514 self.noseglinkeditOption = self.addOption(FlagOption('-noseglinkedit'))
515 self.sectcreateOption = self.addOption(MultiArgOption('-sectcreate', numArgs=3))
516 self.sectorderOption = self.addOption(MultiArgOption('-sectorder', numArgs=3))
517 self.Zall_loadOption = self.addOption(FlagOption('-Zall_load'))
518 self.Zallowable_clientOption = self.addOption(SeparateOption('-Zallowable_client'))
519 self.Zbind_at_loadOption = self.addOption(SeparateOption('-Zbind_at_load'))
520 self.ZbundleOption = self.addOption(FlagOption('-Zbundle'))
521 self.Zbundle_loaderOption = self.addOption(JoinedOrSeparateOption('-Zbundle_loader'))
522 self.Zdead_stripOption = self.addOption(FlagOption('-Zdead_strip'))
523 self.Zdylib_fileOption = self.addOption(JoinedOrSeparateOption('-Zdylib_file'))
524 self.ZdynamicOption = self.addOption(FlagOption('-Zdynamic'))
525 self.ZdynamiclibOption = self.addOption(FlagOption('-Zdynamiclib'))
526 self.Zexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zexported_symbols_list'))
527 self.Zflat_namespaceOption = self.addOption(FlagOption('-Zflat_namespace'))
528 self.Zfn_seg_addr_table_filenameOption = self.addOption(JoinedOrSeparateOption('-Zfn_seg_addr_table_filename'))
529 self.Zforce_cpusubtype_ALLOption = self.addOption(FlagOption('-Zforce_cpusubtype_ALL'))
530 self.Zforce_flat_namespaceOption = self.addOption(FlagOption('-Zforce_flat_namespace'))
531 self.Zimage_baseOption = self.addOption(FlagOption('-Zimage_base'))
532 self.ZinitOption = self.addOption(JoinedOrSeparateOption('-Zinit'))
533 self.Zmulti_moduleOption = self.addOption(FlagOption('-Zmulti_module'))
534 self.Zmultiply_definedOption = self.addOption(JoinedOrSeparateOption('-Zmultiply_defined'))
535 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
536 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
537 self.Zno_dead_strip_inits_and_termsOption = self.addOption(FlagOption('-Zno_dead_strip_inits_and_terms'))
538 self.Zseg_addr_tableOption = self.addOption(JoinedOrSeparateOption('-Zseg_addr_table'))
539 self.ZsegaddrOption = self.addOption(JoinedOrSeparateOption('-Zsegaddr'))
540 self.Zsegs_read_only_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_only_addr'))
541 self.Zsegs_read_write_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_write_addr'))
542 self.Zsingle_moduleOption = self.addOption(FlagOption('-Zsingle_module'))
Daniel Dunbar0fe5a4f2009-01-11 22:42:24 +0000543 self.ZumbrellaOption = self.addOption(JoinedOrSeparateOption('-Zumbrella'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000544 self.Zunexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zunexported_symbols_list'))
545 self.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000546
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000547 self.addOption(SeparateOption('-filelist', isLinkerInput=True))
548 self.addOption(SeparateOption('-framework', isLinkerInput=True))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000549 # FIXME: Alias.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000550 self.addOption(SeparateOption('-install_name'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000551 self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000552 self.addOption(SeparateOption('-seg_addr_table'))
553 self.addOption(SeparateOption('-seg_addr_table_filename'))
554
555 # Where are these coming from? I can't find them...
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000556 self.eOption = self.addOption(JoinedOrSeparateOption('-e'))
557 self.rOption = self.addOption(JoinedOrSeparateOption('-r'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000558
559 # Is this actually declared anywhere? I can only find it in a
560 # spec. :(
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000561 self.pgOption = self.addOption(FlagOption('-pg'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000562
563 doNotReallySupport = 1
564 if doNotReallySupport:
565 # Archaic gcc option.
566 self.addOption(FlagOption('-cpp-precomp'))
567 self.addOption(FlagOption('-no-cpp-precomp'))
568
569 # C options for testing
570
571 self.addOption(JoinedOrSeparateOption('-include'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000572 self.AOption = self.addOption(SeparateOption('-A'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000573 self.addOption(JoinedOrSeparateOption('-D'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000574 self.FOption = self.addOption(JoinedOrSeparateOption('-F'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000575 self.addOption(JoinedOrSeparateOption('-I'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000576 self.LOption = self.addOption(JoinedOrSeparateOption('-L'))
577 self.TOption = self.addOption(JoinedOrSeparateOption('-T'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000578 self.addOption(JoinedOrSeparateOption('-U'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000579 self.ZOption = self.addOption(JoinedOrSeparateOption('-Z'))
580
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000581 self.addOption(JoinedOrSeparateOption('-l', isLinkerInput=True))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000582 self.uOption = self.addOption(JoinedOrSeparateOption('-u'))
583 self.tOption = self.addOption(JoinedOrSeparateOption('-t'))
584 self.yOption = self.addOption(JoinedOption('-y'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000585
586 # FIXME: What is going on here? '-X' goes to linker, and -X ... goes nowhere?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000587 self.XOption = self.addOption(FlagOption('-X'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000588 # Not exactly sure how to decompose this. I split out -Xarch_
589 # because we need to recognize that in the driver driver part.
590 # FIXME: Man, this is lame it needs its own option.
591 self.XarchOption = self.addOption(JoinedAndSeparateOption('-Xarch_'))
592 self.addOption(JoinedOption('-X'))
593
594 # The driver needs to know about this flag.
595 self.syntaxOnlyOption = self.addOption(FlagOption('-fsyntax-only'))
596
597 # FIXME: Wrong?
598 # FIXME: What to do about the ambiguity of options like
599 # -dumpspecs? How is this handled in gcc?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000600 # FIXME: Naming convention.
601 self.dOption = self.addOption(FlagOption('-d'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000602 self.addOption(JoinedOption('-d'))
603 self.addOption(JoinedOption('-g'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000604
605 self.f_exceptionsOption = self.addOption(FlagOption('-fexceptions'))
Daniel Dunbaree8cc262009-01-12 02:24:21 +0000606 self.f_objcOption = self.addOption(FlagOption('-fobjc'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000607 self.f_openmpOption = self.addOption(FlagOption('-fopenmp'))
608 self.f_gnuRuntimeOption = self.addOption(FlagOption('-fgnu-runtime'))
609 self.f_nestedFunctionsOption = self.addOption(FlagOption('-fnested-functions'))
610 self.f_pieOption = self.addOption(FlagOption('-fpie'))
611 self.f_profileArcsOption = self.addOption(FlagOption('-fprofile-arcs'))
612 self.f_profileGenerateOption = self.addOption(FlagOption('-fprofile-generate'))
613 self.f_createProfileOption = self.addOption(FlagOption('-fcreate-profile'))
614 self.coverageOption = self.addOption(FlagOption('-coverage'))
615 self.coverageOption2 = self.addOption(FlagOption('--coverage'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000616 self.addOption(JoinedOption('-f'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000617
618 self.m_32Option = self.addOption(FlagOption('-m32'))
619 self.m_64Option = self.addOption(FlagOption('-m64'))
620 self.m_iphoneosVersionMinOption = self.addOption(JoinedOption('-miphoneos-version-min='))
621 self.m_macosxVersionMinOption = self.addOption(JoinedOption('-mmacosx-version-min='))
622
623 # Ugh. Need to disambiguate our naming convetion. -m x goes to
624 # the linker sometimes, wheres -mxxxx is used for a variety of
625 # other things.
626 self.mOption = self.addOption(SeparateOption('-m'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000627 self.addOption(JoinedOption('-m'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000628
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000629 self.addOption(JoinedOption('-i'))
630 self.addOption(JoinedOption('-O'))
631 self.addOption(JoinedOption('-W'))
632 # FIXME: Weird. This option isn't really separate, --param=a=b
633 # works. An alias somewhere?
634 self.addOption(SeparateOption('--param'))
635
636 # FIXME: What is this? Seems to do something on Linux. I think
637 # only one is valid, but have a log that uses both.
638 self.addOption(FlagOption('-pthread'))
639 self.addOption(FlagOption('-pthreads'))
640
Daniel Dunbara5677512009-01-05 19:53:30 +0000641 def addOption(self, opt):
642 self.options.append(opt)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000643 return opt
Daniel Dunbara5677512009-01-05 19:53:30 +0000644
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000645 def parseArgs(self, argv):
Daniel Dunbara5677512009-01-05 19:53:30 +0000646 """
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000647 parseArgs([str]) -> ArgList
Daniel Dunbara5677512009-01-05 19:53:30 +0000648
649 Parse command line into individual option instances.
650 """
651
652 iargs = enumerate(argv)
653 it = iter(iargs)
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000654 args = ArgList(self, argv)
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000655 for pos,a in it:
656 i = InputIndex(0, pos)
Daniel Dunbara5677512009-01-05 19:53:30 +0000657 # FIXME: Handle '@'
658 if not a:
659 # gcc's handling of empty arguments doesn't make
660 # sense, but this is not a common use case. :)
661 #
662 # We just ignore them here (note that other things may
663 # still take them as arguments).
664 pass
665 elif a[0] == '-' and a != '-':
666 args.append(self.lookupOptForArg(i, a, it))
667 else:
Daniel Dunbar5039f212009-01-06 02:30:10 +0000668 args.append(PositionalArg(i, self.inputOption))
Daniel Dunbara5677512009-01-05 19:53:30 +0000669 return args
670
Daniel Dunbar5039f212009-01-06 02:30:10 +0000671 def lookupOptForArg(self, i, string, it):
672 for o in self.options:
673 arg = o.accept(i, string, it)
674 if arg is not None:
675 return arg
676 return PositionalArg(i, self.unknownOption)