<commit_before>class Option(object):
    """Root option class."""
    def __init__(self, name):
        self.name = name

    def accept(self, index, arg, it):
        """accept(index, arg, iterator) -> Arg or None
        
        Accept the argument at the given index, returning an Arg, or
        return None if the option does not accept this argument.

        May raise MissingArgumentError.
        """
        abstract

    def __repr__(self):
        return '<%s name=%r>' % (self.__class__.__name__,
                                 self.name)

# Dummy options

class InputOption(Option):
    def __init__(self):
        super(InputOption, self).__init__('<input>')

    def accept(self):
        raise RuntimeError,"accept() should never be used on InputOption instance."

class UnknownOption(Option):
    def __init__(self):
        super(UnknownOption, self).__init__('<unknown>')

    def accept(self):
        raise RuntimeError,"accept() should never be used on UnknownOption instance."        

# Normal options

class FlagOption(Option):
    """An option which takes no arguments."""

    def accept(self, index, arg, it):
        if arg == self.name:
            return Arg(index, self)

class JoinedOption(Option):
    """An option which literally prefixes its argument."""

    def accept(self, index, arg, it):        
        if arg.startswith(self.name):
            return JoinedValueArg(index, self)

class SeparateOption(Option):
    """An option which is followed by its value."""

    def accept(self, index, arg, it):
        if arg == self.name:
            try:
                _,value = it.next()
            except StopIteration:
                raise MissingArgumentError,self
            return SeparateValueArg(index, self)

class MultiArgOption(Option):
    """An option which takes multiple arguments."""

    def __init__(self, name, numArgs):
        assert numArgs > 1
        super(MultiArgOption, self).__init__(name)
        self.numArgs = numArgs

    def accept(self, index, arg, it):
        if arg.startswith(self.name):
            try:
                values = [it.next()[1] for i in range(self.numArgs)]
            except StopIteration:
                raise MissingArgumentError,self
            return MultipleValuesArg(index, self)

class JoinedOrSeparateOption(Option):
    """An option which either literally prefixes its value or is
    followed by an value."""

    def accept(self, index, arg, it):
        if arg.startswith(self.name):
            if len(arg) != len(self.name): # Joined case
                return JoinedValueArg(index, self)
            else:
                try:
                    _,value = it.next()
                except StopIteration:
                    raise MissingArgumentError,self
                return SeparateValueArg(index, self)

class JoinedAndSeparateOption(Option):
    """An option which literally prefixes its value and is followed by
    an value."""

    def accept(self, index, arg, it):
        if arg.startswith(self.name):
            try:
                _,value = it.next()
            except StopIteration:
                raise MissingArgumentError,self
            return JoinedAndSeparateValuesArg(index, self)

###

class Arg(object):
    """Arg - Base class for actual driver arguments."""
    def __init__(self, index, opt):
        assert opt is not None
        self.index = index
        self.opt = opt
        
    def __repr__(self):
        return '<%s index=%r opt=%r>' % (self.__class__.__name__,
                                         self.index,
                                         self.opt)

    def render(self, args):
        """render(args) -> [str]

        Map the argument into a list of actual program arguments,
        given the source argument array."""
        assert self.opt
        return [self.opt.name]

class ValueArg(Arg):
    """ValueArg - An instance of an option which has an argument."""

    def getValue(self, args):
        abstract

    def setValue(self, args, value):
        abstract

class PositionalArg(ValueArg):
    """PositionalArg - A simple positional argument."""

    def getValue(self, args):
        return args[self.index]
    
    def setValue(self, args, value):
        args[self.index] = value

    def render(self, args):
        return [args[self.index]]

class JoinedValueArg(ValueArg):
    """JoinedValueArg - A single value argument where the value is
    joined (suffixed) to the option."""

    def getValue(self, args):
        return args[self.index][len(self.opt.name):]

    def setValue(self, args, value):
        assert self.opt.name == args[self.index][:len(self.opt.name)]
        args[self.index] = self.opt.name + value

    def render(self, args):
        return [self.opt.name + self.getValue(args)]

