<commit_before>//===-- ValueObjectVariable.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/Core/ValueObjectVariable.h"

#include "lldb/Core/Address.h"      // for Address
#include "lldb/Core/AddressRange.h" // for AddressRange
#include "lldb/Core/Module.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h" // for Scalar, operator!=
#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpression.h" // for DWARFExpression
#include "lldb/Symbol/Declaration.h"         // for Declaration
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"     // for DataExtractor
#include "lldb/Utility/Status.h"            // for Status
#include "lldb/lldb-private-enumerations.h" // for AddressType::eAddressTy...
#include "lldb/lldb-types.h"                // for addr_t

#include "llvm/ADT/StringRef.h" // for StringRef

#include <assert.h> // for assert
#include <memory>   // for shared_ptr

namespace lldb_private {
class ExecutionContextScope;
}
namespace lldb_private {
class StackFrame;
}
namespace lldb_private {
struct RegisterInfo;
}
using namespace lldb_private;

lldb::ValueObjectSP
ValueObjectVariable::Create(ExecutionContextScope *exe_scope,
                            const lldb::VariableSP &var_sp) {
  return (new ValueObjectVariable(exe_scope, var_sp))->GetSP();
}

ValueObjectVariable::ValueObjectVariable(ExecutionContextScope *exe_scope,
                                         const lldb::VariableSP &var_sp)
    : ValueObject(exe_scope), m_variable_sp(var_sp) {
  // Do not attempt to construct one of these objects with no variable!
  assert(m_variable_sp.get() != NULL);
  m_name = var_sp->GetName();
}

ValueObjectVariable::~ValueObjectVariable() {}

CompilerType ValueObjectVariable::GetCompilerTypeImpl() {
  Type *var_type = m_variable_sp->GetType();
  if (var_type)
    return var_type->GetForwardCompilerType();
  return CompilerType();
}

ConstString ValueObjectVariable::GetTypeName() {
  Type *var_type = m_variable_sp->GetType();
  if (var_type)
    return var_type->GetName();
  return ConstString();
}

ConstString ValueObjectVariable::GetDisplayTypeName() {
  Type *var_type = m_variable_sp->GetType();
  if (var_type)
    return var_type->GetForwardCompilerType().GetDisplayTypeName();
  return ConstString();
}

ConstString ValueObjectVariable::GetQualifiedTypeName() {
  Type *var_type = m_variable_sp->GetType();
  if (var_type)
    return var_type->GetQualifiedName();
  return ConstString();
}

size_t ValueObjectVariable::CalculateNumChildren(uint32_t max) {
  CompilerType type(GetCompilerType());

  if (!type.IsValid())
    return 0;

  const bool omit_empty_base_classes = true;
  auto child_count = type.GetNumChildren(omit_empty_base_classes);
  return child_count <= max ? child_count : max;
}

uint64_t ValueObjectVariable::GetByteSize() {
  ExecutionContext exe_ctx(GetExecutionContextRef());

  CompilerType type(GetCompilerType());

  if (!type.IsValid())
    return 0;

  return type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
}

lldb::ValueType ValueObjectVariable::GetValueType() const {
  if (m_variable_sp)
    return m_variable_sp->GetScope();
  return lldb::eValueTypeInvalid;
}

bool ValueObjectVariable::UpdateValue() {
  SetValueIsValid(false);
  m_error.Clear();

  Variable *variable = m_variable_sp.get();
  DWARFExpression &expr = variable->LocationExpression();

  if (variable->GetLocationIsConstantValueData()) {
    // expr doesn't contain DWARF bytes, it contains the constant variable
    // value bytes themselves...
    if (expr.GetExpressionData(m_data)) {
      if (m_data.GetDataStart() && m_data.GetByteSize())
        m_value.SetBytes(m_data.GetDataStart(), m_data.GetByteSize());
      m_value.SetContext(Value::eContextTypeVariable, variable);
    } else {
      CompilerType var_type(GetCompilerTypeImpl());
      if (var_type.IsValid()) {
        if (SwiftASTContext::IsPossibleZeroSizeType(var_type))
          m_value.SetCompilerType(var_type);
        else
          m_error.SetErrorString("empty constant data");
      }
    }
    // constant bytes can't be edited - sorry
    m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
    SetAddressTypeOfChildren(eAddressTypeInvalid);
  } else {
    lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
    ExecutionContext exe_ctx(GetExecutionContextRef());

    Target *target = exe_ctx.GetTargetPtr();
    if (target) {
      m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
      m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
    }

    if (expr.IsLocationList()) {
      SymbolContext sc;
      variable->CalculateSymbolContext(&sc);
      if (sc.function)
        loclist_base_load_addr =
            sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
                target);
    }
    Value old_value(m_value);
    if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
                      nullptr, m_value, &m_error)) {
      m_resolved_value = m_value;
      m_value.SetContext(Value::eContextTypeVariable, variable);

      CompilerType compiler_type = GetCompilerType();
      if (compiler_type.IsValid())
        m_value.SetCompilerType(compiler_type);

      Value::ValueType value_type = m_value.GetValueType();

      Process *process = exe_ctx.GetProcessPtr();
      const bool process_is_alive = process && process->IsAlive();
      const uint32_t type_info =
          compiler_type.IsValid() ? compiler_type.GetTypeInfo() : 0;
      const bool is_pointer_or_ref =
          (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;

      switch (value_type) {
      case Value::eValueTypeFileAddress:
        // If this type is a pointer, then its children will be considered load
        // addresses
        // if the pointer or reference is dereferenced, but only if the process
        // is alive.
        //
        // There could be global variables like in the following code:
        // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
        // Foo g_foo1;
        // Foo g_foo2;
        // LinkedListNode g_second_node = { &g_foo2, NULL };
        // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
        //
        // When we aren't running, we should be able to look at these variables
        // using
        // the "target variable" command. Children of the "g_first_node" always
        // will
        // be of the same address type as the parent. But children of the "next"
        // member of
        // LinkedListNode will become load addresses if we have a live process,
        // or remain
        // what a file address if it what a file address.
        if (process_is_alive && is_pointer_or_ref)
          SetAddressTypeOfChildren(eAddressTypeLoad);
        else
          SetAddressTypeOfChildren(eAddressTypeFile);
        break;
      case Value::eValueTypeHostAddress:
        // Same as above for load addresses, except children of pointer or refs
        // are always
        // load addresses. Host addresses are used to store freeze dried
        // variables. If this
        // type is a struct, the entire struct contents will be copied into the
        // heap of the
        // LLDB process, but we do not currrently follow any pointers.
        if (is_pointer_or_ref)
          SetAddressTypeOfChildren(eAddressTypeLoad);
        else
          SetAddressTypeOfChildren(eAddressTypeHost);
        break;
      case Value::eValueTypeLoadAddress:
      case Value::eValueTypeScalar:
      case Value::eValueTypeVector:
        SetAddressTypeOfChildren(eAddressTypeLoad);
        break;
      }

      switch (value_type) {
      case Value::eValueTypeVector:
      // fall through
      case Value::eValueTypeScalar:
        // The variable value is in the Scalar value inside the m_value.
        // We can point our m_data right to it.
        m_error =
            m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
        break;

      case Value::eValueTypeFileAddress:
      case Value::eValueTypeLoadAddress:
      case Value::eValueTypeHostAddress:
        // The DWARF expression result was an address in the inferior
        // process. If this variable is an aggregate type, we just need
        // the address as the main value as all child variable objects
        // will rely upon this location and add an offset and then read
        // their own values as needed. If this variable is a simple
        // type, we read all data for it into m_data.
        // Make sure this type has a value before we try and read it

        SymbolContext var_sc;
        variable->CalculateSymbolContext(&var_sc);
        // If we have a file address, convert it to a load address if we can.
        m_value.ConvertToLoadAddress(var_sc);

        if (!CanProvideValue()) {
          // this value object represents an aggregate type whose
          // children have values, but this object does not. So we
          // say we are changed if our location has changed.
          SetValueDidChange(value_type != old_value.GetValueType() ||
                            m_value.GetScalar() != old_value.GetScalar());
        } else {
          // Copy the Value and set the context to use our Variable
          // so it can extract read its value into m_data appropriately
          Value value(m_value);
          value.SetContext(Value::eContextTypeVariable, variable);
          m_error =
              value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());

          SetValueDidChange(value_type != old_value.GetValueType() ||
                            m_value.GetScalar() != old_value.GetScalar());
        }
        break;
      }

      SetValueIsValid(m_error.Success());
    } else {
      // could not find location, won't allow editing
      m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
    }
  }
  return m_error.Success();
}

bool ValueObjectVariable::IsInScope() {
  const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
  if (exe_ctx_ref.HasFrameRef()) {
    ExecutionContext exe_ctx(exe_ctx_ref);
    StackFrame *frame = exe_ctx.GetFramePtr();
    if (frame) {
      return m_variable_sp->IsInScope(frame);
    } else {
      // This ValueObject had a frame at one time, but now we
      // can't locate it, so return false since we probably aren't
      // in scope.
      return false;
    }
  }
  // We have a variable that wasn't tied to a frame, which
  // means it is a global and is always in scope.
  return true;
}

lldb::ModuleSP ValueObjectVariable::GetModule() {
  if (m_variable_sp) {
    SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
    if (sc_scope) {
      return sc_scope->CalculateSymbolContextModule();
    }
  }
  return lldb::ModuleSP();
}

SymbolContextScope *ValueObjectVariable::GetSymbolContextScope() {
  if (m_variable_sp)
    return m_variable_sp->GetSymbolContextScope();
  return NULL;
}

bool ValueObjectVariable::GetDeclaration(Declaration &decl) {
  if (m_variable_sp) {
    decl = m_variable_sp->GetDeclaration();
    return true;
  }
  return false;
}

const char *ValueObjectVariable::GetLocationAsCString() {
  if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
    return GetLocationAsCStringImpl(m_resolved_value, m_data);
  else
    return ValueObject::GetLocationAsCString();
}

bool ValueObjectVariable::SetValueFromCString(const char *value_str,
                                              Status &error) {
  if (!UpdateValueIfNeeded()) {
    error.SetErrorString("unable to update value before writing");
    return false;
  }

  if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo) {
    RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
    ExecutionContext exe_ctx(GetExecutionContextRef());
    RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
    RegisterValue reg_value;
    if (!reg_info || !reg_ctx) {
      error.SetErrorString("unable to retrieve register info");
      return false;
    }
    error = reg_value.SetValueFromString(reg_info, llvm::StringRef(value_str));
    if (error.Fail())
      return false;
    if (reg_ctx->WriteRegister(reg_info, reg_value)) {
      SetNeedsUpdate();
      return true;
    } else {
      error.SetErrorString("unable to write back to register");
      return false;
    }
  } else
    return ValueObject::SetValueFromCString(value_str, error);
}

