You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			238 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			238 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===-- Results.cpp ---------------------------------------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "Results.h"
 | |
| #include <assert.h>
 | |
| 
 | |
| #ifdef __APPLE__
 | |
| #include "CFCMutableArray.h"
 | |
| #include "CFCMutableDictionary.h"
 | |
| #include "CFCReleaser.h"
 | |
| #include "CFCString.h"
 | |
| #endif
 | |
| 
 | |
| using namespace lldb_perf;
 | |
| 
 | |
| static void AddResultToArray(CFCMutableArray &array, Results::Result *result);
 | |
| 
 | |
| static void AddResultToDictionary(CFCMutableDictionary &parent_dict,
 | |
|                                   const char *key, Results::Result *result);
 | |
| 
 | |
| static void AddResultToArray(CFCMutableArray &parent_array,
 | |
|                              Results::Result *result) {
 | |
|   switch (result->GetType()) {
 | |
|   case Results::Result::Type::Invalid:
 | |
|     break;
 | |
| 
 | |
|   case Results::Result::Type::Array: {
 | |
|     Results::Array *value = result->GetAsArray();
 | |
|     CFCMutableArray array;
 | |
|     value->ForEach([&array](const Results::ResultSP &value_sp) -> bool {
 | |
|       AddResultToArray(array, value_sp.get());
 | |
|       return true;
 | |
|     });
 | |
|     parent_array.AppendValue(array.get(), true);
 | |
|   } break;
 | |
| 
 | |
|   case Results::Result::Type::Dictionary: {
 | |
|     Results::Dictionary *value = result->GetAsDictionary();
 | |
|     CFCMutableDictionary dict;
 | |
|     value->ForEach([&dict](const std::string &key,
 | |
|                            const Results::ResultSP &value_sp) -> bool {
 | |
|       AddResultToDictionary(dict, key.c_str(), value_sp.get());
 | |
|       return true;
 | |
|     });
 | |
|     if (result->GetDescription()) {
 | |
|       dict.AddValueCString(CFSTR("description"), result->GetDescription());
 | |
|     }
 | |
|     parent_array.AppendValue(dict.get(), true);
 | |
|   } break;
 | |
| 
 | |
|   case Results::Result::Type::Double: {
 | |
|     double d = result->GetAsDouble()->GetValue();
 | |
|     CFCReleaser<CFNumberRef> cf_number(
 | |
|         ::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &d));
 | |
|     if (cf_number.get())
 | |
|       parent_array.AppendValue(cf_number.get(), true);
 | |
|   } break;
 | |
|   case Results::Result::Type::String: {
 | |
|     CFCString cfstr(result->GetAsString()->GetValue());
 | |
|     if (cfstr.get())
 | |
|       parent_array.AppendValue(cfstr.get(), true);
 | |
|   } break;
 | |
| 
 | |
|   case Results::Result::Type::Unsigned: {
 | |
|     uint64_t uval64 = result->GetAsUnsigned()->GetValue();
 | |
|     CFCReleaser<CFNumberRef> cf_number(
 | |
|         ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &uval64));
 | |
|     if (cf_number.get())
 | |
|       parent_array.AppendValue(cf_number.get(), true);
 | |
|   } break;
 | |
| 
 | |
|   default:
 | |
|     llvm_unreachable("unhandled result");
 | |
|   }
 | |
| }
 | |
| 
 | |
| static void AddResultToDictionary(CFCMutableDictionary &parent_dict,
 | |
|                                   const char *key, Results::Result *result) {
 | |
|   assert(key && key[0]);
 | |
|   CFCString cf_key(key);
 | |
|   switch (result->GetType()) {
 | |
|   case Results::Result::Type::Invalid:
 | |
|     break;
 | |
| 
 | |
|   case Results::Result::Type::Array: {
 | |
|     Results::Array *value = result->GetAsArray();
 | |
|     CFCMutableArray array;
 | |
|     value->ForEach([&array](const Results::ResultSP &value_sp) -> bool {
 | |
|       AddResultToArray(array, value_sp.get());
 | |
|       return true;
 | |
|     });
 | |
|     parent_dict.AddValue(cf_key.get(), array.get(), true);
 | |
|   } break;
 | |
|   case Results::Result::Type::Dictionary: {
 | |
|     Results::Dictionary *value = result->GetAsDictionary();
 | |
|     CFCMutableDictionary dict;
 | |
|     value->ForEach([&dict](const std::string &key,
 | |
|                            const Results::ResultSP &value_sp) -> bool {
 | |
|       AddResultToDictionary(dict, key.c_str(), value_sp.get());
 | |
|       return true;
 | |
|     });
 | |
|     if (result->GetDescription()) {
 | |
|       dict.AddValueCString(CFSTR("description"), result->GetDescription());
 | |
|     }
 | |
|     parent_dict.AddValue(cf_key.get(), dict.get(), true);
 | |
|   } break;
 | |
|   case Results::Result::Type::Double: {
 | |
|     parent_dict.SetValueDouble(cf_key.get(), result->GetAsDouble()->GetValue(),
 | |
|                                true);
 | |
|   } break;
 | |
|   case Results::Result::Type::String: {
 | |
|     parent_dict.SetValueCString(cf_key.get(), result->GetAsString()->GetValue(),
 | |
|                                 true);
 | |
|   } break;
 | |
| 
 | |
|   case Results::Result::Type::Unsigned: {
 | |
|     parent_dict.SetValueUInt64(cf_key.get(),
 | |
|                                result->GetAsUnsigned()->GetValue(), true);
 | |
|   } break;
 | |
|   default:
 | |
|     llvm_unreachable("unhandled result");
 | |
|   }
 | |
| }
 | |