class SeparateValueArg(ValueArg):
    """SeparateValueArg - A single value argument where the value
    follows the option in the argument vector."""

    def getValue(self, args):
        return args[self.index+1]

    def setValue(self, args, value):
        args[self.index+1] = value

    def render(self, args):
        return [self.opt.name, self.getValue(args)]

class MultipleValuesArg(Arg):
    """MultipleValuesArg - An argument with multiple values which
    follow the option in the argument vector."""

    # FIXME: Should we unify this with SeparateValueArg?

    def getValues(self, args):
        return args[self.index + 1:self.index + 1 + self.opt.numArgs]

    def setValues(self, args, value):
        assert self.opt.numArgs == len(value)
        args[self.index + 1:self.index + 1 + self.opt.numArgs] = value

    def render(self, args):
        return [self.opt.name] + self.getValues(args)

# FIXME: Man, this is lame. It is only used by -Xarch. Maybe easier to
# just special case?
class JoinedAndSeparateValuesArg(Arg):
    """JoinedAndSeparateValuesArg - An argument with both joined and
    separate values."""

    def getJoinedValue(self, args):
        return args[self.index][len(self.opt.name):]

    def getSeparateValue(self, args):
        return args[self.index+1]

    def setJoinedValue(self, args, value):
        assert self.opt.name == args[self.index][:len(self.opt.name)]
        args[self.index] = self.opt.name + value
        
    def setSeparateValue(self, args, vaue):
        args[self.index+1] = value

    def render(self, args):
        return ([self.opt.name + self.getJoinedValue(args)] + 
                [self.getSeparateValue(args)])

class DerivedArg(ValueArg):
    """DerivedArg - A synthesized argument which does not correspend
    to an item in the argument vector."""

    def __init__(self, value):
        # FIXME: The UnknownOption() here is a total hack so we can
        # rely on arg.opt not being nil. Ok for now since DerivedArg
        # is dying.
        super(DerivedArg, self).__init__(-1, UnknownOption())
        self.value = value

    def getValue(self, args):
        return self.value

    def setValue(self, args, value):
        raise ValueError,"Cannot call setValue() on a DerivedArg."
    
    def render(self, args):
        return [self.value]

class ArgList:
    """ArgList - Collect an input argument vector along with a set of parsed Args
    and supporting information."""

    def __init__(self, argv):
        self.argv = list(argv)
        self.args = []
        self.lastArgs = {}

    def getLastArg(self, option):
        return self.lastArgs.get(option)

    # Support use as a simple arg list.

    def __iter__(self):
        return iter(self.args)

    def append(self, arg):
        self.args.append(arg)
        self.lastArgs[arg.opt] = arg

    # Forwarding methods.

    def getValue(self, arg):
        return arg.getValue(self.argv)

    def getValues(self, arg):
        return arg.getValues(self.argv)

    def getSeparateValue(self, arg):
        return arg.getSeparateValue(self.argv)

    def getJoinedValue(self, arg):
        return arg.getJoinedValue(self.argv)
    
class OptionParser:
    def __init__(self):
        self.options = []
        self.inputOption = InputOption()
        self.unknownOption = UnknownOption()

        # Driver driver options
        self.archOption = self.addOption(SeparateOption('-arch'))

        # Misc driver options
        self.addOption(FlagOption('-pass-exit-codes'))
        self.addOption(FlagOption('--help'))
        self.addOption(FlagOption('--target-help'))

        self.dumpspecsOption = self.addOption(FlagOption('-dumpspecs'))
        self.dumpversionOption = self.addOption(FlagOption('-dumpversion'))
        self.dumpmachineOption = self.addOption(FlagOption('-dumpmachine'))
        self.printSearchDirsOption = self.addOption(FlagOption('-print-search-dirs'))
        self.printLibgccFilenameOption = self.addOption(FlagOption('-print-libgcc-file-name'))
        # FIXME: Hrm, where does this come from? It isn't always true that
        # we take both - and --. For example, gcc --S ... ends up sending
        # -fS to cc1. Investigate.<commit_msg>ccc: Remove ValueArg::setValue, this is no longer used.<commit_after>class Option(object):
    """Root option class."""
    def __init__(self, name):
        self.name = name

    def accept(self, index, arg, it):
        """accept(index, arg, iterator) -> Arg or None
        
        Accept the argument at the given index, returning an Arg, or
        return None if the option does not accept this argument.

        May raise MissingArgumentError.
        """
        abstract

    def __repr__(self):
        return '<%s name=%r>' % (self.__class__.__name__,
                                 self.name)