bool ValueObjectVariable::SetData(DataExtractor &data, Status &error) {
  if (!UpdateValueIfNeeded()) {
    error.SetErrorString("unable to update value before writing");
    return false;
  }

  if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo) {
    RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
    ExecutionContext exe_ctx(GetExecutionContextRef());
    RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
    RegisterValue reg_value;
    if (!reg_info || !reg_ctx) {
      error.SetErrorString("unable to retrieve register info");
      return false;
    }
    error = reg_value.SetValueFromData(reg_info, data, 0, true);
    if (error.Fail())
      return false;
    if (reg_ctx->WriteRegister(reg_info, reg_value)) {
      SetNeedsUpdate();
      return true;
    } else {
      error.SetErrorString("unable to write back to register");
      return false;
    }
  } else
    return ValueObject::SetData(data, error);
}
<commit_msg>Add back condition that was accidentally removed in r331462.<commit_after>//===-- ValueObjectVariable.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/Core/ValueObjectVariable.h"

#include "lldb/Core/Address.h"      // for Address
#include "lldb/Core/AddressRange.h" // for AddressRange
#include "lldb/Core/Module.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h" // for Scalar, operator!=
#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpression.h" // for DWARFExpression
#include "lldb/Symbol/Declaration.h"         // for Declaration
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"     // for DataExtractor
#include "lldb/Utility/Status.h"            // for Status
#include "lldb/lldb-private-enumerations.h" // for AddressType::eAddressTy...
#include "lldb/lldb-types.h"                // for addr_t

#include "llvm/ADT/StringRef.h" // for StringRef

#include <assert.h> // for assert
#include <memory>   // for shared_ptr

namespace lldb_private {
class ExecutionContextScope;
}
namespace lldb_private {
class StackFrame;
}
namespace lldb_private {
struct RegisterInfo;
}
using namespace lldb_private;

lldb::ValueObjectSP
ValueObjectVariable::Create(ExecutionContextScope *exe_scope,
                            const lldb::VariableSP &var_sp) {
  return (new ValueObjectVariable(exe_scope, var_sp))->GetSP();
}

ValueObjectVariable::ValueObjectVariable(ExecutionContextScope *exe_scope,
                                         const lldb::VariableSP &var_sp)
    : ValueObject(exe_scope), m_variable_sp(var_sp) {
  // Do not attempt to construct one of these objects with no variable!
  assert(m_variable_sp.get() != NULL);
  m_name = var_sp->GetName();
}

ValueObjectVariable::~ValueObjectVariable() {}

CompilerType ValueObjectVariable::GetCompilerTypeImpl() {
  Type *var_type = m_variable_sp->GetType();
  if (var_type)
    return var_type->GetForwardCompilerType();
  return CompilerType();
}

ConstString ValueObjectVariable::GetTypeName() {
  Type *var_type = m_variable_sp->GetType();
  if (var_type)
    return var_type->GetName();
  return ConstString();
}

ConstString ValueObjectVariable::GetDisplayTypeName() {
  Type *var_type = m_variable_sp->GetType();
  if (var_type)
    return var_type->GetForwardCompilerType().GetDisplayTypeName();
  return ConstString();
}

ConstString ValueObjectVariable::GetQualifiedTypeName() {
  Type *var_type = m_variable_sp->GetType();
  if (var_type)
    return var_type->GetQualifiedName();
  return ConstString();
}

size_t ValueObjectVariable::CalculateNumChildren(uint32_t max) {
  CompilerType type(GetCompilerType());

  if (!type.IsValid())
    return 0;

  const bool omit_empty_base_classes = true;
  auto child_count = type.GetNumChildren(omit_empty_base_classes);
  return child_count <= max ? child_count : max;
}

uint64_t ValueObjectVariable::GetByteSize() {
  ExecutionContext exe_ctx(GetExecutionContextRef());

  CompilerType type(GetCompilerType());

  if (!type.IsValid())
    return 0;

  return type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
}

lldb::ValueType ValueObjectVariable::GetValueType() const {
  if (m_variable_sp)
    return m_variable_sp->GetScope();
  return lldb::eValueTypeInvalid;
}

bool ValueObjectVariable::UpdateValue() {
  SetValueIsValid(false);
  m_error.Clear();

  Variable *variable = m_variable_sp.get();
  DWARFExpression &expr = variable->LocationExpression();

  if (variable->GetLocationIsConstantValueData()) {
    // expr doesn't contain DWARF bytes, it contains the constant variable
    // value bytes themselves...
    if (expr.GetExpressionData(m_data)) {
      if (m_data.GetDataStart() && m_data.GetByteSize())
        m_value.SetBytes(m_data.GetDataStart(), m_data.GetByteSize());
      m_value.SetContext(Value::eContextTypeVariable, variable);
    } else {
      CompilerType var_type(GetCompilerTypeImpl());
      if (var_type.IsValid()) {
        if (SwiftASTContext::IsPossibleZeroSizeType(var_type))
          m_value.SetCompilerType(var_type);
        else
          m_error.SetErrorString("empty constant data");
      }
    }
    // constant bytes can't be edited - sorry
    m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
    SetAddressTypeOfChildren(eAddressTypeInvalid);
  } else {
    lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
    ExecutionContext exe_ctx(GetExecutionContextRef());

    Target *target = exe_ctx.GetTargetPtr();
    if (target) {
      m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
      m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
    }

    if (expr.IsLocationList()) {
      SymbolContext sc;
      variable->CalculateSymbolContext(&sc);
      if (sc.function)
        loclist_base_load_addr =
            sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
                target);
    }
    Value old_value(m_value);
    if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
                      nullptr, m_value, &m_error)) {
      m_resolved_value = m_value;
      m_value.SetContext(Value::eContextTypeVariable, variable);

      CompilerType compiler_type = GetCompilerType();
      if (compiler_type.IsValid())
        m_value.SetCompilerType(compiler_type);

      Value::ValueType value_type = m_value.GetValueType();

      Process *process = exe_ctx.GetProcessPtr();
      const bool process_is_alive = process && process->IsAlive();
      const uint32_t type_info =
          compiler_type.IsValid() ? compiler_type.GetTypeInfo() : 0;
      const bool is_pointer_or_ref =
          (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;

      switch (value_type) {
      case Value::eValueTypeFileAddress:
        // If this type is a pointer, then its children will be considered load
        // addresses
        // if the pointer or reference is dereferenced, but only if the process
        // is alive.
        //
        // There could be global variables like in the following code:
        // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
        // Foo g_foo1;
        // Foo g_foo2;
        // LinkedListNode g_second_node = { &g_foo2, NULL };
        // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
        //
        // When we aren't running, we should be able to look at these variables
        // using
        // the "target variable" command. Children of the "g_first_node" always
        // will
        // be of the same address type as the parent. But children of the "next"
        // member of
        // LinkedListNode will become load addresses if we have a live process,
        // or remain
        // what a file address if it what a file address.
        if (process_is_alive && is_pointer_or_ref)
          SetAddressTypeOfChildren(eAddressTypeLoad);
        else
          SetAddressTypeOfChildren(eAddressTypeFile);
        break;
      case Value::eValueTypeHostAddress:
        // Same as above for load addresses, except children of pointer or refs
        // are always
        // load addresses. Host addresses are used to store freeze dried
        // variables. If this
        // type is a struct, the entire struct contents will be copied into the
        // heap of the
        // LLDB process, but we do not currrently follow any pointers.
        if (is_pointer_or_ref)
          SetAddressTypeOfChildren(eAddressTypeLoad);
        else
          SetAddressTypeOfChildren(eAddressTypeHost);
        break;
      case Value::eValueTypeLoadAddress:
      case Value::eValueTypeScalar:
      case Value::eValueTypeVector:
        SetAddressTypeOfChildren(eAddressTypeLoad);
        break;
      }

      switch (value_type) {
      case Value::eValueTypeVector:
      // fall through
      case Value::eValueTypeScalar:
        // The variable value is in the Scalar value inside the m_value.
        // We can point our m_data right to it.
        m_error =
            m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
        break;

      case Value::eValueTypeFileAddress:
      case Value::eValueTypeLoadAddress:
      case Value::eValueTypeHostAddress:
        // The DWARF expression result was an address in the inferior
        // process. If this variable is an aggregate type, we just need
        // the address as the main value as all child variable objects
        // will rely upon this location and add an offset and then read
        // their own values as needed. If this variable is a simple
        // type, we read all data for it into m_data.
        // Make sure this type has a value before we try and read it

        // If we have a file address, convert it to a load address if we can.
        if (value_type == Value::eValueTypeFileAddress && process_is_alive) {
          SymbolContext var_sc;
          variable->CalculateSymbolContext(&var_sc);
          m_value.ConvertToLoadAddress(var_sc);
        }

        if (!CanProvideValue()) {
          // this value object represents an aggregate type whose
          // children have values, but this object does not. So we
          // say we are changed if our location has changed.
          SetValueDidChange(value_type != old_value.GetValueType() ||
                            m_value.GetScalar() != old_value.GetScalar());
        } else {
          // Copy the Value and set the context to use our Variable
          // so it can extract read its value into m_data appropriately
          Value value(m_value);
          value.SetContext(Value::eContextTypeVariable, variable);
          m_error =
              value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());

          SetValueDidChange(value_type != old_value.GetValueType() ||
                            m_value.GetScalar() != old_value.GetScalar());
        }
        break;
      }

      SetValueIsValid(m_error.Success());
    } else {
      // could not find location, won't allow editing
      m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
    }
  }
  return m_error.Success();
}

bool ValueObjectVariable::IsInScope() {
  const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
  if (exe_ctx_ref.HasFrameRef()) {
    ExecutionContext exe_ctx(exe_ctx_ref);
    StackFrame *frame = exe_ctx.GetFramePtr();
    if (frame) {
      return m_variable_sp->IsInScope(frame);
    } else {
      // This ValueObject had a frame at one time, but now we
      // can't locate it, so return false since we probably aren't
      // in scope.
      return false;
    }
  }
  // We have a variable that wasn't tied to a frame, which
  // means it is a global and is always in scope.
  return true;
}

lldb::ModuleSP ValueObjectVariable::GetModule() {
  if (m_variable_sp) {
    SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
    if (sc_scope) {
      return sc_scope->CalculateSymbolContextModule();
    }
  }
  return lldb::ModuleSP();
}

SymbolContextScope *ValueObjectVariable::GetSymbolContextScope() {
  if (m_variable_sp)
    return m_variable_sp->GetSymbolContextScope();
  return NULL;
}

bool ValueObjectVariable::GetDeclaration(Declaration &decl) {
  if (m_variable_sp) {
    decl = m_variable_sp->GetDeclaration();
    return true;
  }
  return false;
}

const char *ValueObjectVariable::GetLocationAsCString() {
  if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
    return GetLocationAsCStringImpl(m_resolved_value, m_data);
  else
    return ValueObject::GetLocationAsCString();
}

bool ValueObjectVariable::SetValueFromCString(const char *value_str,
                                              Status &error) {
  if (!UpdateValueIfNeeded()) {
    error.SetErrorString("unable to update value before writing");
    return false;
  }

  if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo) {
    RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
    ExecutionContext exe_ctx(GetExecutionContextRef());
    RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
    RegisterValue reg_value;
    if (!reg_info || !reg_ctx) {
      error.SetErrorString("unable to retrieve register info");
      return false;
    }
    error = reg_value.SetValueFromString(reg_info, llvm::StringRef(value_str));
    if (error.Fail())
      return false;
    if (reg_ctx->WriteRegister(reg_info, reg_value)) {
      SetNeedsUpdate();
      return true;
    } else {
      error.SetErrorString("unable to write back to register");
      return false;
    }
  } else
    return ValueObject::SetValueFromCString(value_str, error);
}

