//===-- 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)
{
    if (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(size_t idx) const
{
    VariableSP var_sp;
    if (idx < m_variables.size())
        var_sp = m_variables[idx];
    return var_sp;
}

VariableSP
VariableList::RemoveVariableAtIndex(size_t idx)
{
    VariableSP var_sp;
    if (idx < m_variables.size())
    {
        var_sp = m_variables[idx];
        m_variables.erase (m_variables.begin() + 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;
}

size_t
VariableList::AppendVariablesWithScope (lldb::ValueType type,
                                        VariableList &var_list,
                                        bool if_unique)
{
    const size_t initial_size = var_list.GetSize();
    iterator pos, end = m_variables.end();
    for (pos = m_variables.begin(); pos != end; ++pos)
    {
        if ((*pos)->GetScope() == type)
        {
            if (if_unique)
                var_list.AddVariableIfUnique (*pos);
            else
                var_list.AddVariable(*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);
    }
}