# Dummy options

class InputOption(Option):
    def __init__(self):
        super(InputOption, self).__init__('<input>')

    def accept(self):
        raise RuntimeError,"accept() should never be used on InputOption instance."

class UnknownOption(Option):
    def __init__(self):
        super(UnknownOption, self).__init__('<unknown>')

    def accept(self):
        raise RuntimeError,"accept() should never be used on UnknownOption instance."        

# Normal options

class FlagOption(Option):
    """An option which takes no arguments."""

    def accept(self, index, arg, it):
        if arg == self.name:
            return Arg(index, self)

class JoinedOption(Option):
    """An option which literally prefixes its argument."""

    def accept(self, index, arg, it):        
        if arg.startswith(self.name):
            return JoinedValueArg(index, self)

class SeparateOption(Option):
    """An option which is followed by its value."""

    def accept(self, index, arg, it):
        if arg == self.name:
            try:
                _,value = it.next()
            except StopIteration:
                raise MissingArgumentError,self
            return SeparateValueArg(index, self)

class MultiArgOption(Option):
    """An option which takes multiple arguments."""

    def __init__(self, name, numArgs):
        assert numArgs > 1
        super(MultiArgOption, self).__init__(name)
        self.numArgs = numArgs

    def accept(self, index, arg, it):
        if arg.startswith(self.name):
            try:
                values = [it.next()[1] for i in range(self.numArgs)]
            except StopIteration:
                raise MissingArgumentError,self
            return MultipleValuesArg(index, self)

class JoinedOrSeparateOption(Option):
    """An option which either literally prefixes its value or is
    followed by an value."""

    def accept(self, index, arg, it):
        if arg.startswith(self.name):
            if len(arg) != len(self.name): # Joined case
                return JoinedValueArg(index, self)
            else:
                try:
                    _,value = it.next()
                except StopIteration:
                    raise MissingArgumentError,self
                return SeparateValueArg(index, self)

class JoinedAndSeparateOption(Option):
    """An option which literally prefixes its value and is followed by
    an value."""

    def accept(self, index, arg, it):
        if arg.startswith(self.name):
            try:
                _,value = it.next()
            except StopIteration:
                raise MissingArgumentError,self
            return JoinedAndSeparateValuesArg(index, self)

###

class Arg(object):
    """Arg - Base class for actual driver arguments."""
    def __init__(self, index, opt):
        assert opt is not None
        self.index = index
        self.opt = opt
        
    def __repr__(self):
        return '<%s index=%r opt=%r>' % (self.__class__.__name__,
                                         self.index,
                                         self.opt)

    def render(self, args):
        """render(args) -> [str]

        Map the argument into a list of actual program arguments,
        given the source argument array."""
        assert self.opt
        return [self.opt.name]

class ValueArg(Arg):
    """ValueArg - An instance of an option which has an argument."""

    def getValue(self, args):
        abstract

class PositionalArg(ValueArg):
    """PositionalArg - A simple positional argument."""

    def getValue(self, args):
        return args[self.index]

    def render(self, args):
        return [args[self.index]]

class JoinedValueArg(ValueArg):
    """JoinedValueArg - A single value argument where the value is
    joined (suffixed) to the option."""

    def getValue(self, args):
        return args[self.index][len(self.opt.name):]

    def render(self, args):
        return [self.opt.name + self.getValue(args)]