bool ValueObjectVariable::SetData(DataExtractor &data, Status &error) {
  if (!UpdateValueIfNeeded()) {
    error.SetErrorString("unable to update value before writing");
    return false;
  }

  if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo) {
    RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
    ExecutionContext exe_ctx(GetExecutionContextRef());
    RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
    RegisterValue reg_value;
    if (!reg_info || !reg_ctx) {
      error.SetErrorString("unable to retrieve register info");
      return false;
    }
    error = reg_value.SetValueFromData(reg_info, data, 0, true);
    if (error.Fail())
      return false;
    if (reg_ctx->WriteRegister(reg_info, reg_value)) {
      SetNeedsUpdate();
      return true;
    } else {
      error.SetErrorString("unable to write back to register");
      return false;
    }
  } else
    return ValueObject::SetData(data, error);
}
<|endoftext|>


<commit_before>/*!
*	@file	Liepa.cpp
*	@brief	Implementation of Liepa's subdivision scheme
*/

#include <cmath>
#include "Liepa.h"

namespace psalm
{

/*!
*	Sets default values for Liepa subdivision.
*/

Liepa::Liepa()
{
	alpha = sqrt(2);
}

/*!
*	Sets current value of density parameter for the algorithm.
*
*	@param alpha New value for density parameter
*/

void Liepa::set_alpha(double alpha)
{
	this->alpha = alpha;
}

/*!
*	@returns Current value of density parameter for the algorithm.
*/

double Liepa::get_alpha()
{
	return(alpha);
}

/*!
*	Applies Liepa's subdivision scheme to the given mesh. The mesh will be
*	irreversibly _changed_ by this function.
*
*	@param	input_mesh Mesh on which the algorithm is applied
*	@return	true on success, else false
*/

bool Liepa::apply_to(mesh& input_mesh)
{
	/*
		Compute scale attribute as the average length of the edges
		adjacent to a vertex.

		ASSUMPTION: Mesh consists of a single triangulated hole, i.e.
		_all_ vertices are boundary vertices.
	*/

	for(size_t i = 0; i < input_mesh.num_vertices(); i++)
	{
		vertex* v = input_mesh.get_vertex(i);
		size_t n = v->valency();

		double attribute		= 0.0;
		bool found_first_boundary_edge	= false;	// in the triangulated mesh, there are
								// only two boundary edges per vertex;
								// if we have found those two, the search
								// may be stopped.
		for(size_t i = 0; i < n; i++)
		{
			edge* e = v->get_edge(i);
			if(e->is_on_boundary())
			{
				attribute += 0.5*e->calc_length();

				// break if we have already seen a boundary
				// edge -- see discussion above
				if(found_first_boundary_edge)
					break;
				else
					found_first_boundary = true;
			}
		}

		// If the scale attributes have already been seeded, their
		// average is taken to be the new scale attribute...
		double old_attribute = v->get_scale_attribute();
		if(old_attribute != 0.0)
			v->set_scale_attribute(0.5*(old_attribute + attribute));
		else
			v->set_scale_attribute(attribute);
	}

	bool created_new_triangle;
	do
	{
		// if no new triangle has been created, the algorithm
		// terminates
		created_new_triangle = false;

		// Need to store the number of faces here because new faces
		// might be created within the for-loop below. These must _not_
		// be considered in the same iteration.
		size_t num_faces = input_mesh.num_faces();

		// Compute scale attribute for each face of the mesh
		for(size_t i = 0; i < num_faces; i++)
		{
			face* f = input_mesh.get_face(i);
			if(f->num_edges() != 3)
			{
				std::cerr << "psalm: Input mesh contains non-triangular face. Liepa's subdivision scheme is not applicable.\n";
				return(false);
			}

			vertex* vertices[3];
			vertices[0] = f->get_vertex(0);
			vertices[1] = f->get_vertex(1);
			vertices[2] = f->get_vertex(2);

			// Compute centroid and scale attribute. If the scale
			// attribute test fails, replace the triangle.

			v3ctor centroid_pos;
			double centroid_scale_attribute = 0.0;

			for(size_t j = 0; j < 3; j++)
			{
				centroid_pos += vertices[j]->get_position()/3.0;
				centroid_scale_attribute += vertices[j]->get_scale_attribute()/3.0;
			}

			size_t tests_failed = 0;
			for(size_t j = 0; j < 3; j++)
			{
				double scaled_distance = alpha*(centroid_pos - vertices[j]->get_position()).length();
				if(	scaled_distance > centroid_scale_attribute &&
					scaled_distance > vertices[j]->get_scale_attribute())
				{
					// We will replace the triangle only if
					// _all_ three tests failed
					tests_failed++;
				}
			}

			// Replace old triangle with three smaller triangles
			if(tests_failed == 3)
			{
				created_new_triangle = true;

				vertex* centroid_vertex = input_mesh.add_vertex(centroid_pos);
				centroid_vertex->set_scale_attribute(centroid_scale_attribute);

				// Remove old face and replace it by three new
				// faces. Calling remove_face() will ensure
				// that the edges are updated correctly.

				input_mesh.remove_face(f);
				delete f;

				face* new_face1 = input_mesh.add_face(vertices[0], vertices[1], centroid_vertex, true);
				face* new_face2 = input_mesh.add_face(centroid_vertex, vertices[1], vertices[2], true);
				face* new_face3 = input_mesh.add_face(vertices[0], centroid_vertex, vertices[2], true);

				if(!new_face1 || !new_face2 || !new_face3)
				{
					std::cerr << "psalm: Error: Liepa::apply_to(): Unable to add new face\n";
					return(false);
				}

				num_faces--;
				i--;

				// Relax edges afterwards to maintain
				// Delaunay-like mesh

				input_mesh.relax_edge(new_face1->get_edge(0).e);
				input_mesh.relax_edge(new_face2->get_edge(1).e);
				input_mesh.relax_edge(new_face3->get_edge(2).e);
			}
		}

		if(!created_new_triangle)
			return(true);

		// Relax interior edges
		bool relaxed_edge;
		do
		{
			relaxed_edge = false;
			for(size_t i = 0; i < input_mesh.num_edges(); i++)
			{
				if(input_mesh.relax_edge(input_mesh.get_edge(i)))
					relaxed_edge = true;
			}
		}
		while(relaxed_edge);

		/*
			XXX: This might lead to wrong results...

			// Calculate new scaling attributes. TODO: This should become a
			// function.
			for(size_t i = 0; i < input_mesh.num_vertices(); i++)
			{
				vertex* v = input_mesh.get_vertex(i);
				size_t n = v->valency();

				if(!v->is_on_boundary())
					continue;

				double attribute = 0.0;
				for(size_t i = 0; i < n; i++)
					attribute += v->get_edge(i)->calc_length()/static_cast<double>(n);

				v->set_scale_attribute(attribute);
			}
		*/

		if(!relaxed_edge)
			continue;
	}
	while(created_new_triangle);

	return(true);
}

} // end of namespace "psalm"
<commit_msg>Corrected typo in Liepa subdivision<commit_after>/*!
*	@file	Liepa.cpp
*	@brief	Implementation of Liepa's subdivision scheme
*/

#include <cmath>
#include "Liepa.h"

namespace psalm
{

/*!
*	Sets default values for Liepa subdivision.
*/

Liepa::Liepa()
{
	alpha = sqrt(2);
}

/*!
*	Sets current value of density parameter for the algorithm.
*
*	@param alpha New value for density parameter
*/

void Liepa::set_alpha(double alpha)
{
	this->alpha = alpha;
}

/*!
*	@returns Current value of density parameter for the algorithm.
*/

double Liepa::get_alpha()
{
	return(alpha);
}

/*!
*	Applies Liepa's subdivision scheme to the given mesh. The mesh will be
*	irreversibly _changed_ by this function.
*
*	@param	input_mesh Mesh on which the algorithm is applied
*	@return	true on success, else false
*/

bool Liepa::apply_to(mesh& input_mesh)
{
	/*
		Compute scale attribute as the average length of the edges
		adjacent to a vertex.

		ASSUMPTION: Mesh consists of a single triangulated hole, i.e.
		_all_ vertices are boundary vertices.
	*/

	for(size_t i = 0; i < input_mesh.num_vertices(); i++)
	{
		vertex* v = input_mesh.get_vertex(i);
		size_t n = v->valency();

		double attribute		= 0.0;
		bool found_first_boundary_edge	= false;	// in the triangulated mesh, there are
								// only two boundary edges per vertex;
								// if we have found those two, the search
								// may be stopped.
		for(size_t i = 0; i < n; i++)
		{
			edge* e = v->get_edge(i);
			if(e->is_on_boundary())
			{
				attribute += 0.5*e->calc_length();

				// break if we have already seen a boundary
				// edge -- see discussion above
				if(found_first_boundary_edge)
					break;
				else
					found_first_boundary_edge = true;
			}
		}

		// If the scale attributes have already been seeded, their
		// average is taken to be the new scale attribute...
		double old_attribute = v->get_scale_attribute();
		if(old_attribute != 0.0)
			v->set_scale_attribute(0.5*(old_attribute + attribute));
		else
			v->set_scale_attribute(attribute);
	}

	bool created_new_triangle;
	do
	{
		// if no new triangle has been created, the algorithm
		// terminates
		created_new_triangle = false;

		// Need to store the number of faces here because new faces
		// might be created within the for-loop below. These must _not_
		// be considered in the same iteration.
		size_t num_faces = input_mesh.num_faces();

		// Compute scale attribute for each face of the mesh
		for(size_t i = 0; i < num_faces; i++)
		{
			face* f = input_mesh.get_face(i);
			if(f->num_edges() != 3)
			{
				std::cerr << "psalm: Input mesh contains non-triangular face. Liepa's subdivision scheme is not applicable.\n";
				return(false);
			}

			vertex* vertices[3];
			vertices[0] = f->get_vertex(0);
			vertices[1] = f->get_vertex(1);
			vertices[2] = f->get_vertex(2);

			// Compute centroid and scale attribute. If the scale
			// attribute test fails, replace the triangle.

			v3ctor centroid_pos;
			double centroid_scale_attribute = 0.0;

			for(size_t j = 0; j < 3; j++)
			{
				centroid_pos += vertices[j]->get_position()/3.0;
				centroid_scale_attribute += vertices[j]->get_scale_attribute()/3.0;
			}

			size_t tests_failed = 0;
			for(size_t j = 0; j < 3; j++)
			{
				double scaled_distance = alpha*(centroid_pos - vertices[j]->get_position()).length();
				if(	scaled_distance > centroid_scale_attribute &&
					scaled_distance > vertices[j]->get_scale_attribute())
				{
					// We will replace the triangle only if
					// _all_ three tests failed
					tests_failed++;
				}
			}

			// Replace old triangle with three smaller triangles
			if(tests_failed == 3)
			{
				created_new_triangle = true;

				vertex* centroid_vertex = input_mesh.add_vertex(centroid_pos);
				centroid_vertex->set_scale_attribute(centroid_scale_attribute);

				// Remove old face and replace it by three new
				// faces. Calling remove_face() will ensure
				// that the edges are updated correctly.

				input_mesh.remove_face(f);
				delete f;

				face* new_face1 = input_mesh.add_face(vertices[0], vertices[1], centroid_vertex, true);
				face* new_face2 = input_mesh.add_face(centroid_vertex, vertices[1], vertices[2], true);
				face* new_face3 = input_mesh.add_face(vertices[0], centroid_vertex, vertices[2], true);

				if(!new_face1 || !new_face2 || !new_face3)
				{
					std::cerr << "psalm: Error: Liepa::apply_to(): Unable to add new face\n";
					return(false);
				}

				num_faces--;
				i--;

				// Relax edges afterwards to maintain
				// Delaunay-like mesh

				input_mesh.relax_edge(new_face1->get_edge(0).e);
				input_mesh.relax_edge(new_face2->get_edge(1).e);
				input_mesh.relax_edge(new_face3->get_edge(2).e);
			}
		}

		if(!created_new_triangle)
			return(true);

		// Relax interior edges
		bool relaxed_edge;
		do
		{
			relaxed_edge = false;
			for(size_t i = 0; i < input_mesh.num_edges(); i++)
			{
				if(input_mesh.relax_edge(input_mesh.get_edge(i)))
					relaxed_edge = true;
			}
		}
		while(relaxed_edge);

		/*
			XXX: This might lead to wrong results...

			// Calculate new scaling attributes. TODO: This should become a
			// function.
			for(size_t i = 0; i < input_mesh.num_vertices(); i++)
			{
				vertex* v = input_mesh.get_vertex(i);
				size_t n = v->valency();

				if(!v->is_on_boundary())
					continue;

				double attribute = 0.0;
				for(size_t i = 0; i < n; i++)
					attribute += v->get_edge(i)->calc_length()/static_cast<double>(n);

				v->set_scale_attribute(attribute);
			}
		*/

		if(!relaxed_edge)
			continue;
	}
	while(created_new_triangle);

	return(true);
}

} // end of namespace "psalm"
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/utf_string_conversions.h"
#include "chrome/browser/spellchecker_platform_engine.h"
#include "testing/gtest/include/gtest/gtest.h"

