blob: f98b7c81de94c382faa8c6ae08b368fb8eaf8f7d [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 Dunbar996ce962009-01-12 07:40:25 +0000149 def getValues(self, args):
150 return [self.getValue(args)]
151
Daniel Dunbar5039f212009-01-06 02:30:10 +0000152class PositionalArg(ValueArg):
153 """PositionalArg - A simple positional argument."""
Daniel Dunbara5677512009-01-05 19:53:30 +0000154
155 def getValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000156 return args.getInputString(self.index)
Daniel Dunbara5677512009-01-05 19:53:30 +0000157
158 def render(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000159 return [args.getInputString(self.index)]
Daniel Dunbara5677512009-01-05 19:53:30 +0000160
161class JoinedValueArg(ValueArg):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000162 """JoinedValueArg - A single value argument where the value is
163 joined (suffixed) to the option."""
164
Daniel Dunbara5677512009-01-05 19:53:30 +0000165 def getValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000166 return args.getInputString(self.index)[len(self.opt.name):]
Daniel Dunbara5677512009-01-05 19:53:30 +0000167
Daniel Dunbara5677512009-01-05 19:53:30 +0000168 def render(self, args):
169 return [self.opt.name + self.getValue(args)]
170
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000171 def renderAsInput(self, args):
172 if self.opt.noOptAsInput:
173 return [self.getValue(args)]
174 return self.render(args)
175
Daniel Dunbara5677512009-01-05 19:53:30 +0000176class SeparateValueArg(ValueArg):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000177 """SeparateValueArg - A single value argument where the value
178 follows the option in the argument vector."""
179
Daniel Dunbara5677512009-01-05 19:53:30 +0000180 def getValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000181 return args.getInputString(self.index, offset=1)
Daniel Dunbara5677512009-01-05 19:53:30 +0000182
Daniel Dunbara5677512009-01-05 19:53:30 +0000183 def render(self, args):
184 return [self.opt.name, self.getValue(args)]
185
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000186 def renderAsInput(self, args):
187 if self.opt.noOptAsInput:
188 return [self.getValue(args)]
189 return self.render(args)
190
Daniel Dunbara5677512009-01-05 19:53:30 +0000191class MultipleValuesArg(Arg):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000192 """MultipleValuesArg - An argument with multiple values which
193 follow the option in the argument vector."""
194
195 # FIXME: Should we unify this with SeparateValueArg?
196
Daniel Dunbara5677512009-01-05 19:53:30 +0000197 def getValues(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000198 return [args.getInputString(self.index, offset=1+i)
199 for i in range(self.opt.numArgs)]
Daniel Dunbara5677512009-01-05 19:53:30 +0000200
Daniel Dunbara5677512009-01-05 19:53:30 +0000201 def render(self, args):
202 return [self.opt.name] + self.getValues(args)
203
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000204class CommaJoinedValuesArg(Arg):
205 """CommaJoinedValuesArg - An argument with multiple values joined
206 by commas and joined (suffixed) to the option.
207
208 The key point of this arg is that it renders its values into
209 separate arguments, which allows it to be used as a generic
210 mechanism for passing arguments through to tools."""
211
212 def getValues(self, args):
213 return args.getInputString(self.index)[len(self.opt.name):].split(',')
214
215 def render(self, args):
216 return [self.opt.name + ','.join(self.getValues(args))]
217
218 def renderAsInput(self, args):
219 return self.getValues(args)
220
Daniel Dunbara5677512009-01-05 19:53:30 +0000221# FIXME: Man, this is lame. It is only used by -Xarch. Maybe easier to
222# just special case?
223class JoinedAndSeparateValuesArg(Arg):
224 """JoinedAndSeparateValuesArg - An argument with both joined and
225 separate values."""
226
227 def getJoinedValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000228 return args.getInputString(self.index)[len(self.opt.name):]
Daniel Dunbara5677512009-01-05 19:53:30 +0000229
230 def getSeparateValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000231 return args.getInputString(self.index, offset=1)
Daniel Dunbara5677512009-01-05 19:53:30 +0000232
233 def render(self, args):
234 return ([self.opt.name + self.getJoinedValue(args)] +
235 [self.getSeparateValue(args)])
236
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000237###
238
239class InputIndex:
240 def __init__(self, sourceId, pos):
241 self.sourceId = sourceId
242 self.pos = pos
243
244 def __repr__(self):
245 return 'InputIndex(%d, %d)' % (self.sourceId, self.pos)
246
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000247class ArgList:
Daniel Dunbar5039f212009-01-06 02:30:10 +0000248 """ArgList - Collect an input argument vector along with a set of parsed Args
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000249 and supporting information."""
250
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000251 def __init__(self, parser, argv):
252 self.parser = parser
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000253 self.argv = list(argv)
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000254 self.syntheticArgv = []
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000255 self.lastArgs = {}
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000256 self.args = []
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000257
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000258 def getArgs(self, option):
259 # FIXME: How efficient do we want to make this. One reasonable
260 # solution would be to embed a linked list inside each arg and
261 # automatically chain them (with pointers to head and
262 # tail). This gives us efficient access to the (first, last,
263 # all) arg(s) with little overhead.
264 for arg in self.args:
265 if arg.opt is option:
266 yield arg
267
Daniel Dunbar996ce962009-01-12 07:40:25 +0000268 def getArgs2(self, optionA, optionB):
269 """getArgs2 - Iterate over all arguments for two options, in
270 the order they were specified."""
271 # As long as getArgs is efficient, we can easily make this
272 # efficient by iterating both at once and always taking the
273 # earlier arg.
274 for arg in self.args:
275 if arg.opt in (optionA, optionB):
276 yield arg
277
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000278 def getArgs3(self, optionA, optionB, optionC):
279 """getArgs3 - Iterate over all arguments for three options, in
280 the order they were specified."""
281 for arg in self.args:
282 if arg.opt in (optionA, optionB, optionC):
283 yield arg
284
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000285 def getLastArg(self, option):
286 return self.lastArgs.get(option)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000287
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000288 def getInputString(self, index, offset=0):
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000289 # Source 0 is argv.
290 if index.sourceId == 0:
291 return self.argv[index.pos + offset]
292
293 # Source 1 is synthetic argv.
294 if index.sourceId == 1:
295 return self.syntheticArgv[index.pos + offset]
296
297 raise RuntimeError,'Unknown source ID for index.'
298
Daniel Dunbar0fe5a4f2009-01-11 22:42:24 +0000299 def addLastArg(self, output, option):
300 """addLastArgs - Extend the given output vector with the last
301 instance of a given option."""
302 arg = self.getLastArg(option)
303 if arg:
304 output.extend(self.render(arg))
305
306 def addAllArgs(self, output, option):
307 """addAllArgs - Extend the given output vector with all
308 instances of a given option."""
309 for arg in self.getArgs(option):
310 output.extend(self.render(arg))
311
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000312 def addAllArgs2(self, output, optionA, optionB):
313 """addAllArgs2 - Extend the given output vector with all
314 instances of two given option, with relative order preserved."""
315 for arg in self.getArgs2(optionA, optionB):
316 output.extend(self.render(arg))
317
318 def addAllArgs3(self, output, optionA, optionB, optionC):
319 """addAllArgs3 - Extend the given output vector with all
320 instances of three given option, with relative order preserved."""
321 for arg in self.getArgs3(optionA, optionB, optionC):
322 output.extend(self.render(arg))
323
Daniel Dunbar0fe5a4f2009-01-11 22:42:24 +0000324 def addAllArgsTranslated(self, output, option, translation):
325 """addAllArgsTranslated - Extend the given output vector with
326 all instances of a given option, rendered as separate
327 arguments with the actual option name translated to a user
328 specified string. For example, '-foox' will be render as
329 ['-bar', 'x'] if '-foo' was the option and '-bar' was the
330 translation.
331
332 This routine expects that the option can only yield ValueArg
333 instances."""
334 for arg in self.getArgs(option):
335 assert isinstance(arg, ValueArg)
336 output.append(translation)
337 output.append(self.getValue(arg))
338
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000339 def makeIndex(self, *strings):
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000340 pos = len(self.syntheticArgv)
341 self.syntheticArgv.extend(strings)
342 return InputIndex(1, pos)
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000343
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000344 def makeFlagArg(self, option):
345 return Arg(self.makeIndex(option.name),
346 option)
347
348 def makeInputArg(self, string):
349 return PositionalArg(self.makeIndex(string),
350 self.parser.inputOption)
351
352 def makeUnknownArg(self, string):
353 return PositionalArg(self.makeIndex(string),
354 self.parser.unknownOption)
355
356 def makeSeparateArg(self, string, option):
357 return SeparateValueArg(self.makeIndex(option.name, string),
358 option)
359
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000360 # Support use as a simple arg list.
361
362 def __iter__(self):
363 return iter(self.args)
364
365 def append(self, arg):
366 self.args.append(arg)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000367 self.lastArgs[arg.opt] = arg
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000368
369 # Forwarding methods.
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000370 #
371 # FIXME: Clean this up once restructuring is done.
372
373 def render(self, arg):
374 return arg.render(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000375
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000376 def renderAsInput(self, arg):
377 return arg.renderAsInput(self)
378
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000379 def getValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000380 return arg.getValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000381
382 def getValues(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000383 return arg.getValues(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000384
385 def getSeparateValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000386 return arg.getSeparateValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000387
388 def getJoinedValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000389 return arg.getJoinedValue(self)
Daniel Dunbar1dd2ada2009-01-06 06:32:49 +0000390
391###
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000392
Daniel Dunbara5677512009-01-05 19:53:30 +0000393class OptionParser:
394 def __init__(self):
395 self.options = []
Daniel Dunbar5039f212009-01-06 02:30:10 +0000396 self.inputOption = InputOption()
397 self.unknownOption = UnknownOption()
398
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000399 # Driver driver options
400 self.archOption = self.addOption(SeparateOption('-arch'))
401
402 # Misc driver options
403 self.addOption(FlagOption('-pass-exit-codes'))
404 self.addOption(FlagOption('--help'))
405 self.addOption(FlagOption('--target-help'))
406
407 self.dumpspecsOption = self.addOption(FlagOption('-dumpspecs'))
408 self.dumpversionOption = self.addOption(FlagOption('-dumpversion'))
409 self.dumpmachineOption = self.addOption(FlagOption('-dumpmachine'))
410 self.printSearchDirsOption = self.addOption(FlagOption('-print-search-dirs'))
411 self.printLibgccFilenameOption = self.addOption(FlagOption('-print-libgcc-file-name'))
412 # FIXME: Hrm, where does this come from? It isn't always true that
413 # we take both - and --. For example, gcc --S ... ends up sending
414 # -fS to cc1. Investigate.
415 #
416 # FIXME: Need to implement some form of alias support inside
417 # getLastOption to handle this.
418 self.printLibgccFileNameOption2 = self.addOption(FlagOption('--print-libgcc-file-name'))
419 self.printFileNameOption = self.addOption(JoinedOption('-print-file-name='))
420 self.printProgNameOption = self.addOption(JoinedOption('-print-prog-name='))
421 self.printProgNameOption2 = self.addOption(JoinedOption('--print-prog-name='))
422 self.printMultiDirectoryOption = self.addOption(FlagOption('-print-multi-directory'))
423 self.printMultiLibOption = self.addOption(FlagOption('-print-multi-lib'))
424 self.addOption(FlagOption('-print-multi-os-directory'))
425
426 # Hmmm, who really takes this?
427 self.addOption(FlagOption('--version'))
428
429 # Pipeline control
430 self.hashHashHashOption = self.addOption(FlagOption('-###'))
431 self.EOption = self.addOption(FlagOption('-E'))
432 self.SOption = self.addOption(FlagOption('-S'))
433 self.cOption = self.addOption(FlagOption('-c'))
434 self.combineOption = self.addOption(FlagOption('-combine'))
435 self.noIntegratedCPPOption = self.addOption(FlagOption('-no-integrated-cpp'))
436 self.pipeOption = self.addOption(FlagOption('-pipe'))
437 self.saveTempsOption = self.addOption(FlagOption('-save-temps'))
438 self.saveTempsOption2 = self.addOption(FlagOption('--save-temps'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000439 # FIXME: Error out if this is used.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000440 self.addOption(JoinedOption('-specs='))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000441 # FIXME: Implement.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000442 self.addOption(FlagOption('-time'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000443 # FIXME: Implement.
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000444 self.vOption = self.addOption(FlagOption('-v'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000445
446 # Input/output stuff
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000447 self.oOption = self.addOption(JoinedOrSeparateOption('-o', noOptAsInput=True))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000448 self.xOption = self.addOption(JoinedOrSeparateOption('-x'))
449
Daniel Dunbaree8cc262009-01-12 02:24:21 +0000450 self.ObjCOption = self.addOption(FlagOption('-ObjC'))
451 self.ObjCXXOption = self.addOption(FlagOption('-ObjC++'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000452
453 # FIXME: Weird, gcc claims this here in help but I'm not sure why;
454 # perhaps interaction with preprocessor? Investigate.
Daniel Dunbar816dd502009-01-12 17:53:19 +0000455
456 # FIXME: This is broken in Darwin cc1, it wants std* and this
457 # is std=. May need an option group for this as well.
458 self.stdOption = self.addOption(JoinedOption('-std='))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000459 self.addOption(JoinedOrSeparateOption('--sysroot'))
460
461 # Version control
462 self.addOption(JoinedOrSeparateOption('-B'))
463 self.addOption(JoinedOrSeparateOption('-V'))
464 self.addOption(JoinedOrSeparateOption('-b'))
465
466 # Blanket pass-through options.
467
Daniel Dunbar996ce962009-01-12 07:40:25 +0000468 self.WaOption = self.addOption(CommaJoinedOption('-Wa,'))
469 self.XassemblerOption = self.addOption(SeparateOption('-Xassembler'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000470
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000471 self.addOption(CommaJoinedOption('-Wp,'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000472 self.addOption(SeparateOption('-Xpreprocessor'))
473
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000474 self.addOption(CommaJoinedOption('-Wl,', isLinkerInput=True))
475 self.addOption(SeparateOption('-Xlinker', isLinkerInput=True, noOptAsInput=True))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000476
477 ####
478 # Bring on the random garbage.
479
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000480 self.MOption = self.addOption(FlagOption('-M'))
481 self.MDOption = self.addOption(FlagOption('-MD'))
482 self.MGOption = self.addOption(FlagOption('-MG'))
483 self.MMDOption = self.addOption(FlagOption('-MMD'))
484 self.MPOption = self.addOption(FlagOption('-MP'))
485 self.MMOption = self.addOption(FlagOption('-MM'))
486 self.MFOption = self.addOption(JoinedOrSeparateOption('-MF'))
487 self.MTOption = self.addOption(JoinedOrSeparateOption('-MT'))
488 self.MQOption = self.addOption(JoinedOrSeparateOption('-MQ'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000489 self.MachOption = self.addOption(FlagOption('-Mach'))
Daniel Dunbar816dd502009-01-12 17:53:19 +0000490 self.undefOption = self.addOption(FlagOption('-undef'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000491
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000492 self.wOption = self.addOption(FlagOption('-w'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000493 self.addOption(JoinedOrSeparateOption('-allowable_client'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000494 self.client_nameOption = self.addOption(JoinedOrSeparateOption('-client_name'))
495 self.compatibility_versionOption = self.addOption(JoinedOrSeparateOption('-compatibility_version'))
496 self.current_versionOption = self.addOption(JoinedOrSeparateOption('-current_version'))
497 self.dylinkerOption = self.addOption(FlagOption('-dylinker'))
498 self.dylinker_install_nameOption = self.addOption(JoinedOrSeparateOption('-dylinker_install_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000499 self.addOption(JoinedOrSeparateOption('-exported_symbols_list'))
500 self.addOption(JoinedOrSeparateOption('-idirafter'))
501 self.addOption(JoinedOrSeparateOption('-iquote'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000502 self.isysrootOption = self.addOption(JoinedOrSeparateOption('-isysroot'))
503 self.keep_private_externsOption = self.addOption(JoinedOrSeparateOption('-keep_private_externs'))
504 self.private_bundleOption = self.addOption(FlagOption('-private_bundle'))
505 self.seg1addrOption = self.addOption(JoinedOrSeparateOption('-seg1addr'))
506 self.segprotOption = self.addOption(JoinedOrSeparateOption('-segprot'))
507 self.sub_libraryOption = self.addOption(JoinedOrSeparateOption('-sub_library'))
508 self.sub_umbrellaOption = self.addOption(JoinedOrSeparateOption('-sub_umbrella'))
509 self.umbrellaOption = self.addOption(JoinedOrSeparateOption('-umbrella'))
510 self.undefinedOption = self.addOption(JoinedOrSeparateOption('-undefined'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000511 self.addOption(JoinedOrSeparateOption('-unexported_symbols_list'))
512 self.addOption(JoinedOrSeparateOption('-weak_framework'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000513 self.headerpad_max_install_namesOption = self.addOption(JoinedOption('-headerpad_max_install_names'))
514 self.twolevel_namespaceOption = self.addOption(FlagOption('-twolevel_namespace'))
515 self.twolevel_namespace_hintsOption = self.addOption(FlagOption('-twolevel_namespace_hints'))
516 self.prebindOption = self.addOption(FlagOption('-prebind'))
517 self.noprebindOption = self.addOption(FlagOption('-noprebind'))
518 self.nofixprebindingOption = self.addOption(FlagOption('-nofixprebinding'))
519 self.prebind_all_twolevel_modulesOption = self.addOption(FlagOption('-prebind_all_twolevel_modules'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000520 self.remapOption = self.addOption(FlagOption('-remap'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000521 self.read_only_relocsOption = self.addOption(SeparateOption('-read_only_relocs'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000522 self.addOption(FlagOption('-single_module'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000523 self.nomultidefsOption = self.addOption(FlagOption('-nomultidefs'))
524 self.nostartfilesOption = self.addOption(FlagOption('-nostartfiles'))
525 self.nodefaultlibsOption = self.addOption(FlagOption('-nodefaultlibs'))
526 self.nostdlibOption = self.addOption(FlagOption('-nostdlib'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000527 self.nostdincOption = self.addOption(FlagOption('-nostdinc'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000528 self.objectOption = self.addOption(FlagOption('-object'))
529 self.preloadOption = self.addOption(FlagOption('-preload'))
530 self.staticOption = self.addOption(FlagOption('-static'))
531 self.pagezero_sizeOption = self.addOption(FlagOption('-pagezero_size'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000532 self.addOption(FlagOption('-shared'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000533 self.staticLibgccOption = self.addOption(FlagOption('-static-libgcc'))
534 self.sharedLibgccOption = self.addOption(FlagOption('-shared-libgcc'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000535 self.COption = self.addOption(FlagOption('-C'))
536 self.CCOption = self.addOption(FlagOption('-CC'))
537 self.HOption = self.addOption(FlagOption('-H'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000538 self.addOption(FlagOption('-R'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000539 self.POption = self.addOption(FlagOption('-P'))
540 self.QOption = self.addOption(FlagOption('-Q'))
Daniel Dunbar816dd502009-01-12 17:53:19 +0000541 self.QnOption = self.addOption(FlagOption('-Qn'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000542 self.addOption(FlagOption('-all_load'))
543 self.addOption(FlagOption('--constant-cfstrings'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000544 self.traditionalOption = self.addOption(FlagOption('-traditional'))
545 self.traditionalCPPOption = self.addOption(FlagOption('-traditional-cpp'))
546 # FIXME: Alias.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000547 self.addOption(FlagOption('--traditional'))
548 self.addOption(FlagOption('-no_dead_strip_inits_and_terms'))
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000549 self.addOption(JoinedOption('-weak-l', isLinkerInput=True))
550 self.addOption(SeparateOption('-weak_framework', isLinkerInput=True))
551 self.addOption(SeparateOption('-weak_library', isLinkerInput=True))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000552 self.whyloadOption = self.addOption(FlagOption('-whyload'))
553 self.whatsloadedOption = self.addOption(FlagOption('-whatsloaded'))
554 self.sectalignOption = self.addOption(MultiArgOption('-sectalign', numArgs=3))
555 self.sectobjectsymbolsOption = self.addOption(MultiArgOption('-sectobjectsymbols', numArgs=2))
556 self.segcreateOption = self.addOption(MultiArgOption('-segcreate', numArgs=3))
557 self.segs_read_Option = self.addOption(JoinedOption('-segs_read_'))
558 self.seglinkeditOption = self.addOption(FlagOption('-seglinkedit'))
559 self.noseglinkeditOption = self.addOption(FlagOption('-noseglinkedit'))
560 self.sectcreateOption = self.addOption(MultiArgOption('-sectcreate', numArgs=3))
561 self.sectorderOption = self.addOption(MultiArgOption('-sectorder', numArgs=3))
562 self.Zall_loadOption = self.addOption(FlagOption('-Zall_load'))
563 self.Zallowable_clientOption = self.addOption(SeparateOption('-Zallowable_client'))
564 self.Zbind_at_loadOption = self.addOption(SeparateOption('-Zbind_at_load'))
565 self.ZbundleOption = self.addOption(FlagOption('-Zbundle'))
566 self.Zbundle_loaderOption = self.addOption(JoinedOrSeparateOption('-Zbundle_loader'))
567 self.Zdead_stripOption = self.addOption(FlagOption('-Zdead_strip'))
568 self.Zdylib_fileOption = self.addOption(JoinedOrSeparateOption('-Zdylib_file'))
569 self.ZdynamicOption = self.addOption(FlagOption('-Zdynamic'))
570 self.ZdynamiclibOption = self.addOption(FlagOption('-Zdynamiclib'))
571 self.Zexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zexported_symbols_list'))
572 self.Zflat_namespaceOption = self.addOption(FlagOption('-Zflat_namespace'))
573 self.Zfn_seg_addr_table_filenameOption = self.addOption(JoinedOrSeparateOption('-Zfn_seg_addr_table_filename'))
574 self.Zforce_cpusubtype_ALLOption = self.addOption(FlagOption('-Zforce_cpusubtype_ALL'))
575 self.Zforce_flat_namespaceOption = self.addOption(FlagOption('-Zforce_flat_namespace'))
576 self.Zimage_baseOption = self.addOption(FlagOption('-Zimage_base'))
577 self.ZinitOption = self.addOption(JoinedOrSeparateOption('-Zinit'))
578 self.Zmulti_moduleOption = self.addOption(FlagOption('-Zmulti_module'))
579 self.Zmultiply_definedOption = self.addOption(JoinedOrSeparateOption('-Zmultiply_defined'))
580 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
581 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
582 self.Zno_dead_strip_inits_and_termsOption = self.addOption(FlagOption('-Zno_dead_strip_inits_and_terms'))
583 self.Zseg_addr_tableOption = self.addOption(JoinedOrSeparateOption('-Zseg_addr_table'))
584 self.ZsegaddrOption = self.addOption(JoinedOrSeparateOption('-Zsegaddr'))
585 self.Zsegs_read_only_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_only_addr'))
586 self.Zsegs_read_write_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_write_addr'))
587 self.Zsingle_moduleOption = self.addOption(FlagOption('-Zsingle_module'))
Daniel Dunbar0fe5a4f2009-01-11 22:42:24 +0000588 self.ZumbrellaOption = self.addOption(JoinedOrSeparateOption('-Zumbrella'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000589 self.Zunexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zunexported_symbols_list'))
590 self.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000591
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000592 self.addOption(SeparateOption('-filelist', isLinkerInput=True))
593 self.addOption(SeparateOption('-framework', isLinkerInput=True))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000594 # FIXME: Alias.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000595 self.addOption(SeparateOption('-install_name'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000596 self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000597 self.addOption(SeparateOption('-seg_addr_table'))
598 self.addOption(SeparateOption('-seg_addr_table_filename'))
599
600 # Where are these coming from? I can't find them...
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000601 self.eOption = self.addOption(JoinedOrSeparateOption('-e'))
602 self.rOption = self.addOption(JoinedOrSeparateOption('-r'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000603
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000604 self.pgOption = self.addOption(FlagOption('-pg'))
Daniel Dunbar816dd502009-01-12 17:53:19 +0000605 self.pOption = self.addOption(FlagOption('-p'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000606
607 doNotReallySupport = 1
608 if doNotReallySupport:
609 # Archaic gcc option.
610 self.addOption(FlagOption('-cpp-precomp'))
611 self.addOption(FlagOption('-no-cpp-precomp'))
612
613 # C options for testing
614
615 self.addOption(JoinedOrSeparateOption('-include'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000616 # FIXME: This is broken, we need -A as a single option to send
617 # stuff to cc1, but the way the ld spec is constructed it
618 # wants to see -A options but only as a separate arg.
619 self.AOption = self.addOption(JoinedOrSeparateOption('-A'))
620 self.DOption = self.addOption(JoinedOrSeparateOption('-D'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000621 self.FOption = self.addOption(JoinedOrSeparateOption('-F'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000622 self.IOption = self.addOption(JoinedOrSeparateOption('-I'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000623 self.LOption = self.addOption(JoinedOrSeparateOption('-L'))
624 self.TOption = self.addOption(JoinedOrSeparateOption('-T'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000625 self.UOption = self.addOption(JoinedOrSeparateOption('-U'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000626 self.ZOption = self.addOption(JoinedOrSeparateOption('-Z'))
627
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000628 self.addOption(JoinedOrSeparateOption('-l', isLinkerInput=True))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000629 self.uOption = self.addOption(JoinedOrSeparateOption('-u'))
630 self.tOption = self.addOption(JoinedOrSeparateOption('-t'))
631 self.yOption = self.addOption(JoinedOption('-y'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000632
633 # FIXME: What is going on here? '-X' goes to linker, and -X ... goes nowhere?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000634 self.XOption = self.addOption(FlagOption('-X'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000635 # Not exactly sure how to decompose this. I split out -Xarch_
636 # because we need to recognize that in the driver driver part.
637 # FIXME: Man, this is lame it needs its own option.
638 self.XarchOption = self.addOption(JoinedAndSeparateOption('-Xarch_'))
639 self.addOption(JoinedOption('-X'))
640
641 # The driver needs to know about this flag.
642 self.syntaxOnlyOption = self.addOption(FlagOption('-fsyntax-only'))
643
644 # FIXME: Wrong?
645 # FIXME: What to do about the ambiguity of options like
646 # -dumpspecs? How is this handled in gcc?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000647 # FIXME: Naming convention.
648 self.dOption = self.addOption(FlagOption('-d'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000649 self.addOption(JoinedOption('-d'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000650
Daniel Dunbar996ce962009-01-12 07:40:25 +0000651 # Take care on extension, the Darwin assembler wants to add a
652 # flag for any -g* option.
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000653 self.g3Option = self.addOption(JoinedOption('-g3'))
Daniel Dunbar996ce962009-01-12 07:40:25 +0000654 self.gOption = self.addOption(JoinedOption('-g'))
655
Daniel Dunbar816dd502009-01-12 17:53:19 +0000656 self.fastOption = self.addOption(FlagOption('-fast'))
657 self.fastfOption = self.addOption(FlagOption('-fastf'))
658 self.fastcpOption = self.addOption(FlagOption('-fastcp'))
659
Daniel Dunbar996ce962009-01-12 07:40:25 +0000660 self.f_appleKextOption = self.addOption(FlagOption('-fapple-kext'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000661 self.f_exceptionsOption = self.addOption(FlagOption('-fexceptions'))
Daniel Dunbaree8cc262009-01-12 02:24:21 +0000662 self.f_objcOption = self.addOption(FlagOption('-fobjc'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000663 self.f_openmpOption = self.addOption(FlagOption('-fopenmp'))
664 self.f_gnuRuntimeOption = self.addOption(FlagOption('-fgnu-runtime'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000665 self.f_mudflapOption = self.addOption(FlagOption('-fmudflap'))
666 self.f_mudflapthOption = self.addOption(FlagOption('-fmudflapth'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000667 self.f_nestedFunctionsOption = self.addOption(FlagOption('-fnested-functions'))
668 self.f_pieOption = self.addOption(FlagOption('-fpie'))
669 self.f_profileArcsOption = self.addOption(FlagOption('-fprofile-arcs'))
670 self.f_profileGenerateOption = self.addOption(FlagOption('-fprofile-generate'))
671 self.f_createProfileOption = self.addOption(FlagOption('-fcreate-profile'))
Daniel Dunbar6325fcf2009-01-12 09:23:15 +0000672 self.f_traditionalOption = self.addOption(FlagOption('-ftraditional'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000673 self.coverageOption = self.addOption(FlagOption('-coverage'))
674 self.coverageOption2 = self.addOption(FlagOption('--coverage'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000675 self.addOption(JoinedOption('-f'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000676
677 self.m_32Option = self.addOption(FlagOption('-m32'))
678 self.m_64Option = self.addOption(FlagOption('-m64'))
679 self.m_iphoneosVersionMinOption = self.addOption(JoinedOption('-miphoneos-version-min='))
680 self.m_macosxVersionMinOption = self.addOption(JoinedOption('-mmacosx-version-min='))
Daniel Dunbar996ce962009-01-12 07:40:25 +0000681 self.m_kernelOption = self.addOption(FlagOption('-mkernel'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000682
683 # Ugh. Need to disambiguate our naming convetion. -m x goes to
684 # the linker sometimes, wheres -mxxxx is used for a variety of
685 # other things.
686 self.mOption = self.addOption(SeparateOption('-m'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000687 self.addOption(JoinedOption('-m'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000688
Daniel Dunbar816dd502009-01-12 17:53:19 +0000689 self.ansiOption = self.addOption(FlagOption('-ansi'))
690 self.trigraphsOption = self.addOption(FlagOption('-trigraphs'))
691 self.pedanticOption = self.addOption(FlagOption('-pedantic'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000692 self.addOption(JoinedOption('-i'))
Daniel Dunbar816dd502009-01-12 17:53:19 +0000693 self.OOption = self.addOption(JoinedOption('-O'))
694 self.WOption = self.addOption(JoinedOption('-W'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000695 # FIXME: Weird. This option isn't really separate, --param=a=b
Daniel Dunbar816dd502009-01-12 17:53:19 +0000696 # works. There is something else going on which interprets the
697 # '='.
698 self._paramOption = self.addOption(SeparateOption('--param'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000699
700 # FIXME: What is this? Seems to do something on Linux. I think
701 # only one is valid, but have a log that uses both.
702 self.addOption(FlagOption('-pthread'))
703 self.addOption(FlagOption('-pthreads'))
704
Daniel Dunbara5677512009-01-05 19:53:30 +0000705 def addOption(self, opt):
706 self.options.append(opt)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000707 return opt
Daniel Dunbara5677512009-01-05 19:53:30 +0000708
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000709 def parseArgs(self, argv):
Daniel Dunbara5677512009-01-05 19:53:30 +0000710 """
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000711 parseArgs([str]) -> ArgList
Daniel Dunbara5677512009-01-05 19:53:30 +0000712
713 Parse command line into individual option instances.
714 """
715
716 iargs = enumerate(argv)
717 it = iter(iargs)
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000718 args = ArgList(self, argv)
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000719 for pos,a in it:
720 i = InputIndex(0, pos)
Daniel Dunbara5677512009-01-05 19:53:30 +0000721 # FIXME: Handle '@'
722 if not a:
723 # gcc's handling of empty arguments doesn't make
724 # sense, but this is not a common use case. :)
725 #
726 # We just ignore them here (note that other things may
727 # still take them as arguments).
728 pass
729 elif a[0] == '-' and a != '-':
730 args.append(self.lookupOptForArg(i, a, it))
731 else:
Daniel Dunbar5039f212009-01-06 02:30:10 +0000732 args.append(PositionalArg(i, self.inputOption))
Daniel Dunbara5677512009-01-05 19:53:30 +0000733 return args
734
Daniel Dunbar5039f212009-01-06 02:30:10 +0000735 def lookupOptForArg(self, i, string, it):
736 for o in self.options:
737 arg = o.accept(i, string, it)
738 if arg is not None:
739 return arg
740 return PositionalArg(i, self.unknownOption)