blob: 6c543294bf86c908317185bd3b9a4a752fdba700 [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 Dunbar39cbfaa2009-01-07 18:54:26 +0000237 def makeIndex(self, *strings):
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000238 pos = len(self.syntheticArgv)
239 self.syntheticArgv.extend(strings)
240 return InputIndex(1, pos)
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000241
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000242 def makeFlagArg(self, option):
243 return Arg(self.makeIndex(option.name),
244 option)
245
246 def makeInputArg(self, string):
247 return PositionalArg(self.makeIndex(string),
248 self.parser.inputOption)
249
250 def makeUnknownArg(self, string):
251 return PositionalArg(self.makeIndex(string),
252 self.parser.unknownOption)
253
254 def makeSeparateArg(self, string, option):
255 return SeparateValueArg(self.makeIndex(option.name, string),
256 option)
257
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000258 # Support use as a simple arg list.
259
260 def __iter__(self):
261 return iter(self.args)
262
263 def append(self, arg):
264 self.args.append(arg)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000265 self.lastArgs[arg.opt] = arg
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000266
267 # Forwarding methods.
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000268 #
269 # FIXME: Clean this up once restructuring is done.
270
271 def render(self, arg):
272 return arg.render(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000273
274 def getValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000275 return arg.getValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000276
277 def getValues(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000278 return arg.getValues(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000279
280 def getSeparateValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000281 return arg.getSeparateValue(self)
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000282
283 def getJoinedValue(self, arg):
Daniel Dunbarfb2c5c42009-01-07 01:29:28 +0000284 return arg.getJoinedValue(self)
Daniel Dunbar1dd2ada2009-01-06 06:32:49 +0000285
286###
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000287
Daniel Dunbara5677512009-01-05 19:53:30 +0000288class OptionParser:
289 def __init__(self):
290 self.options = []
Daniel Dunbar5039f212009-01-06 02:30:10 +0000291 self.inputOption = InputOption()
292 self.unknownOption = UnknownOption()
293
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000294 # Driver driver options
295 self.archOption = self.addOption(SeparateOption('-arch'))
296
297 # Misc driver options
298 self.addOption(FlagOption('-pass-exit-codes'))
299 self.addOption(FlagOption('--help'))
300 self.addOption(FlagOption('--target-help'))
301
302 self.dumpspecsOption = self.addOption(FlagOption('-dumpspecs'))
303 self.dumpversionOption = self.addOption(FlagOption('-dumpversion'))
304 self.dumpmachineOption = self.addOption(FlagOption('-dumpmachine'))
305 self.printSearchDirsOption = self.addOption(FlagOption('-print-search-dirs'))
306 self.printLibgccFilenameOption = self.addOption(FlagOption('-print-libgcc-file-name'))
307 # FIXME: Hrm, where does this come from? It isn't always true that
308 # we take both - and --. For example, gcc --S ... ends up sending
309 # -fS to cc1. Investigate.
310 #
311 # FIXME: Need to implement some form of alias support inside
312 # getLastOption to handle this.
313 self.printLibgccFileNameOption2 = self.addOption(FlagOption('--print-libgcc-file-name'))
314 self.printFileNameOption = self.addOption(JoinedOption('-print-file-name='))
315 self.printProgNameOption = self.addOption(JoinedOption('-print-prog-name='))
316 self.printProgNameOption2 = self.addOption(JoinedOption('--print-prog-name='))
317 self.printMultiDirectoryOption = self.addOption(FlagOption('-print-multi-directory'))
318 self.printMultiLibOption = self.addOption(FlagOption('-print-multi-lib'))
319 self.addOption(FlagOption('-print-multi-os-directory'))
320
321 # Hmmm, who really takes this?
322 self.addOption(FlagOption('--version'))
323
324 # Pipeline control
325 self.hashHashHashOption = self.addOption(FlagOption('-###'))
326 self.EOption = self.addOption(FlagOption('-E'))
327 self.SOption = self.addOption(FlagOption('-S'))
328 self.cOption = self.addOption(FlagOption('-c'))
329 self.combineOption = self.addOption(FlagOption('-combine'))
330 self.noIntegratedCPPOption = self.addOption(FlagOption('-no-integrated-cpp'))
331 self.pipeOption = self.addOption(FlagOption('-pipe'))
332 self.saveTempsOption = self.addOption(FlagOption('-save-temps'))
333 self.saveTempsOption2 = self.addOption(FlagOption('--save-temps'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000334 # FIXME: Error out if this is used.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000335 self.addOption(JoinedOption('-specs='))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000336 # FIXME: Implement.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000337 self.addOption(FlagOption('-time'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000338 # FIXME: Implement.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000339 self.addOption(FlagOption('-v'))
340
341 # Input/output stuff
342 self.oOption = self.addOption(JoinedOrSeparateOption('-o'))
343 self.xOption = self.addOption(JoinedOrSeparateOption('-x'))
344
345 # FIXME: What do these actually do? The documentation is less than
346 # clear.
347 self.addOption(FlagOption('-ObjC'))
348 self.addOption(FlagOption('-ObjC++'))
349
350 # FIXME: Weird, gcc claims this here in help but I'm not sure why;
351 # perhaps interaction with preprocessor? Investigate.
352 self.addOption(JoinedOption('-std='))
353 self.addOption(JoinedOrSeparateOption('--sysroot'))
354
355 # Version control
356 self.addOption(JoinedOrSeparateOption('-B'))
357 self.addOption(JoinedOrSeparateOption('-V'))
358 self.addOption(JoinedOrSeparateOption('-b'))
359
360 # Blanket pass-through options.
361
362 self.addOption(JoinedOption('-Wa,'))
363 self.addOption(SeparateOption('-Xassembler'))
364
365 self.addOption(JoinedOption('-Wp,'))
366 self.addOption(SeparateOption('-Xpreprocessor'))
367
368 self.addOption(JoinedOption('-Wl,'))
369 self.addOption(SeparateOption('-Xlinker'))
370
371 ####
372 # Bring on the random garbage.
373
374 self.addOption(FlagOption('-MD'))
375 self.addOption(FlagOption('-MP'))
376 self.addOption(FlagOption('-MM'))
377 self.addOption(JoinedOrSeparateOption('-MF'))
378 self.addOption(JoinedOrSeparateOption('-MT'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000379 self.MachOption = self.addOption(FlagOption('-Mach'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000380 self.addOption(FlagOption('-undef'))
381
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000382 self.wOption = self.addOption(FlagOption('-w'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000383 self.addOption(JoinedOrSeparateOption('-allowable_client'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000384 self.client_nameOption = self.addOption(JoinedOrSeparateOption('-client_name'))
385 self.compatibility_versionOption = self.addOption(JoinedOrSeparateOption('-compatibility_version'))
386 self.current_versionOption = self.addOption(JoinedOrSeparateOption('-current_version'))
387 self.dylinkerOption = self.addOption(FlagOption('-dylinker'))
388 self.dylinker_install_nameOption = self.addOption(JoinedOrSeparateOption('-dylinker_install_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000389 self.addOption(JoinedOrSeparateOption('-exported_symbols_list'))
390 self.addOption(JoinedOrSeparateOption('-idirafter'))
391 self.addOption(JoinedOrSeparateOption('-iquote'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000392 self.isysrootOption = self.addOption(JoinedOrSeparateOption('-isysroot'))
393 self.keep_private_externsOption = self.addOption(JoinedOrSeparateOption('-keep_private_externs'))
394 self.private_bundleOption = self.addOption(FlagOption('-private_bundle'))
395 self.seg1addrOption = self.addOption(JoinedOrSeparateOption('-seg1addr'))
396 self.segprotOption = self.addOption(JoinedOrSeparateOption('-segprot'))
397 self.sub_libraryOption = self.addOption(JoinedOrSeparateOption('-sub_library'))
398 self.sub_umbrellaOption = self.addOption(JoinedOrSeparateOption('-sub_umbrella'))
399 self.umbrellaOption = self.addOption(JoinedOrSeparateOption('-umbrella'))
400 self.undefinedOption = self.addOption(JoinedOrSeparateOption('-undefined'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000401 self.addOption(JoinedOrSeparateOption('-unexported_symbols_list'))
402 self.addOption(JoinedOrSeparateOption('-weak_framework'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000403 self.headerpad_max_install_namesOption = self.addOption(JoinedOption('-headerpad_max_install_names'))
404 self.twolevel_namespaceOption = self.addOption(FlagOption('-twolevel_namespace'))
405 self.twolevel_namespace_hintsOption = self.addOption(FlagOption('-twolevel_namespace_hints'))
406 self.prebindOption = self.addOption(FlagOption('-prebind'))
407 self.noprebindOption = self.addOption(FlagOption('-noprebind'))
408 self.nofixprebindingOption = self.addOption(FlagOption('-nofixprebinding'))
409 self.prebind_all_twolevel_modulesOption = self.addOption(FlagOption('-prebind_all_twolevel_modules'))
410 self.read_only_relocsOption = self.addOption(SeparateOption('-read_only_relocs'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000411 self.addOption(FlagOption('-single_module'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000412 self.nomultidefsOption = self.addOption(FlagOption('-nomultidefs'))
413 self.nostartfilesOption = self.addOption(FlagOption('-nostartfiles'))
414 self.nodefaultlibsOption = self.addOption(FlagOption('-nodefaultlibs'))
415 self.nostdlibOption = self.addOption(FlagOption('-nostdlib'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000416 self.addOption(FlagOption('-nostdinc'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000417 self.objectOption = self.addOption(FlagOption('-object'))
418 self.preloadOption = self.addOption(FlagOption('-preload'))
419 self.staticOption = self.addOption(FlagOption('-static'))
420 self.pagezero_sizeOption = self.addOption(FlagOption('-pagezero_size'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000421 self.addOption(FlagOption('-shared'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000422 self.staticLibgccOption = self.addOption(FlagOption('-static-libgcc'))
423 self.sharedLibgccOption = self.addOption(FlagOption('-shared-libgcc'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000424 self.addOption(FlagOption('-C'))
425 self.addOption(FlagOption('-CC'))
426 self.addOption(FlagOption('-R'))
427 self.addOption(FlagOption('-P'))
428 self.addOption(FlagOption('-all_load'))
429 self.addOption(FlagOption('--constant-cfstrings'))
430 self.addOption(FlagOption('-traditional'))
431 self.addOption(FlagOption('--traditional'))
432 self.addOption(FlagOption('-no_dead_strip_inits_and_terms'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000433 self.whyloadOption = self.addOption(FlagOption('-whyload'))
434 self.whatsloadedOption = self.addOption(FlagOption('-whatsloaded'))
435 self.sectalignOption = self.addOption(MultiArgOption('-sectalign', numArgs=3))
436 self.sectobjectsymbolsOption = self.addOption(MultiArgOption('-sectobjectsymbols', numArgs=2))
437 self.segcreateOption = self.addOption(MultiArgOption('-segcreate', numArgs=3))
438 self.segs_read_Option = self.addOption(JoinedOption('-segs_read_'))
439 self.seglinkeditOption = self.addOption(FlagOption('-seglinkedit'))
440 self.noseglinkeditOption = self.addOption(FlagOption('-noseglinkedit'))
441 self.sectcreateOption = self.addOption(MultiArgOption('-sectcreate', numArgs=3))
442 self.sectorderOption = self.addOption(MultiArgOption('-sectorder', numArgs=3))
443 self.Zall_loadOption = self.addOption(FlagOption('-Zall_load'))
444 self.Zallowable_clientOption = self.addOption(SeparateOption('-Zallowable_client'))
445 self.Zbind_at_loadOption = self.addOption(SeparateOption('-Zbind_at_load'))
446 self.ZbundleOption = self.addOption(FlagOption('-Zbundle'))
447 self.Zbundle_loaderOption = self.addOption(JoinedOrSeparateOption('-Zbundle_loader'))
448 self.Zdead_stripOption = self.addOption(FlagOption('-Zdead_strip'))
449 self.Zdylib_fileOption = self.addOption(JoinedOrSeparateOption('-Zdylib_file'))
450 self.ZdynamicOption = self.addOption(FlagOption('-Zdynamic'))
451 self.ZdynamiclibOption = self.addOption(FlagOption('-Zdynamiclib'))
452 self.Zexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zexported_symbols_list'))
453 self.Zflat_namespaceOption = self.addOption(FlagOption('-Zflat_namespace'))
454 self.Zfn_seg_addr_table_filenameOption = self.addOption(JoinedOrSeparateOption('-Zfn_seg_addr_table_filename'))
455 self.Zforce_cpusubtype_ALLOption = self.addOption(FlagOption('-Zforce_cpusubtype_ALL'))
456 self.Zforce_flat_namespaceOption = self.addOption(FlagOption('-Zforce_flat_namespace'))
457 self.Zimage_baseOption = self.addOption(FlagOption('-Zimage_base'))
458 self.ZinitOption = self.addOption(JoinedOrSeparateOption('-Zinit'))
459 self.Zmulti_moduleOption = self.addOption(FlagOption('-Zmulti_module'))
460 self.Zmultiply_definedOption = self.addOption(JoinedOrSeparateOption('-Zmultiply_defined'))
461 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
462 self.ZmultiplydefinedunusedOption = self.addOption(JoinedOrSeparateOption('-Zmultiplydefinedunused'))
463 self.Zno_dead_strip_inits_and_termsOption = self.addOption(FlagOption('-Zno_dead_strip_inits_and_terms'))
464 self.Zseg_addr_tableOption = self.addOption(JoinedOrSeparateOption('-Zseg_addr_table'))
465 self.ZsegaddrOption = self.addOption(JoinedOrSeparateOption('-Zsegaddr'))
466 self.Zsegs_read_only_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_only_addr'))
467 self.Zsegs_read_write_addrOption = self.addOption(JoinedOrSeparateOption('-Zsegs_read_write_addr'))
468 self.Zsingle_moduleOption = self.addOption(FlagOption('-Zsingle_module'))
469 self.Zunexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zunexported_symbols_list'))
470 self.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000471
472 # I dunno why these don't end up working when joined. Maybe
473 # because of translation?
474 self.filelistOption = self.addOption(SeparateOption('-filelist'))
475 self.addOption(SeparateOption('-framework'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000476 # FIXME: Alias.
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000477 self.addOption(SeparateOption('-install_name'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000478 self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000479 self.addOption(SeparateOption('-seg_addr_table'))
480 self.addOption(SeparateOption('-seg_addr_table_filename'))
481
482 # Where are these coming from? I can't find them...
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000483 self.eOption = self.addOption(JoinedOrSeparateOption('-e'))
484 self.rOption = self.addOption(JoinedOrSeparateOption('-r'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000485
486 # Is this actually declared anywhere? I can only find it in a
487 # spec. :(
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000488 self.pgOption = self.addOption(FlagOption('-pg'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000489
490 doNotReallySupport = 1
491 if doNotReallySupport:
492 # Archaic gcc option.
493 self.addOption(FlagOption('-cpp-precomp'))
494 self.addOption(FlagOption('-no-cpp-precomp'))
495
496 # C options for testing
497
498 self.addOption(JoinedOrSeparateOption('-include'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000499 self.AOption = self.addOption(SeparateOption('-A'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000500 self.addOption(JoinedOrSeparateOption('-D'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000501 self.FOption = self.addOption(JoinedOrSeparateOption('-F'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000502 self.addOption(JoinedOrSeparateOption('-I'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000503 self.LOption = self.addOption(JoinedOrSeparateOption('-L'))
504 self.TOption = self.addOption(JoinedOrSeparateOption('-T'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000505 self.addOption(JoinedOrSeparateOption('-U'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000506 self.ZOption = self.addOption(JoinedOrSeparateOption('-Z'))
507
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000508 self.addOption(JoinedOrSeparateOption('-l'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000509 self.uOption = self.addOption(JoinedOrSeparateOption('-u'))
510 self.tOption = self.addOption(JoinedOrSeparateOption('-t'))
511 self.yOption = self.addOption(JoinedOption('-y'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000512
513 # FIXME: What is going on here? '-X' goes to linker, and -X ... goes nowhere?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000514 self.XOption = self.addOption(FlagOption('-X'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000515 # Not exactly sure how to decompose this. I split out -Xarch_
516 # because we need to recognize that in the driver driver part.
517 # FIXME: Man, this is lame it needs its own option.
518 self.XarchOption = self.addOption(JoinedAndSeparateOption('-Xarch_'))
519 self.addOption(JoinedOption('-X'))
520
521 # The driver needs to know about this flag.
522 self.syntaxOnlyOption = self.addOption(FlagOption('-fsyntax-only'))
523
524 # FIXME: Wrong?
525 # FIXME: What to do about the ambiguity of options like
526 # -dumpspecs? How is this handled in gcc?
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000527 # FIXME: Naming convention.
528 self.dOption = self.addOption(FlagOption('-d'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000529 self.addOption(JoinedOption('-d'))
530 self.addOption(JoinedOption('-g'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000531
532 self.f_exceptionsOption = self.addOption(FlagOption('-fexceptions'))
533 self.f_openmpOption = self.addOption(FlagOption('-fopenmp'))
534 self.f_gnuRuntimeOption = self.addOption(FlagOption('-fgnu-runtime'))
535 self.f_nestedFunctionsOption = self.addOption(FlagOption('-fnested-functions'))
536 self.f_pieOption = self.addOption(FlagOption('-fpie'))
537 self.f_profileArcsOption = self.addOption(FlagOption('-fprofile-arcs'))
538 self.f_profileGenerateOption = self.addOption(FlagOption('-fprofile-generate'))
539 self.f_createProfileOption = self.addOption(FlagOption('-fcreate-profile'))
540 self.coverageOption = self.addOption(FlagOption('-coverage'))
541 self.coverageOption2 = self.addOption(FlagOption('--coverage'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000542 self.addOption(JoinedOption('-f'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000543
544 self.m_32Option = self.addOption(FlagOption('-m32'))
545 self.m_64Option = self.addOption(FlagOption('-m64'))
546 self.m_iphoneosVersionMinOption = self.addOption(JoinedOption('-miphoneos-version-min='))
547 self.m_macosxVersionMinOption = self.addOption(JoinedOption('-mmacosx-version-min='))
548
549 # Ugh. Need to disambiguate our naming convetion. -m x goes to
550 # the linker sometimes, wheres -mxxxx is used for a variety of
551 # other things.
552 self.mOption = self.addOption(SeparateOption('-m'))
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000553 self.addOption(JoinedOption('-m'))
Daniel Dunbar6f5d65a2009-01-11 22:12:37 +0000554
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000555 self.addOption(JoinedOption('-i'))
556 self.addOption(JoinedOption('-O'))
557 self.addOption(JoinedOption('-W'))
558 # FIXME: Weird. This option isn't really separate, --param=a=b
559 # works. An alias somewhere?
560 self.addOption(SeparateOption('--param'))
561
562 # FIXME: What is this? Seems to do something on Linux. I think
563 # only one is valid, but have a log that uses both.
564 self.addOption(FlagOption('-pthread'))
565 self.addOption(FlagOption('-pthreads'))
566
Daniel Dunbara5677512009-01-05 19:53:30 +0000567 def addOption(self, opt):
568 self.options.append(opt)
Daniel Dunbarba6e3232009-01-06 06:12:13 +0000569 return opt
Daniel Dunbara5677512009-01-05 19:53:30 +0000570
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000571 def parseArgs(self, argv):
Daniel Dunbara5677512009-01-05 19:53:30 +0000572 """
Daniel Dunbar1e5f3eb2009-01-06 01:35:44 +0000573 parseArgs([str]) -> ArgList
Daniel Dunbara5677512009-01-05 19:53:30 +0000574
575 Parse command line into individual option instances.
576 """
577
578 iargs = enumerate(argv)
579 it = iter(iargs)
Daniel Dunbar39cbfaa2009-01-07 18:54:26 +0000580 args = ArgList(self, argv)
Daniel Dunbarefb4aeb2009-01-07 01:57:39 +0000581 for pos,a in it:
582 i = InputIndex(0, pos)
Daniel Dunbara5677512009-01-05 19:53:30 +0000583 # FIXME: Handle '@'
584 if not a:
585 # gcc's handling of empty arguments doesn't make
586 # sense, but this is not a common use case. :)
587 #
588 # We just ignore them here (note that other things may
589 # still take them as arguments).
590 pass
591 elif a[0] == '-' and a != '-':
592 args.append(self.lookupOptForArg(i, a, it))
593 else:
Daniel Dunbar5039f212009-01-06 02:30:10 +0000594 args.append(PositionalArg(i, self.inputOption))
Daniel Dunbara5677512009-01-05 19:53:30 +0000595 return args
596
Daniel Dunbar5039f212009-01-06 02:30:10 +0000597 def lookupOptForArg(self, i, string, it):
598 for o in self.options:
599 arg = o.accept(i, string, it)
600 if arg is not None:
601 return arg
602 return PositionalArg(i, self.unknownOption)