class SeparateValueArg(ValueArg):
    """SeparateValueArg - A single value argument where the value
    follows the option in the argument vector."""

    def getValue(self, args):
        return args[self.index+1]

    def render(self, args):
        return [self.opt.name, self.getValue(args)]

class MultipleValuesArg(Arg):
    """MultipleValuesArg - An argument with multiple values which
    follow the option in the argument vector."""

    # FIXME: Should we unify this with SeparateValueArg?

    def getValues(self, args):
        return args[self.index + 1:self.index + 1 + self.opt.numArgs]

    def render(self, args):
        return [self.opt.name] + self.getValues(args)

# FIXME: Man, this is lame. It is only used by -Xarch. Maybe easier to
# just special case?
class JoinedAndSeparateValuesArg(Arg):
    """JoinedAndSeparateValuesArg - An argument with both joined and
    separate values."""

    def getJoinedValue(self, args):
        return args[self.index][len(self.opt.name):]

    def getSeparateValue(self, args):
        return args[self.index+1]

    def setJoinedValue(self, args, value):
        assert self.opt.name == args[self.index][:len(self.opt.name)]
        args[self.index] = self.opt.name + value
        
    def setSeparateValue(self, args, vaue):
        args[self.index+1] = value

    def render(self, args):
        return ([self.opt.name + self.getJoinedValue(args)] + 
                [self.getSeparateValue(args)])

class DerivedArg(ValueArg):
    """DerivedArg - A synthesized argument which does not correspend
    to an item in the argument vector."""

    def __init__(self, value):
        # FIXME: The UnknownOption() here is a total hack so we can
        # rely on arg.opt not being nil. Ok for now since DerivedArg
        # is dying.
        super(DerivedArg, self).__init__(-1, UnknownOption())
        self.value = value

    def getValue(self, args):
        return self.value

    def render(self, args):
        return [self.value]

class ArgList:
    """ArgList - Collect an input argument vector along with a set of parsed Args
    and supporting information."""

    def __init__(self, argv):
        self.argv = list(argv)
        self.args = []
        self.lastArgs = {}

    def getLastArg(self, option):
        return self.lastArgs.get(option)

    # Support use as a simple arg list.

    def __iter__(self):
        return iter(self.args)

    def append(self, arg):
        self.args.append(arg)
        self.lastArgs[arg.opt] = arg

    # Forwarding methods.

    def getValue(self, arg):
        return arg.getValue(self.argv)

    def getValues(self, arg):
        return arg.getValues(self.argv)

    def getSeparateValue(self, arg):
        return arg.getSeparateValue(self.argv)

    def getJoinedValue(self, arg):
        return arg.getJoinedValue(self.argv)

###
    
class OptionParser:
    def __init__(self):
        self.options = []
        self.inputOption = InputOption()
        self.unknownOption = UnknownOption()

        # Driver driver options
        self.archOption = self.addOption(SeparateOption('-arch'))

        # Misc driver options
        self.addOption(FlagOption('-pass-exit-codes'))
        self.addOption(FlagOption('--help'))
        self.addOption(FlagOption('--target-help'))

        self.dumpspecsOption = self.addOption(FlagOption('-dumpspecs'))
        self.dumpversionOption = self.addOption(FlagOption('-dumpversion'))
        self.dumpmachineOption = self.addOption(FlagOption('-dumpmachine'))
        self.printSearchDirsOption = self.addOption(FlagOption('-print-search-dirs'))
        self.printLibgccFilenameOption = self.addOption(FlagOption('-print-libgcc-file-name'))
        # FIXME: Hrm, where does this come from? It isn't always true that
        # we take both - and --. For example, gcc --S ... ends up sending
        # -fS to cc1. Investigate.
{'fraction_non_alphanumeric': 0.10831998168917373, 'fraction_numerical': 0.0012016479743648433, 'mean_word_length': 2.4054949337490257, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1757974', 'n_tokens_mistral': 5012, 'n_tokens_neox': 4820, 'n_words': 1450}