// Tests that words are properly ignored. Currently only enabled on OS X as it
// is the only platform to support ignoring words. Note that in this test, we
// supply a non-zero doc_tag, in order to test that ignored words are matched to
// the correct document.
TEST(PlatformSpellCheckTest, IgnoreWords_EN_US) {
  static const struct {
    // A misspelled word.
    const char* input;
    bool input_result;
  } kTestCases[] = {
    {"teh"},
    {"morblier"},
    {"watre"},
    {"noooen"},
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
    string16 word(UTF8ToUTF16(kTestCases[i].input));
    std::vector<string16> suggestions;
    size_t input_length = 0;
    if (kTestCases[i].input != NULL) {
      input_length = word.length();
    }

    int doc_tag = SpellCheckerPlatform::GetDocumentTag();
    bool result = SpellCheckerPlatform::CheckSpelling(word, doc_tag);

    // The word should show up as misspelled.
    EXPECT_EQ(kTestCases[i].input_result, result);

    // Ignore the word.
    SpellCheckerPlatform::IgnoreWord(word);

    // Spellcheck again.
    result = SpellCheckerPlatform::CheckSpelling(word, doc_tag);

    // The word should now show up as correctly spelled.
    EXPECT_EQ(!(kTestCases[i].input_result), result);

    // Close the docuemnt. Any words that we had previously ignored should no
    // longer be ignored and thus should show up as misspelled.
    SpellCheckerPlatform::CloseDocumentWithTag(doc_tag);

    // Spellcheck one more time.
    result = SpellCheckerPlatform::CheckSpelling(word, doc_tag);

    // The word should now show be spelled wrong again
    EXPECT_EQ(kTestCases[i].input_result, result);
  }
}  // Test IgnoreWords_EN_US

TEST(PlatformSpellCheckTest, SpellCheckSuggestions_EN_US) {
  static const struct {
    // A string to be tested.
    const wchar_t* input;

    // A suggested word that should occur.
    const wchar_t* suggested_word;
  } kTestCases[] = {    // A valid English word with a preceding whitespace
    // We need to have separate test cases here, since hunspell and the OS X
    // spellchecking service occasionally differ on what they consider a valid
    // suggestion for a given word, although these lists could likely be
    // integrated somewhat. The test cases for non-Mac are in
    // chrome/renderer/spellcheck_unittest.cc
    // These words come from the wikipedia page of the most commonly
    // misspelled words in english.
    // (http://en.wikipedia.org/wiki/Commonly_misspelled_words).
    // However, 10.6 loads multiple dictionaries and enables many non-English
    // dictionaries by default. As a result, we have removed from the list any
    // word that is marked as correct because it is correct in another
    // language.
    {L"absense", L"absence"},
    {L"acceptible", L"acceptable"},
    {L"accidentaly", L"accidentally"},
    {L"acheive", L"achieve"},
    {L"acknowlege", L"acknowledge"},
    {L"acquaintence", L"acquaintance"},
    {L"aquire", L"acquire"},
    {L"aquit", L"acquit"},
    {L"acrage", L"acreage"},
    {L"adultary", L"adultery"},
    {L"advertize", L"advertise"},
    {L"adviseable", L"advisable"},
    {L"alchohol", L"alcohol"},
    {L"alege", L"allege"},
    {L"allegaince", L"allegiance"},
    {L"allmost", L"almost"},
    // Ideally, this test should pass. It works in firefox, but not in hunspell
    // or OS X.
    // {L"alot", L"a lot"},
    {L"amatuer", L"amateur"},
    {L"ammend", L"amend"},
    {L"amung", L"among"},
    {L"anually", L"annually"},
    {L"apparant", L"apparent"},
    {L"artic", L"arctic"},
    {L"arguement", L"argument"},
    {L"athiest", L"atheist"},
    {L"athelete", L"athlete"},
    {L"avrage", L"average"},
    {L"awfull", L"awful"},
    {L"ballance", L"balance"},
    {L"basicly", L"basically"},
    {L"becuase", L"because"},
    {L"becomeing", L"becoming"},
    {L"befor", L"before"},
    {L"begining", L"beginning"},
    {L"beleive", L"believe"},
    {L"bellweather", L"bellwether"},
    {L"benifit", L"benefit"},
    {L"bouy", L"buoy"},
    {L"briliant", L"brilliant"},
    {L"burgler", L"burglar"},
    {L"camoflage", L"camouflage"},
    {L"carefull", L"careful"},
    {L"Carribean", L"Caribbean"},
    {L"catagory", L"category"},
    {L"cauhgt", L"caught"},
    {L"cieling", L"ceiling"},
    {L"cemetary", L"cemetery"},
    {L"certin", L"certain"},
    {L"changable", L"changeable"},
    {L"cheif", L"chief"},
    {L"citezen", L"citizen"},
    {L"collaegue", L"colleague"},
    {L"colum", L"column"},
    {L"comming", L"coming"},
    {L"commited", L"committed"},
    {L"compitition", L"competition"},
    {L"conceed", L"concede"},
    {L"congradulate", L"congratulate"},
    {L"consciencious", L"conscientious"},
    {L"concious", L"conscious"},
    {L"concensus", L"consensus"},
    {L"contraversy", L"controversy"},
    {L"conveniance", L"convenience"},
    {L"critecize", L"criticize"},
    {L"dacquiri", L"daiquiri"},
    {L"decieve", L"deceive"},
    {L"dicide", L"decide"},
    {L"definate", L"definite"},
    {L"definitly", L"definitely"},
    {L"desparate", L"desperate"},
    {L"develope", L"develop"},
    {L"diffrence", L"difference"},
    {L"disapear", L"disappear"},
    {L"disapoint", L"disappoint"},
    {L"disasterous", L"disastrous"},
    {L"disipline", L"discipline"},
    {L"drunkeness", L"drunkenness"},
    {L"dumbell", L"dumbbell"},
    {L"easely", L"easily"},
    {L"eigth", L"eight"},
    {L"embarass", L"embarrass"},
    {L"enviroment", L"environment"},
    {L"equiped", L"equipped"},
    {L"equiptment", L"equipment"},
    {L"exagerate", L"exaggerate"},
    {L"exellent", L"excellent"},
    {L"exsept", L"except"},
    {L"exercize", L"exercise"},
    {L"exilerate", L"exhilarate"},
    {L"existance", L"existence"},
    {L"experiance", L"experience"},
    {L"experament", L"experiment"},
    {L"explaination", L"explanation"},
    {L"facinating", L"fascinating"},
    {L"firey", L"fiery"},
    {L"finaly", L"finally"},
    {L"flourescent", L"fluorescent"},
    {L"foriegn", L"foreign"},
    {L"fourty", L"forty"},
    {L"foreward", L"forward"},
    {L"freind", L"friend"},
    {L"fundemental", L"fundamental"},
    {L"guage", L"gauge"},
    {L"generaly", L"generally"},
    {L"goverment", L"government"},
    {L"gratefull", L"grateful"},
    {L"garantee", L"guarantee"},
    {L"guidence", L"guidance"},
    {L"happyness", L"happiness"},
    {L"harrass", L"harass"},
    {L"heighth", L"height"},
    {L"heirarchy", L"hierarchy"},
    {L"humerous", L"humorous"},
    {L"hygene", L"hygiene"},
    {L"hipocrit", L"hypocrite"},
    {L"idenity", L"identity"},
    {L"ignorence", L"ignorance"},
    {L"imaginery", L"imaginary"},
    {L"immitate", L"imitate"},
    {L"immitation", L"imitation"},
    {L"imediately", L"immediately"},
    {L"incidently", L"incidentally"},
    {L"independant", L"independent"},
    {L"indispensible", L"indispensable"},
    {L"innoculate", L"inoculate"},
    {L"inteligence", L"intelligence"},
    {L"intresting", L"interesting"},
    {L"interuption", L"interruption"},
    {L"irrelevent", L"irrelevant"},
    {L"irritible", L"irritable"},
    {L"jellous", L"jealous"},
    {L"knowlege", L"knowledge"},
    {L"labratory", L"laboratory"},
    {L"lenght", L"length"},
    {L"liason", L"liaison"},
    {L"libary", L"library"},
    {L"lisence", L"license"},
    {L"lonelyness", L"loneliness"},
    {L"lieing", L"lying"},
    {L"maintenence", L"maintenance"},
    {L"manuever", L"maneuver"},
    {L"marrige", L"marriage"},
    {L"mathmatics", L"mathematics"},
    {L"medcine", L"medicine"},
    {L"miniture", L"miniature"},
    {L"minite", L"minute"},
    {L"mischevous", L"mischievous"},
    {L"mispell", L"misspell"},
    // Maybe this one should pass, as it works in hunspell, but not in firefox.
    // {L"misterius", L"mysterious"},
    {L"naturaly", L"naturally"},
    {L"neccessary", L"necessary"},
    {L"neice", L"niece"},
    {L"nieghbor", L"neighbor"},
    {L"nieghbour", L"neighbor"},
    {L"niether", L"neither"},
    {L"noticable", L"noticeable"},
    {L"occassion", L"occasion"},
    {L"occasionaly", L"occasionally"},
    {L"occurrance", L"occurrence"},
    {L"occured", L"occurred"},
    {L"ommision", L"omission"},
    {L"oppurtunity", L"opportunity"},
    {L"outragous", L"outrageous"},
    {L"parrallel", L"parallel"},
    {L"parliment", L"parliament"},
    {L"particurly", L"particularly"},
    {L"passtime", L"pastime"},
    {L"peculier", L"peculiar"},
    {L"percieve", L"perceive"},
    {L"pernament", L"permanent"},
    {L"perseverence", L"perseverance"},
    {L"personaly", L"personally"},
    {L"persaude", L"persuade"},
    {L"pichure", L"picture"},
    {L"peice", L"piece"},
    {L"plagerize", L"plagiarize"},
    {L"playright", L"playwright"},
    {L"plesant", L"pleasant"},
    {L"pollitical", L"political"},
    {L"posession", L"possession"},
    {L"potatos", L"potatoes"},
    {L"practicle", L"practical"},
    {L"preceed", L"precede"},
    {L"predjudice", L"prejudice"},
    {L"presance", L"presence"},
    {L"privelege", L"privilege"},
    // This one should probably work. It does in FF and Hunspell.
    // {L"probly", L"probably"},
    {L"proffesional", L"professional"},
    {L"promiss", L"promise"},
    {L"pronounciation", L"pronunciation"},
    {L"prufe", L"proof"},
    {L"psycology", L"psychology"},
    {L"publically", L"publicly"},
    {L"quanity", L"quantity"},
    {L"quarentine", L"quarantine"},
    {L"questionaire", L"questionnaire"},
    {L"readible", L"readable"},
    {L"realy", L"really"},
    {L"recieve", L"receive"},
    {L"reciept", L"receipt"},
    {L"reconize", L"recognize"},
    {L"recomend", L"recommend"},
    {L"refered", L"referred"},
    {L"referance", L"reference"},
    {L"relevent", L"relevant"},
    {L"religous", L"religious"},
    {L"repitition", L"repetition"},
    {L"restarant", L"restaurant"},
    {L"rythm", L"rhythm"},
    {L"rediculous", L"ridiculous"},
    {L"sacrefice", L"sacrifice"},
    {L"saftey", L"safety"},
    {L"sissors", L"scissors"},
    {L"secratary", L"secretary"},
    {L"seperate", L"separate"},
    {L"sargent", L"sergeant"},
    {L"shineing", L"shining"},
    {L"similer", L"similar"},
    {L"sinceerly", L"sincerely"},
    {L"speach", L"speech"},
    {L"stoping", L"stopping"},
    {L"strenght", L"strength"},
    {L"succesful", L"successful"},
    {L"supercede", L"supersede"},
    {L"surelly", L"surely"},
    {L"suprise", L"surprise"},
    {L"temperture", L"temperature"},
    {L"temprary", L"temporary"},
    {L"tommorrow", L"tomorrow"},
    {L"tounge", L"tongue"},
    {L"truely", L"truly"},
    {L"twelth", L"twelfth"},
    {L"tyrany", L"tyranny"},
    {L"underate", L"underrate"},
    {L"untill", L"until"},
    {L"unuseual", L"unusual"},
    {L"upholstry", L"upholstery"},
    {L"usible", L"usable"},
    {L"useing", L"using"},
    {L"usualy", L"usually"},
    {L"vaccuum", L"vacuum"},
    {L"vegatarian", L"vegetarian"},
    {L"vehical", L"vehicle"},
    {L"visious", L"vicious"},
    {L"villege", L"village"},
    {L"wierd", L"weird"},
    {L"wellcome", L"welcome"},
    {L"wellfare", L"welfare"},
    {L"wilfull", L"willful"},
    {L"withold", L"withhold"},
    {L"writting", L"writing"},
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
    std::vector<string16> suggestions;
    size_t input_length = 0;
    if (kTestCases[i].input != NULL) {
      input_length = wcslen(kTestCases[i].input);
    }
    bool result = SpellCheckerPlatform::CheckSpelling(
        WideToUTF16(kTestCases[i].input), 0);
    EXPECT_FALSE(result);

    SpellCheckerPlatform::FillSuggestionList(WideToUTF16(kTestCases[i].input),
                                             &suggestions);

    // Check if the suggested words occur.
    bool suggested_word_is_present = false;
    for (int j = 0; j < static_cast<int>(suggestions.size()); j++) {
      if (suggestions.at(j).compare(WideToUTF16(kTestCases[i].suggested_word))
          == 0) {
        suggested_word_is_present = true;
        break;
      }
    }

    EXPECT_TRUE(suggested_word_is_present);
  }
}
<commit_msg>Clean up spellchecker unittest.  In particular, this:   * Fixes some errors -- the test is apparently not being run currently, for reasons I'm fixing separately   * Uses narrow strings instead of wide where there isn't any reason to use wide   * Prints out the word in question when a failure happens   * Tries to otherwise clean up the code<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/string_util.h"
#include "chrome/browser/spellchecker_platform_engine.h"
#include "testing/gtest/include/gtest/gtest.h"

