Home | History | Annotate | Download | only in Interpreter
      1 //===-- OptionValueFileSpecList.cpp -----------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/Interpreter/OptionValueFileSpecList.h"
     11 
     12 // C Includes
     13 // C++ Includes
     14 // Other libraries and framework includes
     15 // Project includes
     16 #include "lldb/Core/Stream.h"
     17 #include "lldb/Interpreter/Args.h"
     18 
     19 using namespace lldb;
     20 using namespace lldb_private;
     21 
     22 void
     23 OptionValueFileSpecList::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
     24 {
     25     if (dump_mask & eDumpOptionType)
     26         strm.Printf ("(%s)", GetTypeAsCString ());
     27     if (dump_mask & eDumpOptionValue)
     28     {
     29         if (dump_mask & eDumpOptionType)
     30             strm.Printf (" =%s", m_current_value.GetSize() > 0 ? "\n" : "");
     31         strm.IndentMore();
     32         const uint32_t size = m_current_value.GetSize();
     33         for (uint32_t i = 0; i<size; ++i)
     34         {
     35             strm.Indent();
     36             strm.Printf("[%u]: ", i);
     37             m_current_value.GetFileSpecAtIndex(i).Dump(&strm);
     38         }
     39         strm.IndentLess();
     40     }
     41 }
     42 
     43 Error
     44 OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperationType op)
     45 {
     46     Error error;
     47     Args args(value);
     48     const size_t argc = args.GetArgumentCount();
     49 
     50     switch (op)
     51     {
     52         case eVarSetOperationClear:
     53             Clear ();
     54             break;
     55 
     56         case eVarSetOperationReplace:
     57             if (argc > 1)
     58             {
     59                 uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
     60                 const uint32_t count = m_current_value.GetSize();
     61                 if (idx > count)
     62                 {
     63                     error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
     64                 }
     65                 else
     66                 {
     67                     for (size_t i=1; i<argc; ++i, ++idx)
     68                     {
     69                         FileSpec file (args.GetArgumentAtIndex(i), false);
     70                         if (idx < count)
     71                             m_current_value.Replace(idx, file);
     72                         else
     73                             m_current_value.Append(file);
     74                     }
     75                 }
     76             }
     77             else
     78             {
     79                 error.SetErrorString("replace operation takes an array index followed by one or more values");
     80             }
     81             break;
     82 
     83 
     84 
     85         case eVarSetOperationAssign:
     86             m_current_value.Clear();
     87             // Fall through to append case
     88         case eVarSetOperationAppend:
     89             if (argc > 0)
     90             {
     91                 m_value_was_set = true;
     92                 for (size_t i=0; i<argc; ++i)
     93                 {
     94                     FileSpec file (args.GetArgumentAtIndex(i), false);
     95                     m_current_value.Append(file);
     96                 }
     97             }
     98             else
     99             {
    100                 error.SetErrorString("assign operation takes at least one file path argument");
    101             }
    102             break;
    103 
    104         case eVarSetOperationInsertBefore:
    105         case eVarSetOperationInsertAfter:
    106             if (argc > 1)
    107             {
    108                 uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
    109                 const uint32_t count = m_current_value.GetSize();
    110                 if (idx > count)
    111                 {
    112                     error.SetErrorStringWithFormat("invalid insert file list index %u, index must be 0 through %u", idx, count);
    113                 }
    114                 else
    115                 {
    116                     if (op == eVarSetOperationInsertAfter)
    117                         ++idx;
    118                     for (size_t i=1; i<argc; ++i, ++idx)
    119                     {
    120                         FileSpec file (args.GetArgumentAtIndex(i), false);
    121                         m_current_value.Insert (idx, file);
    122                     }
    123                 }
    124             }
    125             else
    126             {
    127                 error.SetErrorString("insert operation takes an array index followed by one or more values");
    128             }
    129             break;
    130 
    131         case eVarSetOperationRemove:
    132             if (argc > 0)
    133             {
    134                 std::vector<int> remove_indexes;
    135                 bool all_indexes_valid = true;
    136                 size_t i;
    137                 for (i=0; all_indexes_valid && i<argc; ++i)
    138                 {
    139                     const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
    140                     if (idx == INT32_MAX)
    141                         all_indexes_valid = false;
    142                     else
    143                         remove_indexes.push_back(idx);
    144                 }
    145 
    146                 if (all_indexes_valid)
    147                 {
    148                     size_t num_remove_indexes = remove_indexes.size();
    149                     if (num_remove_indexes)
    150                     {
    151                         // Sort and then erase in reverse so indexes are always valid
    152                         std::sort(remove_indexes.begin(), remove_indexes.end());
    153                         for (size_t j=num_remove_indexes-1; j<num_remove_indexes; ++j)
    154                         {
    155                             m_current_value.Remove (j);
    156                         }
    157                     }
    158                 }
    159                 else
    160                 {
    161                     error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i));
    162                 }
    163             }
    164             else
    165             {
    166                 error.SetErrorString("remove operation takes one or more array index");
    167             }
    168             break;
    169 
    170         case eVarSetOperationInvalid:
    171             error = OptionValue::SetValueFromCString (value, op);
    172             break;
    173     }
    174     return error;
    175 
    176     m_value_was_set = true;
    177     return Error();
    178 }
    179 
    180 lldb::OptionValueSP
    181 OptionValueFileSpecList::DeepCopy () const
    182 {
    183     return OptionValueSP(new OptionValueFileSpecList(*this));
    184 }
    185 
    186 
    187