| void Results::Write(const char *out_path) {
 | |
| #ifdef __APPLE__
 | |
|   CFCMutableDictionary dict;
 | |
| 
 | |
|   m_results.ForEach(
 | |
|       [&dict](const std::string &key, const ResultSP &value_sp) -> bool {
 | |
|         AddResultToDictionary(dict, key.c_str(), value_sp.get());
 | |
|         return true;
 | |
|       });
 | |
|   CFDataRef xmlData = CFPropertyListCreateData(
 | |
|       kCFAllocatorDefault, dict.get(), kCFPropertyListXMLFormat_v1_0, 0, NULL);
 | |
| 
 | |
|   if (out_path == NULL)
 | |
|     out_path = "/dev/stdout";
 | |
| 
 | |
|   CFURLRef file = CFURLCreateFromFileSystemRepresentation(
 | |
|       NULL, (const UInt8 *)out_path, strlen(out_path), FALSE);
 | |
| 
 | |
|   CFURLWriteDataAndPropertiesToResource(file, xmlData, NULL, NULL);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| Results::ResultSP Results::Dictionary::AddUnsigned(const char *name,
 | |
|                                                    const char *description,
 | |
|                                                    uint64_t value) {
 | |
|   assert(name && name[0]);
 | |
|   if (description && description[0]) {
 | |
|     std::unique_ptr<Results::Dictionary> value_dict_ap(
 | |
|         new Results::Dictionary());
 | |
|     value_dict_ap->AddString("description", NULL, description);
 | |
|     value_dict_ap->AddUnsigned("value", NULL, value);
 | |
|     m_dictionary[std::string(name)] = ResultSP(value_dict_ap.release());
 | |
|   } else
 | |
|     m_dictionary[std::string(name)] =
 | |
|         ResultSP(new Unsigned(name, description, value));
 | |
|   return m_dictionary[std::string(name)];
 | |
| }
 | |
| 
 | |
| Results::ResultSP Results::Dictionary::AddDouble(const char *name,
 | |
|                                                  const char *description,
 | |
|                                                  double value) {
 | |
|   assert(name && name[0]);
 | |
| 
 | |
|   if (description && description[0]) {
 | |
|     std::unique_ptr<Results::Dictionary> value_dict_ap(
 | |
|         new Results::Dictionary());
 | |
|     value_dict_ap->AddString("description", NULL, description);
 | |
|     value_dict_ap->AddDouble("value", NULL, value);
 | |
|     m_dictionary[std::string(name)] = ResultSP(value_dict_ap.release());
 | |
|   } else
 | |
|     m_dictionary[std::string(name)] =
 | |
|         ResultSP(new Double(name, description, value));
 | |
|   return m_dictionary[std::string(name)];
 | |
| }
 | |
| Results::ResultSP Results::Dictionary::AddString(const char *name,
 | |
|                                                  const char *description,
 | |
|                                                  const char *value) {
 | |
|   assert(name && name[0]);
 | |
|   if (description && description[0]) {
 | |
|     std::unique_ptr<Results::Dictionary> value_dict_ap(
 | |
|         new Results::Dictionary());
 | |
|     value_dict_ap->AddString("description", NULL, description);
 | |
|     value_dict_ap->AddString("value", NULL, value);
 | |
|     m_dictionary[std::string(name)] = ResultSP(value_dict_ap.release());
 | |
|   } else
 | |
|     m_dictionary[std::string(name)] =
 | |
|         ResultSP(new String(name, description, value));
 | |
|   return m_dictionary[std::string(name)];
 | |
| }
 | |
| 
 | |
| Results::ResultSP Results::Dictionary::Add(const char *name,
 | |
|                                            const char *description,
 | |
|                                            const ResultSP &result_sp) {
 | |
|   assert(name && name[0]);
 | |
|   if (description && description[0]) {
 | |
|     std::unique_ptr<Results::Dictionary> value_dict_ap(
 | |
|         new Results::Dictionary());
 | |
|     value_dict_ap->AddString("description", NULL, description);
 | |
|     value_dict_ap->Add("value", NULL, result_sp);
 | |
|     m_dictionary[std::string(name)] = ResultSP(value_dict_ap.release());
 | |
|   } else
 | |
|     m_dictionary[std::string(name)] = result_sp;
 | |
|   return m_dictionary[std::string(name)];
 | |
| }
 | |
| 
 | |
| void Results::Dictionary::ForEach(
 | |
|     const std::function<bool(const std::string &, const ResultSP &)>
 | |
|         &callback) {
 | |
|   collection::const_iterator pos, end = m_dictionary.end();
 | |
|   for (pos = m_dictionary.begin(); pos != end; ++pos) {
 | |
|     if (callback(pos->first.c_str(), pos->second) == false)
 | |
|       return;
 | |
|   }
 | |
| }
 | |
| 
 | |
| Results::ResultSP Results::Array::Append(const ResultSP &result_sp) {
 | |
|   m_array.push_back(result_sp);
 | |
|   return result_sp;
 | |
| }
 | |
| 
 | |
| void Results::Array::ForEach(
 | |
|     const std::function<bool(const ResultSP &)> &callback) {
 | |
|   collection::const_iterator pos, end = m_array.end();
 | |
|   for (pos = m_array.begin(); pos != end; ++pos) {
 | |
|     if (callback(*pos) == false)
 | |
|       return;
 | |
|   }
 | |
| }
 |