blob: c563f3b1fc3eaaedcbb0d0022505fd277e662c8f [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 Dunbarba6e3232009-01-06 06:12:13 +0000278 def getLastArg(self, option):
279 return self.lastArgs.get(option)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000280
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000281 def getInputString(self, index, offset=0):
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000282 # Source 0 is argv.
283 if index.sourceId == 0:
284 return self.argv[index.pos + offset]
285
286 # Source 1 is synthetic argv.
287 if index.sourceId == 1:
288 return self.syntheticArgv[index.pos + offset]
289
290 raise RuntimeError,'Unknown source ID for index.'
291
Daniel Dunbar0fe5a4f2009-01-11 22:42:24 +0000292 def addLastArg(self, output, option):
293 """addLastArgs - Extend the given output vector with the last
294 instance of a given option."""
295 arg = self.getLastArg(option)
296 if arg:
297 output.extend(self.render(arg))
298
299 def addAllArgs(self, output, option):
300 """addAllArgs - Extend the given output vector with all
301 instances of a given option."""
302 for arg in self.getArgs(option):
303 output.extend(self.render(arg))
304
305 def addAllArgsTranslated(self, output, option, translation):
306 """addAllArgsTranslated - Extend the given output vector with
307 all instances of a given option, rendered as separate
308 arguments with the actual option name translated to a user
309 specified string. For example, '-foox' will be render as
310 ['-bar', 'x'] if '-foo' was the option and '-bar' was the
311 translation.
312
313 This routine expects that the option can only yield ValueArg
314 instances."""
315 for arg in self.getArgs(option):
316 assert isinstance(arg, ValueArg)
317 output.append(translation)
318 output.append(self.getValue(arg))
319
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000320 def makeIndex(self, *strings):
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000321 pos = len(self.syntheticArgv)
322 self.syntheticArgv.extend(strings)
323 return InputIndex(1, pos)
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000324
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000325 def makeFlagArg(self, option):
326 return Arg(self.makeIndex(option.name),
327 option)
328
329 def makeInputArg(self, string):
330 return PositionalArg(self.makeIndex(string),
331 self.parser.inputOption)
332
333 def makeUnknownArg(self, string):
334 return PositionalArg(self.makeIndex(string),
335 self.parser.unknownOption)
336
337 def makeSeparateArg(self, string, option):
338 return SeparateValueArg(self.makeIndex(option.name, string),
339 option)
340
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000341 # Support use as a simple arg list.
342
343 def __iter__(self):
344 return iter(self.args)
345
346 def append(self, arg):
347 self.args.append(arg)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000348 self.lastArgs[arg.opt] = arg
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000349
350 # Forwarding methods.
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000351 #
352 # FIXME: Clean this up once restructuring is done.
353
354 def render(self, arg):
355 return arg.render(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000356
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000357 def renderAsInput(self, arg):
358 return arg.renderAsInput(self)
359
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000360 def getValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000361 return arg.getValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000362
363 def getValues(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000364 return arg.getValues(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000365
366 def getSeparateValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000367 return arg.getSeparateValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000368
369 def getJoinedValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000370 return arg.getJoinedValue(self)
Daniel Dunbar1dd2ada2009-01-06 06:32:49 +0000371
372###
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000373
Daniel Dunbara5677512009-01-05 19:53:30 +0000374class OptionParser:
375 def __init__(self):
376 self.options = []
Daniel Dunbar5039f212009-01-06 02:30:10 +0000377 self.inputOption = InputOption()
378 self.unknownOption = UnknownOption()
379
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000380 # Driver driver options
381 self.archOption = self.addOption(SeparateOption('-arch'))
382
383 # Misc driver options
384 self.addOption(FlagOption('-pass-exit-codes'))
385 self.addOption(FlagOption('--help'))
386 self.addOption(FlagOption('--target-help'))
387
388 self.dumpspecsOption = self.addOption(FlagOption('-dumpspecs'))
389 self.dumpversionOption = self.addOption(FlagOption('-dumpversion'))
390 self.dumpmachineOption = self.addOption(FlagOption('-dumpmachine'))
391 self.printSearchDirsOption = self.addOption(FlagOption('-print-search-dirs'))
392 self.printLibgccFilenameOption = self.addOption(FlagOption('-print-libgcc-file-name'))
393 # FIXME: Hrm, where does this come from? It isn't always true that
394 # we take both - and --. For example, gcc --S ... ends up sending
395 # -fS to cc1. Investigate.
396 #
397 # FIXME: Need to implement some form of alias support inside
398 # getLastOption to handle this.
399 self.printLibgccFileNameOption2 = self.addOption(FlagOption('--print-libgcc-file-name'))
400 self.printFileNameOption = self.addOption(JoinedOption('-print-file-name='))
401 self.printProgNameOption = self.addOption(JoinedOption('-print-prog-name='))
402 self.printProgNameOption2 = self.addOption(JoinedOption('--print-prog-name='))
403 self.printMultiDirectoryOption = self.addOption(FlagOption('-print-multi-directory'))
404 self.printMultiLibOption = self.addOption(FlagOption('-print-multi-lib'))
405 self.addOption(FlagOption('-print-multi-os-directory'))
406
407 # Hmmm, who really takes this?
408 self.addOption(FlagOption('--version'))
409
410 # Pipeline control
411 self.hashHashHashOption = self.addOption(FlagOption('-###'))
412 self.EOption = self.addOption(FlagOption('-E'))
413 self.SOption = self.addOption(FlagOption('-S'))
414 self.cOption = self.addOption(FlagOption('-c'))
415 self.combineOption = self.addOption(FlagOption('-combine'))
416 self.noIntegratedCPPOption = self.addOption(FlagOption('-no-integrated-cpp'))
417 self.pipeOption = self.addOption(FlagOption('-pipe'))
418 self.saveTempsOption = self.addOption(FlagOption('-save-temps'))
419 self.saveTempsOption2 = self.addOption(FlagOption('--save-temps'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000420 # FIXME: Error out if this is used.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000421 self.addOption(JoinedOption('-specs='))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000422 # FIXME: Implement.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000423 self.addOption(FlagOption('-time'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000424 # FIXME: Implement.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000425 self.addOption(FlagOption('-v'))
426
427 # Input/output stuff
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000428 self.oOption = self.addOption(JoinedOrSeparateOption('-o', noOptAsInput=True))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000429 self.xOption = self.addOption(JoinedOrSeparateOption('-x'))
430
Daniel Dunbaree8cc262009-01-12 02:24:21 +0000431 self.ObjCOption = self.addOption(FlagOption('-ObjC'))
432 self.ObjCXXOption = self.addOption(FlagOption('-ObjC++'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000433
434 # FIXME: Weird, gcc claims this here in help but I'm not sure why;
435 # perhaps interaction with preprocessor? Investigate.
436 self.addOption(JoinedOption('-std='))
437 self.addOption(JoinedOrSeparateOption('--sysroot'))
438
439 # Version control
440 self.addOption(JoinedOrSeparateOption('-B'))
441 self.addOption(JoinedOrSeparateOption('-V'))
442 self.addOption(JoinedOrSeparateOption('-b'))
443
444 # Blanket pass-through options.
445
Daniel Dunbar996ce962009-01-12 07:40:25 +0000446 self.WaOption = self.addOption(CommaJoinedOption('-Wa,'))
447 self.XassemblerOption = self.addOption(SeparateOption('-Xassembler'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000448
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000449 self.addOption(CommaJoinedOption('-Wp,'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000450 self.addOption(SeparateOption('-Xpreprocessor'))
451
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000452 self.addOption(CommaJoinedOption('-Wl,', isLinkerInput=True))
453 self.addOption(SeparateOption('-Xlinker', isLinkerInput=True, noOptAsInput=True))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000454
455 ####
456 # Bring on the random garbage.
457
458 self.addOption(FlagOption('-MD'))
459 self.addOption(FlagOption('-MP'))
460 self.addOption(FlagOption('-MM'))
461 self.addOption(JoinedOrSeparateOption('-MF'))
462 self.addOption(JoinedOrSeparateOption('-MT'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000463 self.MachOption = self.addOption(FlagOption('-Mach'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000464 self.addOption(FlagOption('-undef'))
465
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000466 self.wOption = self.addOption(FlagOption('-w'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000467 self.addOption(JoinedOrSeparateOption('-allowable_client'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000468 self.client_nameOption = self.addOption(JoinedOrSeparateOption('-client_name'))
469 self.compatibility_versionOption = self.addOption(JoinedOrSeparateOption('-compatibility_version'))
470 self.current_versionOption = self.addOption(JoinedOrSeparateOption('-current_version'))
471 self.dylinkerOption = self.addOption(FlagOption('-dylinker'))
472 self.dylinker_install_nameOption = self.addOption(JoinedOrSeparateOption('-dylinker_install_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000473 self.addOption(JoinedOrSeparateOption('-exported_symbols_list'))
474 self.addOption(JoinedOrSeparateOption('-idirafter'))
475 self.addOption(JoinedOrSeparateOption('-iquote'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000476 self.isysrootOption = self.addOption(JoinedOrSeparateOption('-isysroot'))
477 self.keep_private_externsOption = self.addOption(JoinedOrSeparateOption('-keep_private_externs'))
478 self.private_bundleOption = self.addOption(FlagOption('-private_bundle'))
479 self.seg1addrOption = self.addOption(JoinedOrSeparateOption('-seg1addr'))
480 self.segprotOption = self.addOption(JoinedOrSeparateOption('-segprot'))
481 self.sub_libraryOption = self.addOption(JoinedOrSeparateOption('-sub_library'))
482 self.sub_umbrellaOption = self.addOption(JoinedOrSeparateOption('-sub_umbrella'))
483 self.umbrellaOption = self.addOption(JoinedOrSeparateOption('-umbrella'))
484 self.undefinedOption = self.addOption(JoinedOrSeparateOption('-undefined'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000485 self.addOption(JoinedOrSeparateOption('-unexported_symbols_list'))
486 self.addOption(JoinedOrSeparateOption('-weak_framework'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000487 self.headerpad_max_install_namesOption = self.addOption(JoinedOption('-headerpad_max_install_names'))
488 self.twolevel_namespaceOption = self.addOption(FlagOption('-twolevel_namespace'))
489 self.twolevel_namespace_hintsOption = self.addOption(FlagOption('-twolevel_namespace_hints'))
490 self.prebindOption = self.addOption(FlagOption('-prebind'))
491 self.noprebindOption = self.addOption(FlagOption('-noprebind'))
492 self.nofixprebindingOption = self.addOption(FlagOption('-nofixprebinding'))
493 self.prebind_all_twolevel_modulesOption = self.addOption(FlagOption('-prebind_all_twolevel_modules'))
494 self.read_only_relocsOption = self.addOption(SeparateOption('-read_only_relocs'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000495 self.addOption(FlagOption('-single_module'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000496 self.nomultidefsOption = self.addOption(FlagOption('-nomultidefs'))
497 self.nostartfilesOption = self.addOption(FlagOption('-nostartfiles'))
498 self.nodefaultlibsOption = self.addOption(FlagOption('-nodefaultlibs'))
499 self.nostdlibOption = self.addOption(FlagOption('-nostdlib'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000500 self.addOption(FlagOption('-nostdinc'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000501 self.objectOption = self.addOption(FlagOption('-object'))
502 self.preloadOption = self.addOption(FlagOption('-preload'))
503 self.staticOption = self.addOption(FlagOption('-static'))
504 self.pagezero_sizeOption = self.addOption(FlagOption('-pagezero_size'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000505 self.addOption(FlagOption('-shared'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000506 self.staticLibgccOption = self.addOption(FlagOption('-static-libgcc'))
507 self.sharedLibgccOption = self.addOption(FlagOption('-shared-libgcc'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000508 self.addOption(FlagOption('-C'))
509 self.addOption(FlagOption('-CC'))
510 self.addOption(FlagOption('-R'))
511 self.addOption(FlagOption('-P'))
512 self.addOption(FlagOption('-all_load'))
513 self.addOption(FlagOption('--constant-cfstrings'))
514 self.addOption(FlagOption('-traditional'))
515 self.addOption(FlagOption('--traditional'))
516 self.addOption(FlagOption('-no_dead_strip_inits_and_terms'))
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000517 self.addOption(JoinedOption('-weak-l', isLinkerInput=True))
518 self.addOption(SeparateOption('-weak_framework', isLinkerInput=True))
519 self.addOption(SeparateOption('-weak_library', isLinkerInput=True))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000520 self.whyloadOption = self.addOption(FlagOption('-whyload'))
521 self.whatsloadedOption = self.addOption(FlagOption('-whatsloaded'))
522 self.sectalignOption = self.addOption(MultiArgOption('-sectalign', numArgs=3))
523 self.sectobjectsymbolsOption = self.addOption(MultiArgOption('-sectobjectsymbols', numArgs=2))
524 self.segcreateOption = self.addOption(MultiArgOption('-segcreate', numArgs=3))
525 self.segs_read_Option = self.addOption(JoinedOption('-segs_read_'))
526 self.seglinkeditOption = self.addOption(FlagOption('-seglinkedit'))
527 self.noseglinkeditOption = self.addOption(FlagOption('-noseglinkedit'))
528 self.sectcreateOption = self.addOption(MultiArgOption('-sectcreate', numArgs=3))
529 self.sectorderOption = self.addOption(MultiArgOption('-sectorder', numArgs=3))
530 self.Zall_loadOption = self.addOption(FlagOption('-Zall_load'))
531 self.Zallowable_clientOption = self.addOption(SeparateOption('-Zallowable_client'))
532 self.Zbind_at_loadOption = self.addOption(SeparateOption('-Zbind_at_load'))
533 self.ZbundleOption = self.addOption(FlagOption('-Zbundle'))
534 self.Zbundle_loaderOption = self.addOption(JoinedOrSeparateOption('-Zbundle_loader'))
535 self.Zdead_stripOption = self.addOption(FlagOption('-Zdead_strip'))
536 self.Zdylib_fileOption = self.addOption(JoinedOrSeparateOption('-Zdylib_file'))
537 self.ZdynamicOption = self.addOption(FlagOption('-Zdynamic'))
538 self.ZdynamiclibOption = self.addOption(FlagOption('-Zdynamiclib'))
539 self.Zexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zexported_symbols_list'))
540 self.Zflat_namespaceOption = self.addOption(FlagOption('-Zflat_namespace'))
541 self.Zfn_seg_addr_table_filenameOption = self.addOption(JoinedOrSeparateOption('-Zfn_seg_addr_table_filename'))
542 self.Zforce_cpusubtype_ALLOption = self.addOption(FlagOption('-Zforce_cpusubtype_ALL'))
543 self.Zforce_flat_namespaceOption = self.addOption(FlagOption('-Zforce_flat_namespace'))
544 self.Zimage_baseOption = self.addOption(FlagOption('-Zimage_base'))
545 self.ZinitOption = self.addOption(JoinedOrSeparateOption('-Zinit'))
546 self.Zmulti_moduleOption = self.addOption(FlagOption('-Zmulti_module'))
547 self.Zmultiply_definedOption = self.addOption(JoinedOrSeparateOption('-Zmultiply_defined'))
548 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
549 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
550 self.Zno_dead_strip_inits_and_termsOption = self.addOption(FlagOption('-Zno_dead_strip_inits_and_terms'))
551 self.Zseg_addr_tableOption = self.addOption(JoinedOrSeparateOption('-Zseg_addr_table'))
552 self.ZsegaddrOption = self.addOption(JoinedOrSeparateOption('-Zsegaddr'))
553 self.Zsegs_read_only_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_only_addr'))
554 self.Zsegs_read_write_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_write_addr'))
555 self.Zsingle_moduleOption = self.addOption(FlagOption('-Zsingle_module'))
Daniel Dunbar0fe5a4f2009-01-11 22:42:24 +0000556 self.ZumbrellaOption = self.addOption(JoinedOrSeparateOption('-Zumbrella'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000557 self.Zunexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zunexported_symbols_list'))
558 self.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000559
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000560 self.addOption(SeparateOption('-filelist', isLinkerInput=True))
561 self.addOption(SeparateOption('-framework', isLinkerInput=True))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000562 # FIXME: Alias.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000563 self.addOption(SeparateOption('-install_name'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000564 self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000565 self.addOption(SeparateOption('-seg_addr_table'))
566 self.addOption(SeparateOption('-seg_addr_table_filename'))
567
568 # Where are these coming from? I can't find them...
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000569 self.eOption = self.addOption(JoinedOrSeparateOption('-e'))
570 self.rOption = self.addOption(JoinedOrSeparateOption('-r'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000571
572 # Is this actually declared anywhere? I can only find it in a
573 # spec. :(
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000574 self.pgOption = self.addOption(FlagOption('-pg'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000575
576 doNotReallySupport = 1
577 if doNotReallySupport:
578 # Archaic gcc option.
579 self.addOption(FlagOption('-cpp-precomp'))
580 self.addOption(FlagOption('-no-cpp-precomp'))
581
582 # C options for testing
583
584 self.addOption(JoinedOrSeparateOption('-include'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000585 self.AOption = self.addOption(SeparateOption('-A'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000586 self.addOption(JoinedOrSeparateOption('-D'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000587 self.FOption = self.addOption(JoinedOrSeparateOption('-F'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000588 self.addOption(JoinedOrSeparateOption('-I'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000589 self.LOption = self.addOption(JoinedOrSeparateOption('-L'))
590 self.TOption = self.addOption(JoinedOrSeparateOption('-T'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000591 self.addOption(JoinedOrSeparateOption('-U'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000592 self.ZOption = self.addOption(JoinedOrSeparateOption('-Z'))
593
Daniel Dunbar2ec55bc2009-01-12 03:33:58 +0000594 self.addOption(JoinedOrSeparateOption('-l', isLinkerInput=True))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000595 self.uOption = self.addOption(JoinedOrSeparateOption('-u'))
596 self.tOption = self.addOption(JoinedOrSeparateOption('-t'))
597 self.yOption = self.addOption(JoinedOption('-y'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000598
599 # FIXME: What is going on here? '-X' goes to linker, and -X ... goes nowhere?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000600 self.XOption = self.addOption(FlagOption('-X'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000601 # Not exactly sure how to decompose this. I split out -Xarch_
602 # because we need to recognize that in the driver driver part.
603 # FIXME: Man, this is lame it needs its own option.
604 self.XarchOption = self.addOption(JoinedAndSeparateOption('-Xarch_'))
605 self.addOption(JoinedOption('-X'))
606
607 # The driver needs to know about this flag.
608 self.syntaxOnlyOption = self.addOption(FlagOption('-fsyntax-only'))
609
610 # FIXME: Wrong?
611 # FIXME: What to do about the ambiguity of options like
612 # -dumpspecs? How is this handled in gcc?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000613 # FIXME: Naming convention.
614 self.dOption = self.addOption(FlagOption('-d'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000615 self.addOption(JoinedOption('-d'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000616
Daniel Dunbar996ce962009-01-12 07:40:25 +0000617 # Take care on extension, the Darwin assembler wants to add a
618 # flag for any -g* option.
619 self.gOption = self.addOption(JoinedOption('-g'))
620
621 self.f_appleKextOption = self.addOption(FlagOption('-fapple-kext'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000622 self.f_exceptionsOption = self.addOption(FlagOption('-fexceptions'))
Daniel Dunbaree8cc262009-01-12 02:24:21 +0000623 self.f_objcOption = self.addOption(FlagOption('-fobjc'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000624 self.f_openmpOption = self.addOption(FlagOption('-fopenmp'))
625 self.f_gnuRuntimeOption = self.addOption(FlagOption('-fgnu-runtime'))
626 self.f_nestedFunctionsOption = self.addOption(FlagOption('-fnested-functions'))
627 self.f_pieOption = self.addOption(FlagOption('-fpie'))
628 self.f_profileArcsOption = self.addOption(FlagOption('-fprofile-arcs'))
629 self.f_profileGenerateOption = self.addOption(FlagOption('-fprofile-generate'))
630 self.f_createProfileOption = self.addOption(FlagOption('-fcreate-profile'))
631 self.coverageOption = self.addOption(FlagOption('-coverage'))
632 self.coverageOption2 = self.addOption(FlagOption('--coverage'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000633 self.addOption(JoinedOption('-f'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000634
635 self.m_32Option = self.addOption(FlagOption('-m32'))
636 self.m_64Option = self.addOption(FlagOption('-m64'))
637 self.m_iphoneosVersionMinOption = self.addOption(JoinedOption('-miphoneos-version-min='))
638 self.m_macosxVersionMinOption = self.addOption(JoinedOption('-mmacosx-version-min='))
Daniel Dunbar996ce962009-01-12 07:40:25 +0000639 self.m_kernelOption = self.addOption(FlagOption('-mkernel'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000640
641 # Ugh. Need to disambiguate our naming convetion. -m x goes to
642 # the linker sometimes, wheres -mxxxx is used for a variety of
643 # other things.
644 self.mOption = self.addOption(SeparateOption('-m'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000645 self.addOption(JoinedOption('-m'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000646
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000647 self.addOption(JoinedOption('-i'))
648 self.addOption(JoinedOption('-O'))
649 self.addOption(JoinedOption('-W'))
650 # FIXME: Weird. This option isn't really separate, --param=a=b
651 # works. An alias somewhere?
652 self.addOption(SeparateOption('--param'))
653
654 # FIXME: What is this? Seems to do something on Linux. I think
655 # only one is valid, but have a log that uses both.
656 self.addOption(FlagOption('-pthread'))
657 self.addOption(FlagOption('-pthreads'))
658
Daniel Dunbara5677512009-01-05 19:53:30 +0000659 def addOption(self, opt):
660 self.options.append(opt)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000661 return opt
Daniel Dunbara5677512009-01-05 19:53:30 +0000662
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000663 def parseArgs(self, argv):
Daniel Dunbara5677512009-01-05 19:53:30 +0000664 """
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000665 parseArgs([str]) -> ArgList
Daniel Dunbara5677512009-01-05 19:53:30 +0000666
667 Parse command line into individual option instances.
668 """
669
670 iargs = enumerate(argv)
671 it = iter(iargs)
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000672 args = ArgList(self, argv)
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000673 for pos,a in it:
674 i = InputIndex(0, pos)
Daniel Dunbara5677512009-01-05 19:53:30 +0000675 # FIXME: Handle '@'
676 if not a:
677 # gcc's handling of empty arguments doesn't make
678 # sense, but this is not a common use case. :)
679 #
680 # We just ignore them here (note that other things may
681 # still take them as arguments).
682 pass
683 elif a[0] == '-' and a != '-':
684 args.append(self.lookupOptForArg(i, a, it))
685 else:
Daniel Dunbar5039f212009-01-06 02:30:10 +0000686 args.append(PositionalArg(i, self.inputOption))
Daniel Dunbara5677512009-01-05 19:53:30 +0000687 return args
688
Daniel Dunbar5039f212009-01-06 02:30:10 +0000689 def lookupOptForArg(self, i, string, it):
690 for o in self.options:
691 arg = o.accept(i, string, it)
692 if arg is not None:
693 return arg
694 return PositionalArg(i, self.unknownOption)