//===-- VariableList.cpp ----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Symbol/VariableList.h"

#include "lldb/Core/RegularExpression.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/CompileUnit.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// VariableList constructor
//----------------------------------------------------------------------
VariableList::VariableList() :
    m_variables()
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
VariableList::~VariableList()
{
}

void
VariableList::AddVariable(const VariableSP &var_sp)
{
    m_variables.push_back(var_sp);
}

bool
VariableList::AddVariableIfUnique (const lldb::VariableSP &var_sp)
{
    if (FindVariableIndex (var_sp) == UINT32_MAX)
    {
        m_variables.push_back(var_sp);
        return true;
    }
    return false;
}

void
VariableList::AddVariables(VariableList *variable_list)
{
    std::copy(  variable_list->m_variables.begin(), // source begin
                variable_list->m_variables.end(),   // source end
                back_inserter(m_variables));        // destination
}

void
VariableList::Clear()
{
    m_variables.clear();
}

VariableSP
VariableList::GetVariableAtIndex(uint32_t idx)
{
    VariableSP var_sp;
    if (idx < m_variables.size())
        var_sp = m_variables[idx];
    return var_sp;
}

uint32_t
VariableList::FindVariableIndex (const VariableSP &var_sp)
{
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if (pos->get() == var_sp.get())
            return std::distance (m_variables.begin(), pos);
    }
    return UINT32_MAX;
}

VariableSP
VariableList::FindVariable(const ConstString& name)
{
    VariableSP var_sp;
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if ((*pos)->NameMatches(name))
        {
            var_sp = (*pos);
            break;
        }
    }
    return var_sp;
}

size_t
VariableList::AppendVariablesIfUnique (const RegularExpression& regex, VariableList &var_list, size_t& total_matches)
{
    const size_t initial_size = var_list.GetSize();
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if ((*pos)->NameMatches (regex))
        {
            // Note the total matches found
            total_matches++;
            // Only add this variable if it isn't already in the "var_list"
            var_list.AddVariableIfUnique (*pos);
        }
    }
    // Return the number of new unique variables added to "var_list"
    return var_list.GetSize() - initial_size;
}

uint32_t
VariableList::FindIndexForVariable (Variable* variable)
{
    VariableSP var_sp;
    iterator pos;
    const iterator begin = m_variables.begin();
    const iterator end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if ((*pos).get() == variable)
            return std::distance (begin, pos);
    }
    return UINT32_MAX;
}

size_t
VariableList::MemorySize() const
{
    size_t mem_size = sizeof(VariableList);
    const_iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
        mem_size += (*pos)->MemorySize();
    return mem_size;
}

size_t
VariableList::GetSize() const
{
    return m_variables.size();
}

void
VariableList::Dump(Stream *s, bool show_context) const
{
//  s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
//  s.Indent();
//  s << "VariableList\n";

    const_iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        (*pos)->Dump(s, show_context);
    }
}

