blob: 564114f405f96f31adf303c2d8af7c13eda69265 [file] [log] [blame]
Daniel Dunbara5677512009-01-05 19:53:30 +00001class Option(object):
2 """Root option class."""
3 def __init__(self, name):
4 self.name = name
5
6 def accept(self, index, arg, it):
7 """accept(index, arg, iterator) -> Arg or None
8
9 Accept the argument at the given index, returning an Arg, or
10 return None if the option does not accept this argument.
11
12 May raise MissingArgumentError.
13 """
14 abstract
15
16 def __repr__(self):
17 return '<%s name=%r>' % (self.__class__.__name__,
18 self.name)
19
Daniel Dunbar5039f212009-01-06 02:30:10 +000020# Dummy options
21
22class InputOption(Option):
23 def __init__(self):
24 super(InputOption, self).__init__('<input>')
25
26 def accept(self):
27 raise RuntimeError,"accept() should never be used on InputOption instance."
28
29class UnknownOption(Option):
30 def __init__(self):
31 super(UnknownOption, self).__init__('<unknown>')
32
33 def accept(self):
34 raise RuntimeError,"accept() should never be used on UnknownOption instance."
35
36# Normal options
37
Daniel Dunbara5677512009-01-05 19:53:30 +000038class FlagOption(Option):
39 """An option which takes no arguments."""
40
41 def accept(self, index, arg, it):
42 if arg == self.name:
43 return Arg(index, self)
44
45class JoinedOption(Option):
46 """An option which literally prefixes its argument."""
47
48 def accept(self, index, arg, it):
49 if arg.startswith(self.name):
50 return JoinedValueArg(index, self)
51
52class SeparateOption(Option):
53 """An option which is followed by its value."""
54
55 def accept(self, index, arg, it):
56 if arg == self.name:
57 try:
58 _,value = it.next()
59 except StopIteration:
60 raise MissingArgumentError,self
61 return SeparateValueArg(index, self)
62
63class MultiArgOption(Option):
64 """An option which takes multiple arguments."""
65
66 def __init__(self, name, numArgs):
67 assert numArgs > 1
68 super(MultiArgOption, self).__init__(name)
69 self.numArgs = numArgs
70
71 def accept(self, index, arg, it):
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +000072 if arg == self.name:
Daniel Dunbara5677512009-01-05 19:53:30 +000073 try:
74 values = [it.next()[1] for i in range(self.numArgs)]
75 except StopIteration:
76 raise MissingArgumentError,self
77 return MultipleValuesArg(index, self)
78
79class JoinedOrSeparateOption(Option):
80 """An option which either literally prefixes its value or is
81 followed by an value."""
82
83 def accept(self, index, arg, it):
84 if arg.startswith(self.name):
85 if len(arg) != len(self.name): # Joined case
86 return JoinedValueArg(index, self)
87 else:
88 try:
89 _,value = it.next()
90 except StopIteration:
91 raise MissingArgumentError,self
92 return SeparateValueArg(index, self)
93
94class JoinedAndSeparateOption(Option):
95 """An option which literally prefixes its value and is followed by
96 an value."""
97
98 def accept(self, index, arg, it):
99 if arg.startswith(self.name):
100 try:
101 _,value = it.next()
102 except StopIteration:
103 raise MissingArgumentError,self
104 return JoinedAndSeparateValuesArg(index, self)
105
106###
107
108class Arg(object):
109 """Arg - Base class for actual driver arguments."""
110 def __init__(self, index, opt):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000111 assert opt is not None
Daniel Dunbara5677512009-01-05 19:53:30 +0000112 self.index = index
113 self.opt = opt
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000114
Daniel Dunbara5677512009-01-05 19:53:30 +0000115 def __repr__(self):
116 return '<%s index=%r opt=%r>' % (self.__class__.__name__,
117 self.index,
118 self.opt)
119
120 def render(self, args):
121 """render(args) -> [str]
122
123 Map the argument into a list of actual program arguments,
124 given the source argument array."""
125 assert self.opt
126 return [self.opt.name]
127
128class ValueArg(Arg):
129 """ValueArg - An instance of an option which has an argument."""
130
131 def getValue(self, args):
132 abstract
133
Daniel Dunbar5039f212009-01-06 02:30:10 +0000134class PositionalArg(ValueArg):
135 """PositionalArg - A simple positional argument."""
Daniel Dunbara5677512009-01-05 19:53:30 +0000136
137 def getValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000138 return args.getInputString(self.index)
Daniel Dunbara5677512009-01-05 19:53:30 +0000139
140 def render(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000141 return [args.getInputString(self.index)]
Daniel Dunbara5677512009-01-05 19:53:30 +0000142
143class JoinedValueArg(ValueArg):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000144 """JoinedValueArg - A single value argument where the value is
145 joined (suffixed) to the option."""
146
Daniel Dunbara5677512009-01-05 19:53:30 +0000147 def getValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000148 return args.getInputString(self.index)[len(self.opt.name):]
Daniel Dunbara5677512009-01-05 19:53:30 +0000149
Daniel Dunbara5677512009-01-05 19:53:30 +0000150 def render(self, args):
151 return [self.opt.name + self.getValue(args)]
152
153class SeparateValueArg(ValueArg):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000154 """SeparateValueArg - A single value argument where the value
155 follows the option in the argument vector."""
156
Daniel Dunbara5677512009-01-05 19:53:30 +0000157 def getValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000158 return args.getInputString(self.index, offset=1)
Daniel Dunbara5677512009-01-05 19:53:30 +0000159
Daniel Dunbara5677512009-01-05 19:53:30 +0000160 def render(self, args):
161 return [self.opt.name, self.getValue(args)]
162
163class MultipleValuesArg(Arg):
Daniel Dunbar5039f212009-01-06 02:30:10 +0000164 """MultipleValuesArg - An argument with multiple values which
165 follow the option in the argument vector."""
166
167 # FIXME: Should we unify this with SeparateValueArg?
168
Daniel Dunbara5677512009-01-05 19:53:30 +0000169 def getValues(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000170 return [args.getInputString(self.index, offset=1+i)
171 for i in range(self.opt.numArgs)]
Daniel Dunbara5677512009-01-05 19:53:30 +0000172
Daniel Dunbara5677512009-01-05 19:53:30 +0000173 def render(self, args):
174 return [self.opt.name] + self.getValues(args)
175
176# FIXME: Man, this is lame. It is only used by -Xarch. Maybe easier to
177# just special case?
178class JoinedAndSeparateValuesArg(Arg):
179 """JoinedAndSeparateValuesArg - An argument with both joined and
180 separate values."""
181
182 def getJoinedValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000183 return args.getInputString(self.index)[len(self.opt.name):]
Daniel Dunbara5677512009-01-05 19:53:30 +0000184
185 def getSeparateValue(self, args):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000186 return args.getInputString(self.index, offset=1)
Daniel Dunbara5677512009-01-05 19:53:30 +0000187
188 def render(self, args):
189 return ([self.opt.name + self.getJoinedValue(args)] +
190 [self.getSeparateValue(args)])
191
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000192###
193
194class InputIndex:
195 def __init__(self, sourceId, pos):
196 self.sourceId = sourceId
197 self.pos = pos
198
199 def __repr__(self):
200 return 'InputIndex(%d, %d)' % (self.sourceId, self.pos)
201
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000202class ArgList:
Daniel Dunbar5039f212009-01-06 02:30:10 +0000203 """ArgList - Collect an input argument vector along with a set of parsed Args
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000204 and supporting information."""
205
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000206 def __init__(self, parser, argv):
207 self.parser = parser
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000208 self.argv = list(argv)
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000209 self.syntheticArgv = []
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000210 self.lastArgs = {}
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000211 self.args = []
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000212
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000213 def getArgs(self, option):
214 # FIXME: How efficient do we want to make this. One reasonable
215 # solution would be to embed a linked list inside each arg and
216 # automatically chain them (with pointers to head and
217 # tail). This gives us efficient access to the (first, last,
218 # all) arg(s) with little overhead.
219 for arg in self.args:
220 if arg.opt is option:
221 yield arg
222
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000223 def getLastArg(self, option):
224 return self.lastArgs.get(option)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000225
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000226 def getInputString(self, index, offset=0):
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000227 # Source 0 is argv.
228 if index.sourceId == 0:
229 return self.argv[index.pos + offset]
230
231 # Source 1 is synthetic argv.
232 if index.sourceId == 1:
233 return self.syntheticArgv[index.pos + offset]
234
235 raise RuntimeError,'Unknown source ID for index.'
236
Daniel Dunbar0fe5a4f2009-01-11 22:42:24 +0000237 def addLastArg(self, output, option):
238 """addLastArgs - Extend the given output vector with the last
239 instance of a given option."""
240 arg = self.getLastArg(option)
241 if arg:
242 output.extend(self.render(arg))
243
244 def addAllArgs(self, output, option):
245 """addAllArgs - Extend the given output vector with all
246 instances of a given option."""
247 for arg in self.getArgs(option):
248 output.extend(self.render(arg))
249
250 def addAllArgsTranslated(self, output, option, translation):
251 """addAllArgsTranslated - Extend the given output vector with
252 all instances of a given option, rendered as separate
253 arguments with the actual option name translated to a user
254 specified string. For example, '-foox' will be render as
255 ['-bar', 'x'] if '-foo' was the option and '-bar' was the
256 translation.
257
258 This routine expects that the option can only yield ValueArg
259 instances."""
260 for arg in self.getArgs(option):
261 assert isinstance(arg, ValueArg)
262 output.append(translation)
263 output.append(self.getValue(arg))
264
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000265 def makeIndex(self, *strings):
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000266 pos = len(self.syntheticArgv)
267 self.syntheticArgv.extend(strings)
268 return InputIndex(1, pos)
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000269
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000270 def makeFlagArg(self, option):
271 return Arg(self.makeIndex(option.name),
272 option)
273
274 def makeInputArg(self, string):
275 return PositionalArg(self.makeIndex(string),
276 self.parser.inputOption)
277
278 def makeUnknownArg(self, string):
279 return PositionalArg(self.makeIndex(string),
280 self.parser.unknownOption)
281
282 def makeSeparateArg(self, string, option):
283 return SeparateValueArg(self.makeIndex(option.name, string),
284 option)
285
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000286 # Support use as a simple arg list.
287
288 def __iter__(self):
289 return iter(self.args)
290
291 def append(self, arg):
292 self.args.append(arg)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000293 self.lastArgs[arg.opt] = arg
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000294
295 # Forwarding methods.
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000296 #
297 # FIXME: Clean this up once restructuring is done.
298
299 def render(self, arg):
300 return arg.render(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000301
302 def getValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000303 return arg.getValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000304
305 def getValues(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000306 return arg.getValues(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000307
308 def getSeparateValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000309 return arg.getSeparateValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000310
311 def getJoinedValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000312 return arg.getJoinedValue(self)
Daniel Dunbar1dd2ada2009-01-06 06:32:49 +0000313
314###
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000315
Daniel Dunbara5677512009-01-05 19:53:30 +0000316class OptionParser:
317 def __init__(self):
318 self.options = []
Daniel Dunbar5039f212009-01-06 02:30:10 +0000319 self.inputOption = InputOption()
320 self.unknownOption = UnknownOption()
321
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000322 # Driver driver options
323 self.archOption = self.addOption(SeparateOption('-arch'))
324
325 # Misc driver options
326 self.addOption(FlagOption('-pass-exit-codes'))
327 self.addOption(FlagOption('--help'))
328 self.addOption(FlagOption('--target-help'))
329
330 self.dumpspecsOption = self.addOption(FlagOption('-dumpspecs'))
331 self.dumpversionOption = self.addOption(FlagOption('-dumpversion'))
332 self.dumpmachineOption = self.addOption(FlagOption('-dumpmachine'))
333 self.printSearchDirsOption = self.addOption(FlagOption('-print-search-dirs'))
334 self.printLibgccFilenameOption = self.addOption(FlagOption('-print-libgcc-file-name'))
335 # FIXME: Hrm, where does this come from? It isn't always true that
336 # we take both - and --. For example, gcc --S ... ends up sending
337 # -fS to cc1. Investigate.
338 #
339 # FIXME: Need to implement some form of alias support inside
340 # getLastOption to handle this.
341 self.printLibgccFileNameOption2 = self.addOption(FlagOption('--print-libgcc-file-name'))
342 self.printFileNameOption = self.addOption(JoinedOption('-print-file-name='))
343 self.printProgNameOption = self.addOption(JoinedOption('-print-prog-name='))
344 self.printProgNameOption2 = self.addOption(JoinedOption('--print-prog-name='))
345 self.printMultiDirectoryOption = self.addOption(FlagOption('-print-multi-directory'))
346 self.printMultiLibOption = self.addOption(FlagOption('-print-multi-lib'))
347 self.addOption(FlagOption('-print-multi-os-directory'))
348
349 # Hmmm, who really takes this?
350 self.addOption(FlagOption('--version'))
351
352 # Pipeline control
353 self.hashHashHashOption = self.addOption(FlagOption('-###'))
354 self.EOption = self.addOption(FlagOption('-E'))
355 self.SOption = self.addOption(FlagOption('-S'))
356 self.cOption = self.addOption(FlagOption('-c'))
357 self.combineOption = self.addOption(FlagOption('-combine'))
358 self.noIntegratedCPPOption = self.addOption(FlagOption('-no-integrated-cpp'))
359 self.pipeOption = self.addOption(FlagOption('-pipe'))
360 self.saveTempsOption = self.addOption(FlagOption('-save-temps'))
361 self.saveTempsOption2 = self.addOption(FlagOption('--save-temps'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000362 # FIXME: Error out if this is used.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000363 self.addOption(JoinedOption('-specs='))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000364 # FIXME: Implement.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000365 self.addOption(FlagOption('-time'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000366 # FIXME: Implement.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000367 self.addOption(FlagOption('-v'))
368
369 # Input/output stuff
370 self.oOption = self.addOption(JoinedOrSeparateOption('-o'))
371 self.xOption = self.addOption(JoinedOrSeparateOption('-x'))
372
Daniel Dunbaree8cc262009-01-12 02:24:21 +0000373 self.ObjCOption = self.addOption(FlagOption('-ObjC'))
374 self.ObjCXXOption = self.addOption(FlagOption('-ObjC++'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000375
376 # FIXME: Weird, gcc claims this here in help but I'm not sure why;
377 # perhaps interaction with preprocessor? Investigate.
378 self.addOption(JoinedOption('-std='))
379 self.addOption(JoinedOrSeparateOption('--sysroot'))
380
381 # Version control
382 self.addOption(JoinedOrSeparateOption('-B'))
383 self.addOption(JoinedOrSeparateOption('-V'))
384 self.addOption(JoinedOrSeparateOption('-b'))
385
386 # Blanket pass-through options.
387
388 self.addOption(JoinedOption('-Wa,'))
389 self.addOption(SeparateOption('-Xassembler'))
390
391 self.addOption(JoinedOption('-Wp,'))
392 self.addOption(SeparateOption('-Xpreprocessor'))
393
394 self.addOption(JoinedOption('-Wl,'))
395 self.addOption(SeparateOption('-Xlinker'))
396
397 ####
398 # Bring on the random garbage.
399
400 self.addOption(FlagOption('-MD'))
401 self.addOption(FlagOption('-MP'))
402 self.addOption(FlagOption('-MM'))
403 self.addOption(JoinedOrSeparateOption('-MF'))
404 self.addOption(JoinedOrSeparateOption('-MT'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000405 self.MachOption = self.addOption(FlagOption('-Mach'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000406 self.addOption(FlagOption('-undef'))
407
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000408 self.wOption = self.addOption(FlagOption('-w'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000409 self.addOption(JoinedOrSeparateOption('-allowable_client'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000410 self.client_nameOption = self.addOption(JoinedOrSeparateOption('-client_name'))
411 self.compatibility_versionOption = self.addOption(JoinedOrSeparateOption('-compatibility_version'))
412 self.current_versionOption = self.addOption(JoinedOrSeparateOption('-current_version'))
413 self.dylinkerOption = self.addOption(FlagOption('-dylinker'))
414 self.dylinker_install_nameOption = self.addOption(JoinedOrSeparateOption('-dylinker_install_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000415 self.addOption(JoinedOrSeparateOption('-exported_symbols_list'))
416 self.addOption(JoinedOrSeparateOption('-idirafter'))
417 self.addOption(JoinedOrSeparateOption('-iquote'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000418 self.isysrootOption = self.addOption(JoinedOrSeparateOption('-isysroot'))
419 self.keep_private_externsOption = self.addOption(JoinedOrSeparateOption('-keep_private_externs'))
420 self.private_bundleOption = self.addOption(FlagOption('-private_bundle'))
421 self.seg1addrOption = self.addOption(JoinedOrSeparateOption('-seg1addr'))
422 self.segprotOption = self.addOption(JoinedOrSeparateOption('-segprot'))
423 self.sub_libraryOption = self.addOption(JoinedOrSeparateOption('-sub_library'))
424 self.sub_umbrellaOption = self.addOption(JoinedOrSeparateOption('-sub_umbrella'))
425 self.umbrellaOption = self.addOption(JoinedOrSeparateOption('-umbrella'))
426 self.undefinedOption = self.addOption(JoinedOrSeparateOption('-undefined'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000427 self.addOption(JoinedOrSeparateOption('-unexported_symbols_list'))
428 self.addOption(JoinedOrSeparateOption('-weak_framework'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000429 self.headerpad_max_install_namesOption = self.addOption(JoinedOption('-headerpad_max_install_names'))
430 self.twolevel_namespaceOption = self.addOption(FlagOption('-twolevel_namespace'))
431 self.twolevel_namespace_hintsOption = self.addOption(FlagOption('-twolevel_namespace_hints'))
432 self.prebindOption = self.addOption(FlagOption('-prebind'))
433 self.noprebindOption = self.addOption(FlagOption('-noprebind'))
434 self.nofixprebindingOption = self.addOption(FlagOption('-nofixprebinding'))
435 self.prebind_all_twolevel_modulesOption = self.addOption(FlagOption('-prebind_all_twolevel_modules'))
436 self.read_only_relocsOption = self.addOption(SeparateOption('-read_only_relocs'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000437 self.addOption(FlagOption('-single_module'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000438 self.nomultidefsOption = self.addOption(FlagOption('-nomultidefs'))
439 self.nostartfilesOption = self.addOption(FlagOption('-nostartfiles'))
440 self.nodefaultlibsOption = self.addOption(FlagOption('-nodefaultlibs'))
441 self.nostdlibOption = self.addOption(FlagOption('-nostdlib'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000442 self.addOption(FlagOption('-nostdinc'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000443 self.objectOption = self.addOption(FlagOption('-object'))
444 self.preloadOption = self.addOption(FlagOption('-preload'))
445 self.staticOption = self.addOption(FlagOption('-static'))
446 self.pagezero_sizeOption = self.addOption(FlagOption('-pagezero_size'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000447 self.addOption(FlagOption('-shared'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000448 self.staticLibgccOption = self.addOption(FlagOption('-static-libgcc'))
449 self.sharedLibgccOption = self.addOption(FlagOption('-shared-libgcc'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000450 self.addOption(FlagOption('-C'))
451 self.addOption(FlagOption('-CC'))
452 self.addOption(FlagOption('-R'))
453 self.addOption(FlagOption('-P'))
454 self.addOption(FlagOption('-all_load'))
455 self.addOption(FlagOption('--constant-cfstrings'))
456 self.addOption(FlagOption('-traditional'))
457 self.addOption(FlagOption('--traditional'))
458 self.addOption(FlagOption('-no_dead_strip_inits_and_terms'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000459 self.whyloadOption = self.addOption(FlagOption('-whyload'))
460 self.whatsloadedOption = self.addOption(FlagOption('-whatsloaded'))
461 self.sectalignOption = self.addOption(MultiArgOption('-sectalign', numArgs=3))
462 self.sectobjectsymbolsOption = self.addOption(MultiArgOption('-sectobjectsymbols', numArgs=2))
463 self.segcreateOption = self.addOption(MultiArgOption('-segcreate', numArgs=3))
464 self.segs_read_Option = self.addOption(JoinedOption('-segs_read_'))
465 self.seglinkeditOption = self.addOption(FlagOption('-seglinkedit'))
466 self.noseglinkeditOption = self.addOption(FlagOption('-noseglinkedit'))
467 self.sectcreateOption = self.addOption(MultiArgOption('-sectcreate', numArgs=3))
468 self.sectorderOption = self.addOption(MultiArgOption('-sectorder', numArgs=3))
469 self.Zall_loadOption = self.addOption(FlagOption('-Zall_load'))
470 self.Zallowable_clientOption = self.addOption(SeparateOption('-Zallowable_client'))
471 self.Zbind_at_loadOption = self.addOption(SeparateOption('-Zbind_at_load'))
472 self.ZbundleOption = self.addOption(FlagOption('-Zbundle'))
473 self.Zbundle_loaderOption = self.addOption(JoinedOrSeparateOption('-Zbundle_loader'))
474 self.Zdead_stripOption = self.addOption(FlagOption('-Zdead_strip'))
475 self.Zdylib_fileOption = self.addOption(JoinedOrSeparateOption('-Zdylib_file'))
476 self.ZdynamicOption = self.addOption(FlagOption('-Zdynamic'))
477 self.ZdynamiclibOption = self.addOption(FlagOption('-Zdynamiclib'))
478 self.Zexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zexported_symbols_list'))
479 self.Zflat_namespaceOption = self.addOption(FlagOption('-Zflat_namespace'))
480 self.Zfn_seg_addr_table_filenameOption = self.addOption(JoinedOrSeparateOption('-Zfn_seg_addr_table_filename'))
481 self.Zforce_cpusubtype_ALLOption = self.addOption(FlagOption('-Zforce_cpusubtype_ALL'))
482 self.Zforce_flat_namespaceOption = self.addOption(FlagOption('-Zforce_flat_namespace'))
483 self.Zimage_baseOption = self.addOption(FlagOption('-Zimage_base'))
484 self.ZinitOption = self.addOption(JoinedOrSeparateOption('-Zinit'))
485 self.Zmulti_moduleOption = self.addOption(FlagOption('-Zmulti_module'))
486 self.Zmultiply_definedOption = self.addOption(JoinedOrSeparateOption('-Zmultiply_defined'))
487 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
488 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
489 self.Zno_dead_strip_inits_and_termsOption = self.addOption(FlagOption('-Zno_dead_strip_inits_and_terms'))
490 self.Zseg_addr_tableOption = self.addOption(JoinedOrSeparateOption('-Zseg_addr_table'))
491 self.ZsegaddrOption = self.addOption(JoinedOrSeparateOption('-Zsegaddr'))
492 self.Zsegs_read_only_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_only_addr'))
493 self.Zsegs_read_write_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_write_addr'))
494 self.Zsingle_moduleOption = self.addOption(FlagOption('-Zsingle_module'))
Daniel Dunbar0fe5a4f2009-01-11 22:42:24 +0000495 self.ZumbrellaOption = self.addOption(JoinedOrSeparateOption('-Zumbrella'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000496 self.Zunexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zunexported_symbols_list'))
497 self.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000498
499 # I dunno why these don't end up working when joined. Maybe
500 # because of translation?
501 self.filelistOption = self.addOption(SeparateOption('-filelist'))
502 self.addOption(SeparateOption('-framework'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000503 # FIXME: Alias.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000504 self.addOption(SeparateOption('-install_name'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000505 self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000506 self.addOption(SeparateOption('-seg_addr_table'))
507 self.addOption(SeparateOption('-seg_addr_table_filename'))
508
509 # Where are these coming from? I can't find them...
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000510 self.eOption = self.addOption(JoinedOrSeparateOption('-e'))
511 self.rOption = self.addOption(JoinedOrSeparateOption('-r'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000512
513 # Is this actually declared anywhere? I can only find it in a
514 # spec. :(
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000515 self.pgOption = self.addOption(FlagOption('-pg'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000516
517 doNotReallySupport = 1
518 if doNotReallySupport:
519 # Archaic gcc option.
520 self.addOption(FlagOption('-cpp-precomp'))
521 self.addOption(FlagOption('-no-cpp-precomp'))
522
523 # C options for testing
524
525 self.addOption(JoinedOrSeparateOption('-include'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000526 self.AOption = self.addOption(SeparateOption('-A'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000527 self.addOption(JoinedOrSeparateOption('-D'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000528 self.FOption = self.addOption(JoinedOrSeparateOption('-F'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000529 self.addOption(JoinedOrSeparateOption('-I'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000530 self.LOption = self.addOption(JoinedOrSeparateOption('-L'))
531 self.TOption = self.addOption(JoinedOrSeparateOption('-T'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000532 self.addOption(JoinedOrSeparateOption('-U'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000533 self.ZOption = self.addOption(JoinedOrSeparateOption('-Z'))
534
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000535 self.addOption(JoinedOrSeparateOption('-l'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000536 self.uOption = self.addOption(JoinedOrSeparateOption('-u'))
537 self.tOption = self.addOption(JoinedOrSeparateOption('-t'))
538 self.yOption = self.addOption(JoinedOption('-y'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000539
540 # FIXME: What is going on here? '-X' goes to linker, and -X ... goes nowhere?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000541 self.XOption = self.addOption(FlagOption('-X'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000542 # Not exactly sure how to decompose this. I split out -Xarch_
543 # because we need to recognize that in the driver driver part.
544 # FIXME: Man, this is lame it needs its own option.
545 self.XarchOption = self.addOption(JoinedAndSeparateOption('-Xarch_'))
546 self.addOption(JoinedOption('-X'))
547
548 # The driver needs to know about this flag.
549 self.syntaxOnlyOption = self.addOption(FlagOption('-fsyntax-only'))
550
551 # FIXME: Wrong?
552 # FIXME: What to do about the ambiguity of options like
553 # -dumpspecs? How is this handled in gcc?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000554 # FIXME: Naming convention.
555 self.dOption = self.addOption(FlagOption('-d'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000556 self.addOption(JoinedOption('-d'))
557 self.addOption(JoinedOption('-g'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000558
559 self.f_exceptionsOption = self.addOption(FlagOption('-fexceptions'))
Daniel Dunbaree8cc262009-01-12 02:24:21 +0000560 self.f_objcOption = self.addOption(FlagOption('-fobjc'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000561 self.f_openmpOption = self.addOption(FlagOption('-fopenmp'))
562 self.f_gnuRuntimeOption = self.addOption(FlagOption('-fgnu-runtime'))
563 self.f_nestedFunctionsOption = self.addOption(FlagOption('-fnested-functions'))
564 self.f_pieOption = self.addOption(FlagOption('-fpie'))
565 self.f_profileArcsOption = self.addOption(FlagOption('-fprofile-arcs'))
566 self.f_profileGenerateOption = self.addOption(FlagOption('-fprofile-generate'))
567 self.f_createProfileOption = self.addOption(FlagOption('-fcreate-profile'))
568 self.coverageOption = self.addOption(FlagOption('-coverage'))
569 self.coverageOption2 = self.addOption(FlagOption('--coverage'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000570 self.addOption(JoinedOption('-f'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000571
572 self.m_32Option = self.addOption(FlagOption('-m32'))
573 self.m_64Option = self.addOption(FlagOption('-m64'))
574 self.m_iphoneosVersionMinOption = self.addOption(JoinedOption('-miphoneos-version-min='))
575 self.m_macosxVersionMinOption = self.addOption(JoinedOption('-mmacosx-version-min='))
576
577 # Ugh. Need to disambiguate our naming convetion. -m x goes to
578 # the linker sometimes, wheres -mxxxx is used for a variety of
579 # other things.
580 self.mOption = self.addOption(SeparateOption('-m'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000581 self.addOption(JoinedOption('-m'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000582
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000583 self.addOption(JoinedOption('-i'))
584 self.addOption(JoinedOption('-O'))
585 self.addOption(JoinedOption('-W'))
586 # FIXME: Weird. This option isn't really separate, --param=a=b
587 # works. An alias somewhere?
588 self.addOption(SeparateOption('--param'))
589
590 # FIXME: What is this? Seems to do something on Linux. I think
591 # only one is valid, but have a log that uses both.
592 self.addOption(FlagOption('-pthread'))
593 self.addOption(FlagOption('-pthreads'))
594
Daniel Dunbara5677512009-01-05 19:53:30 +0000595 def addOption(self, opt):
596 self.options.append(opt)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000597 return opt
Daniel Dunbara5677512009-01-05 19:53:30 +0000598
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000599 def parseArgs(self, argv):
Daniel Dunbara5677512009-01-05 19:53:30 +0000600 """
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000601 parseArgs([str]) -> ArgList
Daniel Dunbara5677512009-01-05 19:53:30 +0000602
603 Parse command line into individual option instances.
604 """
605
606 iargs = enumerate(argv)
607 it = iter(iargs)
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000608 args = ArgList(self, argv)
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000609 for pos,a in it:
610 i = InputIndex(0, pos)
Daniel Dunbara5677512009-01-05 19:53:30 +0000611 # FIXME: Handle '@'
612 if not a:
613 # gcc's handling of empty arguments doesn't make
614 # sense, but this is not a common use case. :)
615 #
616 # We just ignore them here (note that other things may
617 # still take them as arguments).
618 pass
619 elif a[0] == '-' and a != '-':
620 args.append(self.lookupOptForArg(i, a, it))
621 else:
Daniel Dunbar5039f212009-01-06 02:30:10 +0000622 args.append(PositionalArg(i, self.inputOption))
Daniel Dunbara5677512009-01-05 19:53:30 +0000623 return args
624
Daniel Dunbar5039f212009-01-06 02:30:10 +0000625 def lookupOptForArg(self, i, string, it):
626 for o in self.options:
627 arg = o.accept(i, string, it)
628 if arg is not None:
629 return arg
630 return PositionalArg(i, self.unknownOption)