// Tests that words are properly ignored. Currently only enabled on OS X as it
// is the only platform to support ignoring words. Note that in this test, we
// supply a non-zero doc_tag, in order to test that ignored words are matched to
// the correct document.
TEST(PlatformSpellCheckTest, IgnoreWords_EN_US) {
  const char* kTestCases[] = {
    "teh",
    "morblier",
    "watre",
    "noooen",
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
    const string16 word(ASCIIToUTF16(kTestCases[i]));
    const int doc_tag = SpellCheckerPlatform::GetDocumentTag();

    // The word should show up as misspelled.
    EXPECT_FALSE(SpellCheckerPlatform::CheckSpelling(word, doc_tag)) << word;

    // Ignore the word.
    SpellCheckerPlatform::IgnoreWord(word);

    // The word should now show up as correctly spelled.
    EXPECT_TRUE(SpellCheckerPlatform::CheckSpelling(word, doc_tag)) << word;

    // Close the docuemnt. Any words that we had previously ignored should no
    // longer be ignored and thus should show up as misspelled.
    SpellCheckerPlatform::CloseDocumentWithTag(doc_tag);

    // The word should now show be spelled wrong again
    EXPECT_FALSE(SpellCheckerPlatform::CheckSpelling(word, doc_tag)) << word;
  }
}  // Test IgnoreWords_EN_US

