//===--- ArgList.cpp - Argument List Management -------------------------*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Driver/ArgList.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/Option.h"

using namespace clang::driver;

ArgList::ArgList(arglist_type &_Args) : Args(_Args) {
}

ArgList::~ArgList() {
}

void ArgList::append(Arg *A) {
  Args.push_back(A);
}

Arg *ArgList::getLastArg(options::ID Id, bool Claim) const {
  // FIXME: Make search efficient?
  for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) {
    if ((*it)->getOption().matches(Id)) {
      if (Claim) (*it)->claim();
      return *it;
    }
  }
  
  return 0;
}

Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
  Arg *Res, *A0 = getLastArg(Id0, false), *A1 = getLastArg(Id1, false);
  
  if (A0 && A1)
    Res = A0->getIndex() > A1->getIndex() ? A0 : A1;
  else
    Res = A0 ? A0 : A1;

  if (Claim && Res)
    Res->claim();

  return Res;
}

Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
                         bool Claim) const {
  Arg *Res = 0;
  Arg *A0 = getLastArg(Id0, false);
  Arg *A1 = getLastArg(Id1, false);
  Arg *A2 = getLastArg(Id2, false);

  int A0Idx = A0 ? A0->getIndex() : -1;
  int A1Idx = A1 ? A1->getIndex() : -1;
  int A2Idx = A2 ? A2->getIndex() : -1;

  if (A0Idx > A1Idx) {
    if (A0Idx > A2Idx)
      Res = A0;
    else if (A2Idx != -1)
      Res = A2;
  } else {
    if (A1Idx > A2Idx)
      Res = A1;
    else if (A2Idx != -1)
      Res = A2;
  }

  if (Claim && Res)
    Res->claim();

  return Res;
}

bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
  if (Arg *A = getLastArg(Pos, Neg))
    return A->getOption().matches(Pos);
  return Default;
}

void ArgList::AddLastArg(ArgStringList &Output, options::ID Id) const {
  if (Arg *A = getLastArg(Id)) {
    A->claim();
    A->render(*this, Output);
  }
}

void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0) const {
  // FIXME: Make fast.
  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    const Arg *A = *it;
    if (A->getOption().matches(Id0)) {
      A->claim();
      A->render(*this, Output);
    }
  }
}

void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0, 
                         options::ID Id1) const {
  // FIXME: Make fast.
  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    const Arg *A = *it;
    if (A->getOption().matches(Id0) || A->getOption().matches(Id1)) {
      A->claim();
      A->render(*this, Output);
    }
  }
}

void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0, 
                         options::ID Id1, options::ID Id2) const {
  // FIXME: Make fast.
  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    const Arg *A = *it;
    if (A->getOption().matches(Id0) || A->getOption().matches(Id1) ||
        A->getOption().matches(Id2)) {
      A->claim();
      A->render(*this, Output);
    }
  }
}

void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const {
  // FIXME: Make fast.
  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    const Arg *A = *it;
    if (A->getOption().matches(Id0)) {
      A->claim();
      for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
        Output.push_back(A->getValue(*this, i));
    }
  }
}

void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0, 
                              options::ID Id1) const {
  // FIXME: Make fast.
  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    const Arg *A = *it;
    if (A->getOption().matches(Id0) || A->getOption().matches(Id1)) {
      A->claim();
      for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
        Output.push_back(A->getValue(*this, i));
    }
  }
}

void ArgList::AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
                                   const char *Translation,
                                   bool Joined) const {
  // FIXME: Make fast.
  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    const Arg *A = *it;
    if (A->getOption().matches(Id0)) {
      A->claim();

      if (Joined) {
        std::string Value = Translation;
        Value += A->getValue(*this, 0);
        Output.push_back(MakeArgString(Value.c_str()));
      } else {
        Output.push_back(Translation);
        Output.push_back(A->getValue(*this, 0));
      }
    }
  }
}

void ArgList::ClaimAllArgs(options::ID Id0) const {
  // FIXME: Make fast.
  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    const Arg *A = *it;
    if (A->getOption().matches(Id0))
      A->claim();
  }
}

//

InputArgList::InputArgList(const char **ArgBegin, const char **ArgEnd) 
  : ArgList(ActualArgs), NumInputArgStrings(ArgEnd - ArgBegin) 
{
  ArgStrings.append(ArgBegin, ArgEnd);
}

InputArgList::~InputArgList() {
  // An InputArgList always owns its arguments.
  for (iterator it = begin(), ie = end(); it != ie; ++it)
    delete *it;
}

unsigned InputArgList::MakeIndex(const char *String0) const {
  unsigned Index = ArgStrings.size();

  // Tuck away so we have a reliable const char *.
  SynthesizedStrings.push_back(String0);
  ArgStrings.push_back(SynthesizedStrings.back().c_str());

  return Index;
}

unsigned InputArgList::MakeIndex(const char *String0, 
                                 const char *String1) const {
  unsigned Index0 = MakeIndex(String0);
  unsigned Index1 = MakeIndex(String1);
  assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
  (void) Index1;
  return Index0;
}

const char *InputArgList::MakeArgString(const char *Str) const {
  return getArgString(MakeIndex(Str));
}

//

DerivedArgList::DerivedArgList(InputArgList &_BaseArgs, bool _OnlyProxy)
  : ArgList(_OnlyProxy ? _BaseArgs.getArgs() : ActualArgs),
    BaseArgs(_BaseArgs), OnlyProxy(_OnlyProxy)
{
}

DerivedArgList::~DerivedArgList() {
  // We only own the arguments we explicitly synthesized.
  for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end(); 
       it != ie; ++it)
    delete *it;
}

const char *DerivedArgList::MakeArgString(const char *Str) const {
  return BaseArgs.MakeArgString(Str);
}

Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
  return new FlagArg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
}

Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt, 
                                       const char *Value) const {
  return new PositionalArg(Opt, BaseArgs.MakeIndex(Value), BaseArg);
}

Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt, 
                                     const char *Value) const {
  return new SeparateArg(Opt, BaseArgs.MakeIndex(Opt->getName(), Value), 1, 
                         BaseArg);
}

Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt, 
                                   const char *Value) const {
  std::string Joined(Opt->getName());
  Joined += Value;
  return new JoinedArg(Opt, BaseArgs.MakeIndex(Joined.c_str()), BaseArg);
}