TEST(PlatformSpellCheckTest, SpellCheckSuggestions_EN_US) {
  static const struct {
    const char* input;           // A string to be tested.
    const char* suggested_word;  // A suggested word that should occur.
  } kTestCases[] = {
    // We need to have separate test cases here, since hunspell and the OS X
    // spellchecking service occasionally differ on what they consider a valid
    // suggestion for a given word, although these lists could likely be
    // integrated somewhat. The test cases for non-Mac are in
    // chrome/renderer/spellcheck_unittest.cc
    // These words come from the wikipedia page of the most commonly
    // misspelled words in english.
    // (http://en.wikipedia.org/wiki/Commonly_misspelled_words).
    // However, 10.6 loads multiple dictionaries and enables many non-English
    // dictionaries by default. As a result, we have removed from the list any
    // word that is marked as correct because it is correct in another
    // language.
    {"absense", "absence"},
    {"acceptible", "acceptable"},
    {"accidentaly", "accidentally"},
    {"acheive", "achieve"},
    {"acknowlege", "acknowledge"},
    {"acquaintence", "acquaintance"},
    {"aquire", "acquire"},
    {"aquit", "acquit"},
    {"acrage", "acreage"},
    {"adultary", "adultery"},
    {"advertize", "advertise"},
    {"adviseable", "advisable"},
    {"alchohol", "alcohol"},
    {"alege", "allege"},
    {"allegaince", "allegiance"},
    {"allmost", "almost"},
    // Ideally, this test should pass. It works in firefox, but not in hunspell
    // or OS X.
    // {"alot", "a lot"},
    {"amatuer", "amateur"},
    {"ammend", "amend"},
    {"amung", "among"},
    {"anually", "annually"},
    {"apparant", "apparent"},
    {"artic", "arctic"},
    {"arguement", "argument"},
    {"athiest", "atheist"},
    {"athelete", "athlete"},
    {"avrage", "average"},
    {"awfull", "awful"},
    {"ballance", "balance"},
    {"basicly", "basically"},
    {"becuase", "because"},
    {"becomeing", "becoming"},
    {"befor", "before"},
    {"begining", "beginning"},
    {"beleive", "believe"},
    {"bellweather", "bellwether"},
    {"benifit", "benefit"},
    {"bouy", "buoy"},
    {"briliant", "brilliant"},
    {"burgler", "burglar"},
    {"camoflage", "camouflage"},
    {"carefull", "careful"},
    {"Carribean", "Caribbean"},
    {"catagory", "category"},
    {"cauhgt", "caught"},
    {"cieling", "ceiling"},
    {"cemetary", "cemetery"},
    {"certin", "certain"},
    {"changable", "changeable"},
    {"cheif", "chief"},
    {"citezen", "citizen"},
    {"collaegue", "colleague"},
    {"colum", "column"},
    {"comming", "coming"},
    {"commited", "committed"},
    {"compitition", "competition"},
    {"conceed", "concede"},
    {"congradulate", "congratulate"},
    {"consciencious", "conscientious"},
    {"concious", "conscious"},
    {"concensus", "consensus"},
    {"contraversy", "controversy"},
    {"conveniance", "convenience"},
    {"critecize", "criticize"},
    {"dacquiri", "daiquiri"},
    {"decieve", "deceive"},
    {"dicide", "decide"},
    {"definate", "definite"},
    {"definitly", "definitely"},
    {"desparate", "desperate"},
    {"develope", "develop"},
    {"diffrence", "difference"},
    {"disapear", "disappear"},
    {"disapoint", "disappoint"},
    {"disasterous", "disastrous"},
    {"disipline", "discipline"},
    {"drunkeness", "drunkenness"},
    {"dumbell", "dumbbell"},
    {"easely", "easily"},
    {"eigth", "eight"},
    {"embarass", "embarrass"},
    {"enviroment", "environment"},
    {"equiped", "equipped"},
    {"equiptment", "equipment"},
    {"exagerate", "exaggerate"},
    {"exellent", "excellent"},
    {"exsept", "except"},
    {"exercize", "exercise"},
    {"exilerate", "exhilarate"},
    {"existance", "existence"},
    {"experiance", "experience"},
    {"experament", "experiment"},
    {"explaination", "explanation"},
    {"facinating", "fascinating"},
    {"firey", "fiery"},
    {"finaly", "finally"},
    {"flourescent", "fluorescent"},
    {"foriegn", "foreign"},
    {"fourty", "forty"},
    {"foreward", "forward"},
    {"freind", "friend"},
    {"fundemental", "fundamental"},
    {"guage", "gauge"},
    {"generaly", "generally"},
    {"goverment", "government"},
    {"gratefull", "grateful"},
    {"garantee", "guarantee"},
    {"guidence", "guidance"},
    {"happyness", "happiness"},
    {"harrass", "harass"},
    {"heighth", "height"},
    {"heirarchy", "hierarchy"},
    {"humerous", "humorous"},
    {"hygene", "hygiene"},
    {"hipocrit", "hypocrite"},
    {"idenity", "identity"},
    {"ignorence", "ignorance"},
    {"imaginery", "imaginary"},
    {"immitate", "imitate"},
    {"immitation", "imitation"},
    {"imediately", "immediately"},
    {"incidently", "incidentally"},
    {"independant", "independent"},
    {"indispensible", "indispensable"},
    {"innoculate", "inoculate"},
    {"inteligence", "intelligence"},
    {"intresting", "interesting"},
    {"interuption", "interruption"},
    {"irrelevent", "irrelevant"},
    {"irritible", "irritable"},
    {"jellous", "jealous"},
    {"knowlege", "knowledge"},
    {"labratory", "laboratory"},
    {"lenght", "length"},
    {"liason", "liaison"},
    {"libary", "library"},
    {"lisence", "license"},
    {"lonelyness", "loneliness"},
    {"lieing", "lying"},
    {"maintenence", "maintenance"},
    {"manuever", "maneuver"},
    {"marrige", "marriage"},
    {"mathmatics", "mathematics"},
    {"medcine", "medicine"},
    {"miniture", "miniature"},
    {"minite", "minute"},
    {"mischevous", "mischievous"},
    {"mispell", "misspell"},
    // Maybe this one should pass, as it works in hunspell, but not in firefox.
    // {"misterius", "mysterious"},
    {"naturaly", "naturally"},
    {"neccessary", "necessary"},
    {"neice", "niece"},
    {"nieghbor", "neighbor"},
    {"nieghbour", "neighbor"},
    {"niether", "neither"},
    {"noticable", "noticeable"},
    {"occassion", "occasion"},
    {"occasionaly", "occasionally"},
    {"occurrance", "occurrence"},
    {"occured", "occurred"},
    {"ommision", "omission"},
    {"oppurtunity", "opportunity"},
    {"outragous", "outrageous"},
    {"parrallel", "parallel"},
    {"parliment", "parliament"},
    {"particurly", "particularly"},
    {"passtime", "pastime"},
    {"peculier", "peculiar"},
    {"percieve", "perceive"},
    {"pernament", "permanent"},
    {"perseverence", "perseverance"},
    {"personaly", "personally"},
    {"persaude", "persuade"},
    {"pichure", "picture"},
    {"peice", "piece"},
    {"plagerize", "plagiarize"},
    {"playright", "playwright"},
    {"plesant", "pleasant"},
    {"pollitical", "political"},
    {"posession", "possession"},
    {"potatos", "potatoes"},
    {"practicle", "practical"},
    {"preceed", "precede"},
    {"predjudice", "prejudice"},
    {"presance", "presence"},
    {"privelege", "privilege"},
    // This one should probably work. It does in FF and Hunspell.
    // {"probly", "probably"},
    {"proffesional", "professional"},
    {"promiss", "promise"},
    {"pronounciation", "pronunciation"},
    {"prufe", "proof"},
    {"psycology", "psychology"},
    {"publically", "publicly"},
    {"quanity", "quantity"},
    {"quarentine", "quarantine"},
    {"questionaire", "questionnaire"},
    {"readible", "readable"},
    {"realy", "really"},
    {"recieve", "receive"},
    {"reciept", "receipt"},
    {"reconize", "recognize"},
    {"recomend", "recommend"},
    {"refered", "referred"},
    {"referance", "reference"},
    {"relevent", "relevant"},
    {"religous", "religious"},
    {"repitition", "repetition"},
    {"restarant", "restaurant"},
    {"rythm", "rhythm"},
    {"rediculous", "ridiculous"},
    {"sacrefice", "sacrifice"},
    {"saftey", "safety"},
    {"sissors", "scissors"},
    {"secratary", "secretary"},
    {"seperate", "separate"},
    {"sargent", "sergeant"},
    {"shineing", "shining"},
    {"similer", "similar"},
    {"sinceerly", "sincerely"},
    {"speach", "speech"},
    {"strenght", "strength"},
    {"succesful", "successful"},
    {"supercede", "supersede"},
    {"surelly", "surely"},
    {"suprise", "surprise"},
    {"temperture", "temperature"},
    {"temprary", "temporary"},
    {"tommorrow", "tomorrow"},
    {"tounge", "tongue"},
    {"truely", "truly"},
    {"twelth", "twelfth"},
    {"tyrany", "tyranny"},
    {"underate", "underrate"},
    {"untill", "until"},
    {"unuseual", "unusual"},
    {"upholstry", "upholstery"},
    {"usible", "usable"},
    {"useing", "using"},
    {"usualy", "usually"},
    {"vaccuum", "vacuum"},
    {"vegatarian", "vegetarian"},
    {"vehical", "vehicle"},
    {"visious", "vicious"},
    {"villege", "village"},
    {"wierd", "weird"},
    {"wellcome", "welcome"},
    {"wellfare", "welfare"},
    {"wilfull", "willful"},
    {"withold", "withhold"},
    {"writting", "writing"},
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
    const string16 word(ASCIIToUTF16(kTestCases[i].input));
    EXPECT_FALSE(SpellCheckerPlatform::CheckSpelling(word, 0)) << word;

    // Check if the suggested words occur.
    std::vector<string16> suggestions;
    SpellCheckerPlatform::FillSuggestionList(word, &suggestions);
    bool suggested_word_is_present = false;
    const string16 suggested_word(ASCIIToUTF16(kTestCases[i].suggested_word));
    for (size_t j = 0; j < suggestions.size(); j++) {
      if (suggestions[j].compare(suggested_word) == 0) {
        suggested_word_is_present = true;
        break;
      }
    }
    EXPECT_TRUE(suggested_word_is_present) << suggested_word;
  }
}
<|endoftext|>


<commit_before>//===- lib/Trace/ScanFormatSpecifiers.cpp ---------------------------------===//
//
//                                    SeeC
//
// This file is distributed under The MIT License (MIT). See LICENSE.TXT for
// details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
//===----------------------------------------------------------------------===//

#include "seec/Trace/ScanFormatSpecifiers.hpp"

#include <cstring>
#include <limits>

namespace seec {

namespace trace {

ScanConversionSpecifier
ScanConversionSpecifier::readNextFrom(char const * const String) {
  ScanConversionSpecifier Result;

  // Find '%'.
  Result.Start = std::strchr(String, '%');
  if (!Result.Start)
    return Result;

  auto Remainder = Result.Start;
  if (*++Remainder == '\0')
    return Result;

  // Read assignment suppression '*'.
  if (*Remainder == '*') {
    Result.SuppressAssignment = true;
    if (*++Remainder == '\0')
      return Result;
  }

  // Read maximum field width.
  if(isdigit(*Remainder)){
    Result.WidthSpecified = true;

    // Parse int from string.
    char *ParseEnd;
    Result.Width = std::strtoul(Remainder, &ParseEnd, 10);
    Remainder = ParseEnd;

    if (*Remainder == '\0')
      return Result;
  }

  // Read length modifier.
  Result.Length = readLengthModifier(Remainder, &Remainder);
  if (*Remainder == '\0')
    return Result;

  // Read specifier.
  switch (*Remainder) {
#define SEEC_SCAN_FORMAT_SPECIFIER(ID, CHR, WSPACE, SUPPRESS, LENS)            \
    case CHR:                                                                  \
      Result.Conversion = Specifier::ID;                                       \
      break;
#include "seec/Trace/ScanFormatSpecifiers.def"
    default:
      return Result;
  }

  // Special case for parsing set specifier.
  if (Result.Conversion == Specifier::set) {
    auto const UCharValues = std::numeric_limits<unsigned char>::max() + 1;

    Result.SetLookup.reset(new bool[UCharValues]);
    for (unsigned i = 0; i < UCharValues; ++i)
      Result.SetLookup[i] = false;

    if (*++Remainder == '\0')
      return Result;

    // Make set a negation.
    if (*Remainder == '^') {
      Result.SetNegation = true;
      if (*++Remainder == '\0')
        return Result;
    }

    // Special case for including ']' in a set.
    if (*Remainder == ']') {
      Result.SetCharacters.push_back(']');

      auto const CharIdx = static_cast<unsigned char>(']');
      assert(CharIdx < UCharValues);
      Result.SetLookup[CharIdx] = true;

      if (*++Remainder == '\0')
        return Result;
    }

    // Add all remaining characters to the set (until ']' is found).
    while (*Remainder != ']') {
      Result.SetCharacters.push_back(*Remainder);

      auto const CharIdx = static_cast<unsigned char>(*Remainder);
      assert(CharIdx < UCharValues);
      Result.SetLookup[CharIdx] = true;

      if (*++Remainder == '\0')
        return Result;
    }

    if (Result.SetNegation) {
      for (unsigned i = 0; i < UCharValues; ++i)
        Result.SetLookup[i] = !Result.SetLookup[i];
    }
  }

  // Set the end of the parsed region.
  Result.End = ++Remainder;

  return Result;
}

} // namespace trace (in seec)

} // namespace seec
<commit_msg>Fix gcc compiler warning about comparing unsigned and signed.<commit_after>//===- lib/Trace/ScanFormatSpecifiers.cpp ---------------------------------===//
//
//                                    SeeC
//
// This file is distributed under The MIT License (MIT). See LICENSE.TXT for
// details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
//===----------------------------------------------------------------------===//

#include "seec/Trace/ScanFormatSpecifiers.hpp"

#include <cstring>
#include <limits>

namespace seec {

namespace trace {

ScanConversionSpecifier
ScanConversionSpecifier::readNextFrom(char const * const String) {
  ScanConversionSpecifier Result;

  // Find '%'.
  Result.Start = std::strchr(String, '%');
  if (!Result.Start)
    return Result;

  auto Remainder = Result.Start;
  if (*++Remainder == '\0')
    return Result;

  // Read assignment suppression '*'.
  if (*Remainder == '*') {
    Result.SuppressAssignment = true;
    if (*++Remainder == '\0')
      return Result;
  }

  // Read maximum field width.
  if(isdigit(*Remainder)){
    Result.WidthSpecified = true;

    // Parse int from string.
    char *ParseEnd;
    Result.Width = std::strtoul(Remainder, &ParseEnd, 10);
    Remainder = ParseEnd;

    if (*Remainder == '\0')
      return Result;
  }

  // Read length modifier.
  Result.Length = readLengthModifier(Remainder, &Remainder);
  if (*Remainder == '\0')
    return Result;

  // Read specifier.
  switch (*Remainder) {
#define SEEC_SCAN_FORMAT_SPECIFIER(ID, CHR, WSPACE, SUPPRESS, LENS)            \
    case CHR:                                                                  \
      Result.Conversion = Specifier::ID;                                       \
      break;
#include "seec/Trace/ScanFormatSpecifiers.def"
    default:
      return Result;
  }

  // Special case for parsing set specifier.
  if (Result.Conversion == Specifier::set) {
    int const UCharValues = std::numeric_limits<unsigned char>::max() + 1;

    Result.SetLookup.reset(new bool[UCharValues]);
    for (int i = 0; i < UCharValues; ++i)
      Result.SetLookup[i] = false;

    if (*++Remainder == '\0')
      return Result;

    // Make set a negation.
    if (*Remainder == '^') {
      Result.SetNegation = true;
      if (*++Remainder == '\0')
        return Result;
    }

    // Special case for including ']' in a set.
    if (*Remainder == ']') {
      Result.SetCharacters.push_back(']');

      auto const CharIdx = static_cast<unsigned char>(']');
      assert(CharIdx < UCharValues);
      Result.SetLookup[CharIdx] = true;

      if (*++Remainder == '\0')
        return Result;
    }

    // Add all remaining characters to the set (until ']' is found).
    while (*Remainder != ']') {
      Result.SetCharacters.push_back(*Remainder);

      auto const CharIdx = static_cast<unsigned char>(*Remainder);
      assert(CharIdx < UCharValues);
      Result.SetLookup[CharIdx] = true;

      if (*++Remainder == '\0')
        return Result;
    }

    if (Result.SetNegation) {
      for (int i = 0; i < UCharValues; ++i)
        Result.SetLookup[i] = !Result.SetLookup[i];
    }
  }

  // Set the end of the parsed region.
  Result.End = ++Remainder;

  return Result;
}

} // namespace trace (in seec)

} // namespace seec
<|endoftext|>


<commit_before>// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "time.h"
#include <thread>
#include <immintrin.h>

namespace vespalib {

system_time
to_utc(steady_time ts) {
    system_clock::time_point nowUtc = system_clock::now();
    steady_time nowSteady = steady_clock::now();
    return system_time(std::chrono::duration_cast<system_time::duration>(nowUtc.time_since_epoch() - nowSteady.time_since_epoch() + ts.time_since_epoch()));
}

namespace {

string
to_string(duration dur) {
    time_t timeStamp = std::chrono::duration_cast<std::chrono::seconds>(dur).count();
    struct tm timeStruct;
    gmtime_r(&timeStamp, &timeStruct);
    char timeString[128];
    strftime(timeString, sizeof(timeString), "%F %T", &timeStruct);
    char retval[160];
    uint32_t milliSeconds = count_ms(dur) % 1000;
    snprintf(retval, sizeof(retval), "%s.%03u UTC", timeString, milliSeconds);
    return std::string(retval);
}

}

string
to_string(system_time time) {
    return to_string(time.time_since_epoch());
}

Timer::~Timer() = default;

void
Timer::waitAtLeast(duration dur, bool busyWait) {
    if (busyWait) {
        steady_clock::time_point deadline = steady_clock::now() + dur;
        while (steady_clock::now() < deadline) {
            for (int i = 0; i < 1000; i++) {
                _mm_pause();
            }
        }
    } else {
        std::this_thread::sleep_for(dur);
    }
}

}
<commit_msg>There are so many combinations that the libstdc++ library can be built that the performance you get from std::chrono::system_clock and stxad::chrono::steady_clock has a dramatic performance difference. On RHEL7/Centos with an witout this patch is 18ns vs 550ns.<commit_after>// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "time.h"
#include <thread>
#include <immintrin.h>

namespace vespalib {

system_time
to_utc(steady_time ts) {
    system_clock::time_point nowUtc = system_clock::now();
    steady_time nowSteady = steady_clock::now();
    return system_time(std::chrono::duration_cast<system_time::duration>(nowUtc.time_since_epoch() - nowSteady.time_since_epoch() + ts.time_since_epoch()));
}

namespace {

string
to_string(duration dur) {
    time_t timeStamp = std::chrono::duration_cast<std::chrono::seconds>(dur).count();
    struct tm timeStruct;
    gmtime_r(&timeStamp, &timeStruct);
    char timeString[128];
    strftime(timeString, sizeof(timeString), "%F %T", &timeStruct);
    char retval[160];
    uint32_t milliSeconds = count_ms(dur) % 1000;
    snprintf(retval, sizeof(retval), "%s.%03u UTC", timeString, milliSeconds);
    return std::string(retval);
}

}

string
to_string(system_time time) {
    return to_string(time.time_since_epoch());
}

Timer::~Timer() = default;

void
Timer::waitAtLeast(duration dur, bool busyWait) {
    if (busyWait) {
        steady_clock::time_point deadline = steady_clock::now() + dur;
        while (steady_clock::now() < deadline) {
            for (int i = 0; i < 1000; i++) {
                _mm_pause();
            }
        }
    } else {
        std::this_thread::sleep_for(dur);
    }
}

}

namespace std::chrono {

// This is a hack to avoid the slow clock computations on RHEL7/CentOS 7 due to using systemcalls.
// This brings cost down from 550-560ns to 18-19ns

inline namespace _V2 {

system_clock::time_point
system_clock::now() noexcept {
    timespec tp;
    clock_gettime(CLOCK_REALTIME, &tp);
    return time_point(duration(chrono::seconds(tp.tv_sec)
                               + chrono::nanoseconds(tp.tv_nsec)));
}

steady_clock::time_point
steady_clock::now() noexcept {
    timespec tp;
    clock_gettime(CLOCK_MONOTONIC, &tp);
    return time_point(duration(chrono::seconds(tp.tv_sec)
                               + chrono::nanoseconds(tp.tv_nsec)));
}

}
}
<|endoftext|>


<commit_before>#include "SliceRenderer.h"

#include "GLBlaat/GL.h"
#include "GLBlaat/GLFramebuffer.h"
#include "GLBlaat/GLTextureManager.h"

#include "View.h"

#include "Renderables/Renderable.h"
#include "Renderables/VBOMesh.h"

namespace NQVTK
{
	// ------------------------------------------------------------------------
	SliceRenderer::SliceRenderer()
		: shader(0)
	{
	}

	// ------------------------------------------------------------------------
	SliceRenderer::~SliceRenderer()
	{
	}

	// ------------------------------------------------------------------------
	void SliceRenderer::PrepareForRenderable(int objectId,
		Renderable *renderable)
	{
		if (shader) shader->SetUniform1i("objectId", objectId);
		if (shaderAttribs.size() > 0)
		{
			renderable->SetupAttributes(shaderAttribs);
		}
		// If shader is null, this will still setup textures
		// (remember to enable them during rendering...)
		renderable->ApplyParamSets(shader, tm);
		tm->Bind();
	}

	// ------------------------------------------------------------------------
	void SliceRenderer::Draw()
	{
		// Prepare for rendering
		if (fboTarget)
		{
			fboTarget->Bind();
		}
		glViewport(viewportX, viewportY, viewportWidth, viewportHeight);

		// TODO: per-object textures are not initialized before SetupProgram
		// This doesn't matter in layered rendering because the scribe doesn't
		// use them, but will add them to the tm. However, here we don't have
		// such an extra pass...
		if (view)
		{
			if (shader) shader->Start();
			for (unsigned int objectId = 0;
				objectId < view->GetNumberOfRenderables();
				++objectId)
			{
				Renderable *renderable = view->GetRenderable(objectId);
				PrepareForRenderable(objectId, renderable);
			}
			if (shader) shader->Stop();
		}

		Clear();

		glPushAttrib(GL_ALL_ATTRIB_BITS);
		glDisable(GL_LIGHTING);
		glDepthMask(GL_FALSE);
		glDisable(GL_DEPTH_TEST);

		// Use alpha blending for now (with premultiplied alpha)
		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);

		if (view)
		{
			if (shader)
			{
				shader->Start();
				tm->SetupProgram(shader);
				tm->Bind();
			}

			// Compute origin and right/up vectors which preserve aspect ratio
			UpdateViewportPlane();

			// Draw a single slice for each renderable
			for (unsigned int objectId = 0;
				objectId < view->GetNumberOfRenderables();
				++objectId)
			{
				// The shader should discard renderables without volumes and
				// generate appropriate alpha values or discards for blending

				// Visibility implies that the renderable is not null
				if (view->GetVisibility(objectId))
				{
					Renderable *renderable = view->GetRenderable(objectId);
					PrepareForRenderable(objectId, renderable);

					glColor4d(
						renderable->color.x,
						renderable->color.y,
						renderable->color.z,
						renderable->opacity);

					// Draw the full screen quad for our slice plane
					glBegin(GL_QUADS);
					glTexCoord3dv(vporigin.V);
					glVertex3d(-1.0, -1.0, 0.0);
					glTexCoord3dv((vporigin + vpright).V);
					glVertex3d(1.0, -1.0, 0.0);
					glTexCoord3dv((vporigin + vpright + vpup).V);
					glVertex3d(1.0, 1.0, 0.0);
					glTexCoord3dv((vporigin + vpup).V);
					glVertex3d(-1.0, 1.0, 0.0);
					glEnd();
				}
			}

			if (shader)
			{
				tm->Unbind();
				shader->Stop();
			}
		}

		glPopAttrib();

		if (fboTarget)
		{
			fboTarget->Unbind();
		}
	}

	// ------------------------------------------------------------------------
	void SliceRenderer::SetPlane(const Vector3 &origin,
		const Vector3 &right, const Vector3 &up)
	{
		this->origin = origin;
		this->right = right;
		this->up = up;
	}

	// ------------------------------------------------------------------------
	GLProgram *SliceRenderer::SetShader(GLProgram *shader)
	{
		GLProgram *oldshader = this->shader;
		this->shader = shader;
		shaderAttribs.clear();
		if (shader) shaderAttribs = shader->GetActiveAttributes();
		if (shader == oldshader) return 0;
		return oldshader;
	}

	// ------------------------------------------------------------------------
	bool SliceRenderer::CreateDefaultShader()
	{
		GLProgram *shader = GLProgram::New();
		if (!shader) return false;
		bool ok = true;
		if (ok) ok = shader->AddVertexShader(
			"void main() {"
			"   gl_TexCoord[0] = gl_MultiTexCoord0;"
			"   gl_Position = gl_Vertex;"
			"}");
		// TODO: we need the actual object transform here
		if (ok) ok = shader->AddFragmentShader(
			"uniform sampler3D volume;"
			"uniform vec3 volumeOrigin;"
			"uniform vec3 volumeSize;"
			"uniform float volumeDataShift;"
			"uniform float volumeDataScale;"
			"uniform int objectId;"
			"void main() {"
			"   vec3 tc = (gl_TexCoord[0].xyz - volumeOrigin) / volumeSize;"
			"   vec3 tex = /*vec3(volumeDataShift) + volumeDataScale * */"
			"      texture3D(volume, tc).xyz;"
			"   vec4 color = vec4(tex, length(tex));"
			"   for (int i = 0; i < 3; ++i) {"
			"      if (tc[i] < 0.0 || tc[i] > 1.0) {"
			"         color = vec4(vec3(0.0), 1.0);"
			"      }"
			"   }"
			"   gl_FragColor = vec4(color.rgb * color.a, color.a);"
			"}");
		if (ok) ok = shader->Link();
		if (ok) SetShader(shader);
		if (!ok) delete shader;
		return ok;
	}

	// ------------------------------------------------------------------------
	void SliceRenderer::UpdateViewportPlane()
	{
		double viewportAspect = static_cast<double>(viewportWidth) /
			static_cast<double>(viewportHeight);
		double sliceAspect = right.length() / up.length();
		if (viewportAspect > sliceAspect)
		{
			// Add margin left and right
			double margin = viewportAspect / sliceAspect - 1.0;
			vporigin = origin - 0.5 * margin * right;
			vpright = right + margin * right;
			vpup = up;
		}
		else
		{
			// Add margin above and below
			double margin = sliceAspect / viewportAspect - 1.0;
			vporigin = origin - 0.5 * margin * up;
			vpright = right;
			vpup = up + margin * up;
		}
	}
}
<commit_msg>Enabled viewport jittering in the SliceRenderer (untested).<commit_after>#include "SliceRenderer.h"

#include "GLBlaat/GL.h"
#include "GLBlaat/GLFramebuffer.h"
#include "GLBlaat/GLTextureManager.h"

#include "Camera.h"
#include "View.h"

#include "Renderables/Renderable.h"
#include "Renderables/VBOMesh.h"

namespace NQVTK
{
	// ------------------------------------------------------------------------
	SliceRenderer::SliceRenderer()
		: shader(0)
	{
	}

	// ------------------------------------------------------------------------
	SliceRenderer::~SliceRenderer()
	{
	}

	// ------------------------------------------------------------------------
	void SliceRenderer::PrepareForRenderable(int objectId,
		Renderable *renderable)
	{
		if (shader) shader->SetUniform1i("objectId", objectId);
		if (shaderAttribs.size() > 0)
		{
			renderable->SetupAttributes(shaderAttribs);
		}
		// If shader is null, this will still setup textures
		// (remember to enable them during rendering...)
		renderable->ApplyParamSets(shader, tm);
		tm->Bind();
	}

	// ------------------------------------------------------------------------
	void SliceRenderer::Draw()
	{
		// Prepare for rendering
		if (fboTarget)
		{
			fboTarget->Bind();
		}
		glViewport(viewportX, viewportY, viewportWidth, viewportHeight);

		// TODO: per-object textures are not initialized before SetupProgram
		// This doesn't matter in layered rendering because the scribe doesn't
		// use them, but will add them to the tm. However, here we don't have
		// such an extra pass...
		if (view)
		{
			if (shader) shader->Start();
			for (unsigned int objectId = 0;
				objectId < view->GetNumberOfRenderables();
				++objectId)
			{
				Renderable *renderable = view->GetRenderable(objectId);
				PrepareForRenderable(objectId, renderable);
			}
			if (shader) shader->Stop();
		}

		Clear();

		glPushAttrib(GL_ALL_ATTRIB_BITS);
		glDisable(GL_LIGHTING);
		glDepthMask(GL_FALSE);
		glDisable(GL_DEPTH_TEST);

		// Use alpha blending for now (with premultiplied alpha)
		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);

		if (view)
		{
			if (shader)
			{
				shader->Start();
				tm->SetupProgram(shader);
				tm->Bind();
			}

			// Compute origin and right/up vectors which preserve aspect ratio
			UpdateViewportPlane();

			// Draw a single slice for each renderable
			for (unsigned int objectId = 0;
				objectId < view->GetNumberOfRenderables();
				++objectId)
			{
				// The shader should discard renderables without volumes and
				// generate appropriate alpha values or discards for blending

				// Visibility implies that the renderable is not null
				if (view->GetVisibility(objectId))
				{
					Renderable *renderable = view->GetRenderable(objectId);
					PrepareForRenderable(objectId, renderable);

					glColor4d(
						renderable->color.x,
						renderable->color.y,
						renderable->color.z,
						renderable->opacity);

					// Draw the full screen quad for our slice plane
					glBegin(GL_QUADS);
					glTexCoord3dv(vporigin.V);
					glVertex3d(-1.0, -1.0, 0.0);
					glTexCoord3dv((vporigin + vpright).V);
					glVertex3d(1.0, -1.0, 0.0);
					glTexCoord3dv((vporigin + vpright + vpup).V);
					glVertex3d(1.0, 1.0, 0.0);
					glTexCoord3dv((vporigin + vpup).V);
					glVertex3d(-1.0, 1.0, 0.0);
					glEnd();
				}
			}

			if (shader)
			{
				tm->Unbind();
				shader->Stop();
			}
		}

		glPopAttrib();

		if (fboTarget)
		{
			fboTarget->Unbind();
		}
	}

	// ------------------------------------------------------------------------
	void SliceRenderer::SetPlane(const Vector3 &origin,
		const Vector3 &right, const Vector3 &up)
	{
		this->origin = origin;
		this->right = right;
		this->up = up;
	}

	// ------------------------------------------------------------------------
	GLProgram *SliceRenderer::SetShader(GLProgram *shader)
	{
		GLProgram *oldshader = this->shader;
		this->shader = shader;
		shaderAttribs.clear();
		if (shader) shaderAttribs = shader->GetActiveAttributes();
		if (shader == oldshader) return 0;
		return oldshader;
	}

	// ------------------------------------------------------------------------
	bool SliceRenderer::CreateDefaultShader()
	{
		GLProgram *shader = GLProgram::New();
		if (!shader) return false;
		bool ok = true;
		if (ok) ok = shader->AddVertexShader(
			"void main() {"
			"   gl_TexCoord[0] = gl_MultiTexCoord0;"
			"   gl_Position = gl_Vertex;"
			"}");
		// TODO: we need the actual object transform here
		if (ok) ok = shader->AddFragmentShader(
			"uniform sampler3D volume;"
			"uniform vec3 volumeOrigin;"
			"uniform vec3 volumeSize;"
			"uniform float volumeDataShift;"
			"uniform float volumeDataScale;"
			"uniform int objectId;"
			"void main() {"
			"   vec3 tc = (gl_TexCoord[0].xyz - volumeOrigin) / volumeSize;"
			"   vec3 tex = /*vec3(volumeDataShift) + volumeDataScale * */"
			"      texture3D(volume, tc).xyz;"
			"   vec4 color = vec4(tex, length(tex));"
			"   for (int i = 0; i < 3; ++i) {"
			"      if (tc[i] < 0.0 || tc[i] > 1.0) {"
			"         color = vec4(vec3(0.0), 1.0);"
			"      }"
			"   }"
			"   gl_FragColor = vec4(color.rgb * color.a, color.a);"
			"}");
		if (ok) ok = shader->Link();
		if (ok) SetShader(shader);
		if (!ok) delete shader;
		return ok;
	}

	// ------------------------------------------------------------------------
	void SliceRenderer::UpdateViewportPlane()
	{
		double viewportAspect = static_cast<double>(viewportWidth) /
			static_cast<double>(viewportHeight);
		double sliceAspect = right.length() / up.length();
		if (viewportAspect > sliceAspect)
		{
			// Add margin left and right
			double margin = viewportAspect / sliceAspect - 1.0;
			vporigin = origin - 0.5 * margin * right;
			vpright = right + margin * right;
			vpup = up;
		}
		else
		{
			// Add margin above and below
			double margin = sliceAspect / viewportAspect - 1.0;
			vporigin = origin - 0.5 * margin * up;
			vpright = right;
			vpup = up + margin * up;
		}
		// Apply jitter
		vporigin += camera->jitterX * vpright + camera->jitterY * vpup;
	}
}
<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <cstring>

#define MAX_PIECE_NUM 64

using namespace std;

int pieces[MAX_PIECE_NUM];
int piece_num;
int piece_len_sum;
bool is_visited[MAX_PIECE_NUM];

void solve();

bool dfs(int idx, int tgt_value, int acc, int rest);

void print();

int main() {
  int n;

  while (cin >> n && n != 0) {
    piece_num = n;
    piece_len_sum = 0;

    memset(is_visited, false, sizeof(is_visited));

    for (int i = 0; i < piece_num; i++) {
      cin >> n;
      pieces[i] = n;
      piece_len_sum += n;
    }

    solve();
  }
}

void solve() {
  sort(pieces, pieces + piece_num);

  bool res = false;
  for (int tgt_value = pieces[piece_num - 1]; tgt_value <= piece_len_sum;
      tgt_value++) {

    if (piece_len_sum % tgt_value)
      continue;

    //res = dfs(piece_num - 1, tgt_value, 0, 0, piece_len_sum);
    res = dfs(piece_num - 1, tgt_value, 0, piece_len_sum);

    if (res) {
      cout << tgt_value << endl;
      break;
    }
  }

  return;
}

bool dfs(int idx, int tgt_value, int acc, int rest) {
  if (rest == 0)
    return true;

  if (acc == tgt_value)
    return true && dfs(piece_num - 1, tgt_value, 0, rest - acc);

  if (acc > tgt_value)
    return false;

  bool res = false;
  for (int i = idx; i >= 0; i--) {
    if (!is_visited[i]) {
      res = dfs(i - 1, tgt_value, acc, rest);

      if (res)
        return true;

      /*
      if (acc + pieces[i] == tgt_value)
        return true;
      */
      is_visited[i] = true;

      res = dfs(i - 1, tgt_value, acc + pieces[i], rest);

      is_visited[i] = false;

      if (res)
        return true;
    }
  }

  return false;
}

void print() {
  for (int i = 0; i < piece_num; i++)
    cout << pieces[i] << " ";

  cout << endl;
}
<commit_msg>p1011d<commit_after>#include <iostream>
#include <algorithm>
#include <cstring>

#define MAX_PIECE_NUM 64

using namespace std;

int pieces[MAX_PIECE_NUM];
int piece_num;
int piece_len_sum;
bool is_visited[MAX_PIECE_NUM];

void solve();

bool dfs(int idx, int tgt_value, int acc, int rest);

void print();

int main() {
  int n;

  while (cin >> n && n != 0) {
    piece_num = n;
    piece_len_sum = 0;

    memset(is_visited, false, sizeof(is_visited));

    for (int i = 0; i < piece_num; i++) {
      cin >> n;
      pieces[i] = n;
      piece_len_sum += n;
    }

    solve();
  }
}

void solve() {
  sort(pieces, pieces + piece_num);

  bool res = false;
  for (int tgt_value = pieces[piece_num - 1]; tgt_value <= piece_len_sum;
      tgt_value++) {

    if (piece_len_sum % tgt_value)
      continue;

    //res = dfs(piece_num - 1, tgt_value, 0, 0, piece_len_sum);
    res = dfs(piece_num - 1, tgt_value, 0, piece_len_sum);

    if (res) {
      cout << tgt_value << endl;
      break;
    }
  }

  return;
}

bool dfs(int idx, int tgt_value, int acc, int rest) {
  if (rest == 0)
    return true;

  if (acc == tgt_value)
    return true && dfs(piece_num - 1, tgt_value, 0, rest - acc);

  if (idx < 0 || acc > tgt_value)
    return false;

  bool res = false;
  for (int i = idx; i >= 0; i--) {
    if (!is_visited[i] && acc + pieces[i] <= tgt_value) {
      /*
      res = dfs(i - 1, tgt_value, acc, rest);

      if (res)
        return true;
      */

      is_visited[i] = true;
      if (acc + pieces[i] == tgt_value)
        return true && dfs(piece_num - 1, tgt_value, 0, rest - tgt_value);

      res = dfs(i - 1, tgt_value, acc + pieces[i], rest);
      if (res)
        return true;

      is_visited[i] = false;

      while (i >= 1 && pieces[i - 1] == pieces[i])
        i--;
    }
  }

  return false;
}

void print() {
  for (int i = 0; i < piece_num; i++)
    cout << pieces[i] << " ";

  cout << endl;
}
<|endoftext|>