<commit_before>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Elisavet Sakellari <elisavet.sakellari@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "ExternalInterpreterSource.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Utils/Diagnostics.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTImporter.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Sema.h"

using namespace clang;

namespace {
  class ClingASTImporter : public ASTImporter {
  private:
    cling::ExternalInterpreterSource &m_Source;

  public:
    ClingASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                     ASTContext &FromContext, FileManager &FromFileManager,
                     bool MinimalImport,
                     cling::ExternalInterpreterSource& source):
      ASTImporter(ToContext, ToFileManager, FromContext, FromFileManager,
                  MinimalImport), m_Source(source) {}
    virtual ~ClingASTImporter() = default;

    void Imported(Decl *From, Decl *To) override {
      ASTImporter::Imported(From, To);

      if (clang::TagDecl* toTagDecl = dyn_cast<TagDecl>(To)) {
        toTagDecl->setHasExternalLexicalStorage();
        toTagDecl->setMustBuildLookupTable();
        toTagDecl->setHasExternalVisibleStorage();
      }
      if (NamespaceDecl *toNamespaceDecl = dyn_cast<NamespaceDecl>(To)) {
        toNamespaceDecl->setHasExternalVisibleStorage();
      }
      if (ObjCContainerDecl *toContainerDecl = dyn_cast<ObjCContainerDecl>(To)) {
        toContainerDecl->setHasExternalLexicalStorage();
        toContainerDecl->setHasExternalVisibleStorage();
      }
      // Put the name of the Decl imported with the
      // DeclarationName coming from the parent, in  my map.
      if (NamedDecl *toNamedDecl = llvm::dyn_cast<NamedDecl>(To)) {
        NamedDecl *fromNamedDecl = llvm::dyn_cast<NamedDecl>(From);
        m_Source.addToImportedDecls(toNamedDecl->getDeclName(),
                                    fromNamedDecl->getDeclName());
      }
      if (DeclContext *toDeclContext = llvm::dyn_cast<DeclContext>(To)) {
        DeclContext *fromDeclContext = llvm::dyn_cast<DeclContext>(From);
        m_Source.addToImportedDeclContexts(toDeclContext, fromDeclContext);
      }
    }
  };
}

namespace cling {

  ExternalInterpreterSource::ExternalInterpreterSource(
        const cling::Interpreter *parent, cling::Interpreter *child) :
        m_ParentInterpreter(parent), m_ChildInterpreter(child) {

    clang::DeclContext *parentTUDeclContext =
      m_ParentInterpreter->getCI()->getASTContext().getTranslationUnitDecl();

    clang::DeclContext *childTUDeclContext =
      m_ChildInterpreter->getCI()->getASTContext().getTranslationUnitDecl();

    // Also keep in the map of Decl Contexts the Translation Unit Decl Context
    m_ImportedDeclContexts[childTUDeclContext] = parentTUDeclContext;

    FileManager &childFM = m_ChildInterpreter->getCI()->getFileManager();
    FileManager &parentFM = m_ParentInterpreter->getCI()->getFileManager();

    ASTContext &fromASTContext = m_ParentInterpreter->getCI()->getASTContext();
    ASTContext &toASTContext = m_ChildInterpreter->getCI()->getASTContext();
    ClingASTImporter* importer
      = new ClingASTImporter(toASTContext, childFM, fromASTContext, parentFM,
                             /*MinimalImport : ON*/ true, *this);
    m_Importer.reset(llvm::dyn_cast<ASTImporter>(importer));
  }

  ExternalInterpreterSource::~ExternalInterpreterSource() {}

  void ExternalInterpreterSource::ImportDecl(Decl *declToImport,
                                   DeclarationName &childDeclName,
                                   DeclarationName &parentDeclName,
                                   const DeclContext *childCurrentDeclContext) {

    // Don't do the import if we have a Function Template or using decls. They
    // are not supported by clang.
    // FIXME: These are temporary checks and should be de-activated once clang
    // supports their import.
    if ((declToImport->isFunctionOrFunctionTemplate()
         && declToImport->isTemplateDecl()) || dyn_cast<UsingDecl>(declToImport)
         || dyn_cast<UsingShadowDecl>(declToImport)) {
#ifndef NDEBUG
      utils::DiagnosticsStore DS(
        m_Importer->getFromContext().getDiagnostics(), false, false, true);

      llvm::Expected<const Decl *> To = m_Importer->Import(declToImport);
      assert(To.get() && "Import did not work!");
      assert(!DS.empty() &&
             DS[0].getID() == clang::diag::err_unsupported_ast_node &&
             "Import may be supported");
#endif
      return;
    }

    if (auto toOrErr = m_Importer->Import(declToImport)) {
      if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(*toOrErr)) {
        SetExternalVisibleDeclsForName(childCurrentDeclContext,
                                       importedNamedDecl->getDeclName(),
                                       importedNamedDecl);
      }
      // Put the name of the Decl imported with the
      // DeclarationName coming from the parent, in  my map.
      m_ImportedDecls[childDeclName] = parentDeclName;
    } else {
      logAllUnhandledErrors(toOrErr.takeError(), llvm::errs(),
                            "Error importing decl");
    }
  }

  void ExternalInterpreterSource::ImportDeclContext(
                                  DeclContext *declContextToImport,
                                  DeclarationName &childDeclName,
                                  DeclarationName &parentDeclName,
                                  const DeclContext *childCurrentDeclContext) {

    if (auto toOrErr = m_Importer->ImportContext(declContextToImport)) {

      DeclContext *importedDC = *toOrErr;
      importedDC->setHasExternalVisibleStorage(true);
      if (NamedDecl *importedND = llvm::dyn_cast<NamedDecl>(importedDC)) {
        SetExternalVisibleDeclsForName(childCurrentDeclContext,
                                       importedND->getDeclName(),
                                       importedND);
      }

      // Put the name of the DeclContext imported with the
      // DeclarationName coming from the parent, in  my map.
      m_ImportedDecls[childDeclName] = parentDeclName;

      // And also put the declaration context I found from the parent Interpreter
      // in the map of the child Interpreter to have it for the future.
      m_ImportedDeclContexts[importedDC] = declContextToImport;
    } else {
      logAllUnhandledErrors(toOrErr.takeError(), llvm::errs(),
                            "Error importing decl context");
    }
  }

  bool ExternalInterpreterSource::Import(DeclContext::lookup_result lookup_result,
                                const DeclContext *childCurrentDeclContext,
                                DeclarationName &childDeclName,
                                DeclarationName &parentDeclName) {

    for (DeclContext::lookup_iterator I = lookup_result.begin(),
          E = lookup_result.end(); I != E; ++I) {
      // Check if this Name we are looking for is
      // a DeclContext (for example a Namespace, function etc.).
      if (DeclContext *declContextToImport = llvm::dyn_cast<DeclContext>(*I)) {

        ImportDeclContext(declContextToImport, childDeclName,
                          parentDeclName, childCurrentDeclContext);

      }
      ImportDecl(*I, childDeclName, parentDeclName, childCurrentDeclContext);
    }
    return true;
  }

  ///\brief This is the one of the most important function of the class
  /// since from here initiates the lookup and import part of the missing
  /// Decl(s) (Contexts).
  ///
  bool ExternalInterpreterSource::FindExternalVisibleDeclsByName(
    const DeclContext *childCurrentDeclContext, DeclarationName childDeclName) {

    assert(childDeclName && "Child Decl name is empty");

    assert(childCurrentDeclContext->hasExternalVisibleStorage() &&
           "DeclContext has no visible decls in storage");

    //Check if we have already found this declaration Name before
    DeclarationName parentDeclName;
    std::map<clang::DeclarationName,
             clang::DeclarationName>::iterator IDecl =
                                            m_ImportedDecls.find(childDeclName);
    if (IDecl != m_ImportedDecls.end()) {
      parentDeclName = IDecl->second;
    } else {
      // Get the identifier info from the parent interpreter
      // for this Name.
      std::string name = childDeclName.getAsString();
      IdentifierTable &parentIdentifierTable =
                            m_ParentInterpreter->getCI()->getASTContext().Idents;
      IdentifierInfo &parentIdentifierInfo =
                            parentIdentifierTable.get(name);
      parentDeclName = DeclarationName(&parentIdentifierInfo);
    }

    // Search in the map of the stored Decl Contexts for this
    // Decl Context.
    std::map<const clang::DeclContext *, clang::DeclContext *>::iterator
          IDeclContext = m_ImportedDeclContexts.find(childCurrentDeclContext);
    // If childCurrentDeclContext was found before and is already in the map,
    // then do the lookup using the stored pointer.
    if (IDeclContext == m_ImportedDeclContexts.end()) return false;

    DeclContext *parentDeclContext = IDeclContext->second;

    DeclContext::lookup_result lookup_result =
                                    parentDeclContext->lookup(parentDeclName);

    // Check if we found this Name in the parent interpreter
    if (!lookup_result.empty()) {
      if (Import(lookup_result,
                 childCurrentDeclContext, childDeclName, parentDeclName))
        return true;
    }

    return false;
  }

  ///\brief Make available to child all decls in parent's decl context
  /// that corresponds to child decl context.
  void ExternalInterpreterSource::completeVisibleDeclsMap(
                                const clang::DeclContext *childDeclContext) {
    assert (childDeclContext && "No child decl context!");

    if (!childDeclContext->hasExternalVisibleStorage())
      return;

    // Search in the map of the stored Decl Contexts for this
    // Decl Context.
    std::map<const clang::DeclContext *, clang::DeclContext *>::iterator
                  IDeclContext = m_ImportedDeclContexts.find(childDeclContext);
    // If childCurrentDeclContext was found before and is already in the map,
    // then do the lookup using the stored pointer.
    if (IDeclContext == m_ImportedDeclContexts.end()) return ;

    DeclContext *parentDeclContext = IDeclContext->second;

    // Filter the decls from the external source using the stem information
    // stored in Sema.
    StringRef filter =
      m_ChildInterpreter->getCI()->getPreprocessor().getCodeCompletionFilter();
    for (DeclContext::decl_iterator IDeclContext =
                                      parentDeclContext->decls_begin(),
                                    EDeclContext =
                                      parentDeclContext->decls_end();
                              IDeclContext != EDeclContext; ++IDeclContext) {
      if (NamedDecl* parentDecl = llvm::dyn_cast<NamedDecl>(*IDeclContext)) {
        DeclarationName childDeclName = parentDecl->getDeclName();
        if (auto II = childDeclName.getAsIdentifierInfo()) {
          StringRef name = II->getName();
          if (!name.empty() && name.startswith(filter))
            ImportDecl(parentDecl, childDeclName, childDeclName,
                       childDeclContext);
        }
      }
    }

    const_cast<DeclContext *>(childDeclContext)->
                                      setHasExternalVisibleStorage(false);
  }
} // end namespace cling
<commit_msg>Fix wrong asserts.<commit_after>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Elisavet Sakellari <elisavet.sakellari@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "ExternalInterpreterSource.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Utils/Diagnostics.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTImporter.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Sema.h"

using namespace clang;

namespace {
  class ClingASTImporter : public ASTImporter {
  private:
    cling::ExternalInterpreterSource &m_Source;

  public:
    ClingASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                     ASTContext &FromContext, FileManager &FromFileManager,
                     bool MinimalImport,
                     cling::ExternalInterpreterSource& source):
      ASTImporter(ToContext, ToFileManager, FromContext, FromFileManager,
                  MinimalImport), m_Source(source) {}
    virtual ~ClingASTImporter() = default;

    void Imported(Decl *From, Decl *To) override {
      ASTImporter::Imported(From, To);

      if (clang::TagDecl* toTagDecl = dyn_cast<TagDecl>(To)) {
        toTagDecl->setHasExternalLexicalStorage();
        toTagDecl->setMustBuildLookupTable();
        toTagDecl->setHasExternalVisibleStorage();
      }
      if (NamespaceDecl *toNamespaceDecl = dyn_cast<NamespaceDecl>(To)) {
        toNamespaceDecl->setHasExternalVisibleStorage();
      }
      if (ObjCContainerDecl *toContainerDecl = dyn_cast<ObjCContainerDecl>(To)) {
        toContainerDecl->setHasExternalLexicalStorage();
        toContainerDecl->setHasExternalVisibleStorage();
      }
      // Put the name of the Decl imported with the
      // DeclarationName coming from the parent, in  my map.
      if (NamedDecl *toNamedDecl = llvm::dyn_cast<NamedDecl>(To)) {
        NamedDecl *fromNamedDecl = llvm::dyn_cast<NamedDecl>(From);
        m_Source.addToImportedDecls(toNamedDecl->getDeclName(),
                                    fromNamedDecl->getDeclName());
      }
      if (DeclContext *toDeclContext = llvm::dyn_cast<DeclContext>(To)) {
        DeclContext *fromDeclContext = llvm::dyn_cast<DeclContext>(From);
        m_Source.addToImportedDeclContexts(toDeclContext, fromDeclContext);
      }
    }
  };
}

namespace cling {

  ExternalInterpreterSource::ExternalInterpreterSource(
        const cling::Interpreter *parent, cling::Interpreter *child) :
        m_ParentInterpreter(parent), m_ChildInterpreter(child) {

    clang::DeclContext *parentTUDeclContext =
      m_ParentInterpreter->getCI()->getASTContext().getTranslationUnitDecl();

    clang::DeclContext *childTUDeclContext =
      m_ChildInterpreter->getCI()->getASTContext().getTranslationUnitDecl();

    // Also keep in the map of Decl Contexts the Translation Unit Decl Context
    m_ImportedDeclContexts[childTUDeclContext] = parentTUDeclContext;

    FileManager &childFM = m_ChildInterpreter->getCI()->getFileManager();
    FileManager &parentFM = m_ParentInterpreter->getCI()->getFileManager();

    ASTContext &fromASTContext = m_ParentInterpreter->getCI()->getASTContext();
    ASTContext &toASTContext = m_ChildInterpreter->getCI()->getASTContext();
    ClingASTImporter* importer
      = new ClingASTImporter(toASTContext, childFM, fromASTContext, parentFM,
                             /*MinimalImport : ON*/ true, *this);
    m_Importer.reset(llvm::dyn_cast<ASTImporter>(importer));
  }

  ExternalInterpreterSource::~ExternalInterpreterSource() {}

  void ExternalInterpreterSource::ImportDecl(Decl *declToImport,
                                   DeclarationName &childDeclName,
                                   DeclarationName &parentDeclName,
                                   const DeclContext *childCurrentDeclContext) {

    // Don't do the import if we have a Function Template or using decls. They
    // are not supported by clang.
    // FIXME: These are temporary checks and should be de-activated once clang
    // supports their import.
    if ((declToImport->isFunctionOrFunctionTemplate()
         && declToImport->isTemplateDecl()) || dyn_cast<UsingDecl>(declToImport)
         || dyn_cast<UsingShadowDecl>(declToImport)) {
#ifndef NDEBUG
      utils::DiagnosticsStore DS(
        m_Importer->getFromContext().getDiagnostics(), false, false, true);

      const Decl* To = llvm::cantFail(m_Importer->Import(declToImport));
      assert(To && "Import did not work!");
      assert((DS.empty() ||
              DS[0].getID() == clang::diag::err_unsupported_ast_node) &&
             "Import not supported!");
#endif
      return;
    }

    if (auto toOrErr = m_Importer->Import(declToImport)) {
      if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(*toOrErr)) {
        SetExternalVisibleDeclsForName(childCurrentDeclContext,
                                       importedNamedDecl->getDeclName(),
                                       importedNamedDecl);
      }
      // Put the name of the Decl imported with the
      // DeclarationName coming from the parent, in  my map.
      m_ImportedDecls[childDeclName] = parentDeclName;
    } else {
      logAllUnhandledErrors(toOrErr.takeError(), llvm::errs(),
                            "Error importing decl");
    }
  }

  void ExternalInterpreterSource::ImportDeclContext(
                                  DeclContext *declContextToImport,
                                  DeclarationName &childDeclName,
                                  DeclarationName &parentDeclName,
                                  const DeclContext *childCurrentDeclContext) {

    if (auto toOrErr = m_Importer->ImportContext(declContextToImport)) {

      DeclContext *importedDC = *toOrErr;
      importedDC->setHasExternalVisibleStorage(true);
      if (NamedDecl *importedND = llvm::dyn_cast<NamedDecl>(importedDC)) {
        SetExternalVisibleDeclsForName(childCurrentDeclContext,
                                       importedND->getDeclName(),
                                       importedND);
      }

      // Put the name of the DeclContext imported with the
      // DeclarationName coming from the parent, in  my map.
      m_ImportedDecls[childDeclName] = parentDeclName;

      // And also put the declaration context I found from the parent Interpreter
      // in the map of the child Interpreter to have it for the future.
      m_ImportedDeclContexts[importedDC] = declContextToImport;
    } else {
      logAllUnhandledErrors(toOrErr.takeError(), llvm::errs(),
                            "Error importing decl context");
    }
  }

  bool ExternalInterpreterSource::Import(DeclContext::lookup_result lookup_result,
                                const DeclContext *childCurrentDeclContext,
                                DeclarationName &childDeclName,
                                DeclarationName &parentDeclName) {

    for (DeclContext::lookup_iterator I = lookup_result.begin(),
          E = lookup_result.end(); I != E; ++I) {
      // Check if this Name we are looking for is
      // a DeclContext (for example a Namespace, function etc.).
      if (DeclContext *declContextToImport = llvm::dyn_cast<DeclContext>(*I)) {

        ImportDeclContext(declContextToImport, childDeclName,
                          parentDeclName, childCurrentDeclContext);

      }
      ImportDecl(*I, childDeclName, parentDeclName, childCurrentDeclContext);
    }
    return true;
  }

  ///\brief This is the one of the most important function of the class
  /// since from here initiates the lookup and import part of the missing
  /// Decl(s) (Contexts).
  ///
  bool ExternalInterpreterSource::FindExternalVisibleDeclsByName(
    const DeclContext *childCurrentDeclContext, DeclarationName childDeclName) {

    assert(childDeclName && "Child Decl name is empty");

    assert(childCurrentDeclContext->hasExternalVisibleStorage() &&
           "DeclContext has no visible decls in storage");

    //Check if we have already found this declaration Name before
    DeclarationName parentDeclName;
    std::map<clang::DeclarationName,
             clang::DeclarationName>::iterator IDecl =
                                            m_ImportedDecls.find(childDeclName);
    if (IDecl != m_ImportedDecls.end()) {
      parentDeclName = IDecl->second;
    } else {
      // Get the identifier info from the parent interpreter
      // for this Name.
      std::string name = childDeclName.getAsString();
      IdentifierTable &parentIdentifierTable =
                            m_ParentInterpreter->getCI()->getASTContext().Idents;
      IdentifierInfo &parentIdentifierInfo =
                            parentIdentifierTable.get(name);
      parentDeclName = DeclarationName(&parentIdentifierInfo);
    }

    // Search in the map of the stored Decl Contexts for this
    // Decl Context.
    std::map<const clang::DeclContext *, clang::DeclContext *>::iterator
          IDeclContext = m_ImportedDeclContexts.find(childCurrentDeclContext);
    // If childCurrentDeclContext was found before and is already in the map,
    // then do the lookup using the stored pointer.
    if (IDeclContext == m_ImportedDeclContexts.end()) return false;

    DeclContext *parentDeclContext = IDeclContext->second;

    DeclContext::lookup_result lookup_result =
                                    parentDeclContext->lookup(parentDeclName);

    // Check if we found this Name in the parent interpreter
    if (!lookup_result.empty()) {
      if (Import(lookup_result,
                 childCurrentDeclContext, childDeclName, parentDeclName))
        return true;
    }

    return false;
  }

  ///\brief Make available to child all decls in parent's decl context
  /// that corresponds to child decl context.
  void ExternalInterpreterSource::completeVisibleDeclsMap(
                                const clang::DeclContext *childDeclContext) {
    assert (childDeclContext && "No child decl context!");

    if (!childDeclContext->hasExternalVisibleStorage())
      return;

    // Search in the map of the stored Decl Contexts for this
    // Decl Context.
    std::map<const clang::DeclContext *, clang::DeclContext *>::iterator
                  IDeclContext = m_ImportedDeclContexts.find(childDeclContext);
    // If childCurrentDeclContext was found before and is already in the map,
    // then do the lookup using the stored pointer.
    if (IDeclContext == m_ImportedDeclContexts.end()) return ;

    DeclContext *parentDeclContext = IDeclContext->second;

    // Filter the decls from the external source using the stem information
    // stored in Sema.
    StringRef filter =
      m_ChildInterpreter->getCI()->getPreprocessor().getCodeCompletionFilter();
    for (DeclContext::decl_iterator IDeclContext =
                                      parentDeclContext->decls_begin(),
                                    EDeclContext =
                                      parentDeclContext->decls_end();
                              IDeclContext != EDeclContext; ++IDeclContext) {
      if (NamedDecl* parentDecl = llvm::dyn_cast<NamedDecl>(*IDeclContext)) {
        DeclarationName childDeclName = parentDecl->getDeclName();
        if (auto II = childDeclName.getAsIdentifierInfo()) {
          StringRef name = II->getName();
          if (!name.empty() && name.startswith(filter))
            ImportDecl(parentDecl, childDeclName, childDeclName,
                       childDeclContext);
        }
      }
    }

    const_cast<DeclContext *>(childDeclContext)->
                                      setHasExternalVisibleStorage(false);
  }
} // end namespace cling
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkWin32OutputWindow.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkWin32OutputWindow.h"

#include "vtkObjectFactory.h"
#include "vtkWindows.h"

vtkStandardNewMacro(vtkWin32OutputWindow);

HWND vtkWin32OutputWindowOutputWindow = 0;

//----------------------------------------------------------------------------
LRESULT APIENTRY vtkWin32OutputWindowWndProc(HWND hWnd, UINT message,
                                             WPARAM wParam,
                                             LPARAM lParam)
{
  switch (message)
    {
    case WM_SIZE:
      {
      int w = LOWORD(lParam);  // width of client area
      int h = HIWORD(lParam); // height of client area

      MoveWindow(vtkWin32OutputWindowOutputWindow,
                 0, 0, w, h, true);
      }
      break;
    case WM_DESTROY:
      vtkWin32OutputWindowOutputWindow = NULL;
      vtkObject::GlobalWarningDisplayOff();
      break;
    case WM_CREATE:
      break;
    }
  return DefWindowProc(hWnd, message, wParam, lParam);
}

//----------------------------------------------------------------------------
vtkWin32OutputWindow::vtkWin32OutputWindow()
{
  // Default to sending output to stderr/cerr when running a dashboard:
  //
  if(getenv("DART_TEST_FROM_DART") ||
    getenv("DASHBOARD_TEST_FROM_CTEST"))
    {
    this->SendToStdErr = true;
    }
  else
    {
    this->SendToStdErr = false;
    }
}

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

//----------------------------------------------------------------------------
// Display text in the window, and translate the \n to \r\n.
//
void vtkWin32OutputWindow::DisplayText(const char* someText)
{
  if(!someText)
    {
    return;
    }
  if(this->PromptUser)
    {
    this->PromptText(someText);
    return;
    }

  // Create a buffer big enough to hold the entire text
  char* buffer = new char[strlen(someText)+1];
  // Start at the beginning
  const char* NewLinePos = someText;
  while(NewLinePos)
    {
    int len = 0;
    // Find the next new line in text
    NewLinePos = strchr(someText, '\n');
    // if no new line is found then just add the text
    if(NewLinePos == 0)
      {
      vtkWin32OutputWindow::AddText(someText);
      OutputDebugString(someText);

      if (this->SendToStdErr)
        {
        cerr << someText;
        }
      }
    // if a new line is found copy it to the buffer
    // and add the buffer with a control new line
    else
      {
      len = NewLinePos - someText;
      strncpy(buffer, someText, len);
      buffer[len] = 0;
      someText = NewLinePos+1;
      vtkWin32OutputWindow::AddText(buffer);
      vtkWin32OutputWindow::AddText("\r\n");
      OutputDebugString(buffer);
      OutputDebugString("\r\n");

      if (this->SendToStdErr)
        {
        cerr << buffer;
        cerr << "\r\n";
        }
      }
    }
  delete [] buffer;
}

//----------------------------------------------------------------------------
// Add some text to the EDIT control.
//
void vtkWin32OutputWindow::AddText(const char* someText)
{
  if(!Initialize()  || (strlen(someText) == 0))
    {
    return;
    }

#ifdef UNICODE
  // move to the end of the text area
  SendMessageW( vtkWin32OutputWindowOutputWindow, EM_SETSEL,
               (WPARAM)-1, (LPARAM)-1 );
  wchar_t *wmsg = new wchar_t [mbstowcs(NULL, someText, 32000)+1];
  mbstowcs(wmsg, someText, 32000);
  // Append the text to the control
  SendMessageW( vtkWin32OutputWindowOutputWindow, EM_REPLACESEL,
                0, (LPARAM)wmsg );
  delete [] wmsg;
#else
  // move to the end of the text area
  SendMessageA( vtkWin32OutputWindowOutputWindow, EM_SETSEL,
               (WPARAM)-1, (LPARAM)-1 );
  // Append the text to the control
  SendMessageA( vtkWin32OutputWindowOutputWindow, EM_REPLACESEL,
                0, (LPARAM)someText );
#endif
}

//----------------------------------------------------------------------------
// initialize the output window with an EDIT control and
// a container window.
//
int vtkWin32OutputWindow::Initialize()
{
  // check to see if it is already initialized
  if(vtkWin32OutputWindowOutputWindow)
    {
    return 1;
    }

  // Initialize the output window

  WNDCLASS wndClass;
  // has the class been registered ?
#ifdef UNICODE
  if (!GetClassInfo(GetModuleHandle(NULL),L"vtkOutputWindow",&wndClass))
#else
  if (!GetClassInfo(GetModuleHandle(NULL),"vtkOutputWindow",&wndClass))
#endif
  {
    wndClass.style = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = vtkWin32OutputWindowWndProc;
    wndClass.cbClsExtra = 0;
    wndClass.hInstance = GetModuleHandle(NULL);
#ifndef _WIN32_WCE
    wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
#endif
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wndClass.lpszMenuName = NULL;
#ifdef UNICODE
    wndClass.lpszClassName = L"vtkOutputWindow";
#else
    wndClass.lpszClassName = "vtkOutputWindow";
#endif
    // vtk doesn't use these extra bytes, but app writers
    // may want them, so we provide them -- big enough for
    // one run time pointer: 4 bytes on 32-bit builds, 8 bytes
    // on 64-bit builds
    wndClass.cbWndExtra = sizeof(vtkLONG);
    RegisterClass(&wndClass);
    }

  // create parent container window
#ifdef _WIN32_WCE
  HWND win = CreateWindow(
    L"vtkOutputWindow", L"vtkOutputWindow",
    WS_OVERLAPPED | WS_CLIPCHILDREN,
    0, 0, 512, 512,
    NULL, NULL, GetModuleHandle(NULL), NULL);
#elif UNICODE
  HWND win = CreateWindow(
    L"vtkOutputWindow", L"vtkOutputWindow",
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
    0, 0, 512, 512,
    NULL, NULL, GetModuleHandle(NULL), NULL);
#else
  HWND win = CreateWindow(
    "vtkOutputWindow", "vtkOutputWindow",
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
    0, 0, 512, 512,
    NULL, NULL, GetModuleHandle(NULL), NULL);
#endif

  // Now create child window with text display box
  CREATESTRUCT lpParam;
  lpParam.hInstance = GetModuleHandle(NULL);
  lpParam.hMenu = NULL;
  lpParam.hwndParent = win;
  lpParam.cx = 512;
  lpParam.cy = 512;
  lpParam.x = 0;
  lpParam.y = 0;
#if defined(_WIN32_WCE) || defined(UNICODE)
  lpParam.lpszName = L"Output Control";
  lpParam.lpszClass = L"EDIT"; // use the RICHEDIT control widget
#else
  lpParam.lpszName = "Output Control";
  lpParam.lpszClass = "EDIT"; // use the RICHEDIT control widget
#endif

#ifdef _WIN32_WCE
  lpParam.style = ES_MULTILINE | ES_READONLY | WS_CHILD
    | ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_VISIBLE
    | WS_VSCROLL | WS_HSCROLL;
#else
  lpParam.style = ES_MULTILINE | ES_READONLY | WS_CHILD
    | ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_VISIBLE | WS_MAXIMIZE
    | WS_VSCROLL | WS_HSCROLL;
#endif

  lpParam.dwExStyle = 0;
  // Create the EDIT window as a child of win
#if defined(_WIN32_WCE) || defined(UNICODE)
  vtkWin32OutputWindowOutputWindow = CreateWindow(
    lpParam.lpszClass,  // pointer to registered class name
    L"", // pointer to window name
    lpParam.style,        // window style
    lpParam.x,                // horizontal position of window
    lpParam.y,                // vertical position of window
    lpParam.cx,           // window width
    lpParam.cy,          // window height
    lpParam.hwndParent,      // handle to parent or owner window
    NULL,          // handle to menu or child-window identifier
    lpParam.hInstance,     // handle to application instance
    &lpParam        // pointer to window-creation data
    );
#else
  vtkWin32OutputWindowOutputWindow = CreateWindow(
    lpParam.lpszClass,  // pointer to registered class name
    "", // pointer to window name
    lpParam.style,        // window style
    lpParam.x,                // horizontal position of window
    lpParam.y,                // vertical position of window
    lpParam.cx,           // window width
    lpParam.cy,          // window height
    lpParam.hwndParent,      // handle to parent or owner window
    NULL,          // handle to menu or child-window identifier
    lpParam.hInstance,     // handle to application instance
    &lpParam        // pointer to window-creation data
    );
#endif

  const int maxsize = 5242880;

#ifdef UNICODE
  SendMessageW(vtkWin32OutputWindowOutputWindow,
               EM_LIMITTEXT, maxsize, 0L);
#else
  SendMessageA(vtkWin32OutputWindowOutputWindow,
               EM_LIMITTEXT, maxsize, 0L);
#endif

  // show the top level container window
  ShowWindow(win, SW_SHOW);
  return 1;
}

//----------------------------------------------------------------------------
void vtkWin32OutputWindow::PromptText(const char* someText)
{
  char *vtkmsg = new char [strlen(someText) + 100];
  sprintf(vtkmsg,"%s\nPress Cancel to suppress any further messages.",
          someText);
#ifdef UNICODE
  wchar_t *wmsg = new wchar_t [mbstowcs(NULL, vtkmsg, 32000)+1];
  mbstowcs(wmsg, vtkmsg, 32000);
  if (MessageBox(NULL, wmsg, L"Error",
                 MB_ICONERROR | MB_OKCANCEL) == IDCANCEL)
    {
    vtkObject::GlobalWarningDisplayOff();
    }
  delete [] wmsg;
#else
  if (MessageBox(NULL, vtkmsg, "Error",
                 MB_ICONERROR | MB_OKCANCEL) == IDCANCEL)
    {
    vtkObject::GlobalWarningDisplayOff();
    }
#endif
  delete [] vtkmsg;
}

//----------------------------------------------------------------------------
void vtkWin32OutputWindow::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  if (vtkWin32OutputWindowOutputWindow)
    {
    os << indent << "OutputWindow: "
       << vtkWin32OutputWindowOutputWindow << "\n";
    }
  else
    {
    os << indent << "OutputWindow: (null)\n";
    }

  os << indent << "SendToStdErr: " << this->SendToStdErr << "\n";
}
<commit_msg>make wider so we can see errors<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkWin32OutputWindow.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkWin32OutputWindow.h"

#include "vtkObjectFactory.h"
#include "vtkWindows.h"

vtkStandardNewMacro(vtkWin32OutputWindow);

HWND vtkWin32OutputWindowOutputWindow = 0;

//----------------------------------------------------------------------------
LRESULT APIENTRY vtkWin32OutputWindowWndProc(HWND hWnd, UINT message,
                                             WPARAM wParam,
                                             LPARAM lParam)
{
  switch (message)
    {
    case WM_SIZE:
      {
      int w = LOWORD(lParam);  // width of client area
      int h = HIWORD(lParam); // height of client area

      MoveWindow(vtkWin32OutputWindowOutputWindow,
                 0, 0, w, h, true);
      }
      break;
    case WM_DESTROY:
      vtkWin32OutputWindowOutputWindow = NULL;
      vtkObject::GlobalWarningDisplayOff();
      break;
    case WM_CREATE:
      break;
    }
  return DefWindowProc(hWnd, message, wParam, lParam);
}

//----------------------------------------------------------------------------
vtkWin32OutputWindow::vtkWin32OutputWindow()
{
  // Default to sending output to stderr/cerr when running a dashboard:
  //
  if(getenv("DART_TEST_FROM_DART") ||
    getenv("DASHBOARD_TEST_FROM_CTEST"))
    {
    this->SendToStdErr = true;
    }
  else
    {
    this->SendToStdErr = false;
    }
}

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

//----------------------------------------------------------------------------
// Display text in the window, and translate the \n to \r\n.
//
void vtkWin32OutputWindow::DisplayText(const char* someText)
{
  if(!someText)
    {
    return;
    }
  if(this->PromptUser)
    {
    this->PromptText(someText);
    return;
    }

  // Create a buffer big enough to hold the entire text
  char* buffer = new char[strlen(someText)+1];
  // Start at the beginning
  const char* NewLinePos = someText;
  while(NewLinePos)
    {
    int len = 0;
    // Find the next new line in text
    NewLinePos = strchr(someText, '\n');
    // if no new line is found then just add the text
    if(NewLinePos == 0)
      {
      vtkWin32OutputWindow::AddText(someText);
      OutputDebugString(someText);

      if (this->SendToStdErr)
        {
        cerr << someText;
        }
      }
    // if a new line is found copy it to the buffer
    // and add the buffer with a control new line
    else
      {
      len = NewLinePos - someText;
      strncpy(buffer, someText, len);
      buffer[len] = 0;
      someText = NewLinePos+1;
      vtkWin32OutputWindow::AddText(buffer);
      vtkWin32OutputWindow::AddText("\r\n");
      OutputDebugString(buffer);
      OutputDebugString("\r\n");

      if (this->SendToStdErr)
        {
        cerr << buffer;
        cerr << "\r\n";
        }
      }
    }
  delete [] buffer;
}

//----------------------------------------------------------------------------
// Add some text to the EDIT control.
//
void vtkWin32OutputWindow::AddText(const char* someText)
{
  if(!Initialize()  || (strlen(someText) == 0))
    {
    return;
    }

#ifdef UNICODE
  // move to the end of the text area
  SendMessageW( vtkWin32OutputWindowOutputWindow, EM_SETSEL,
               (WPARAM)-1, (LPARAM)-1 );
  wchar_t *wmsg = new wchar_t [mbstowcs(NULL, someText, 32000)+1];
  mbstowcs(wmsg, someText, 32000);
  // Append the text to the control
  SendMessageW( vtkWin32OutputWindowOutputWindow, EM_REPLACESEL,
                0, (LPARAM)wmsg );
  delete [] wmsg;
#else
  // move to the end of the text area
  SendMessageA( vtkWin32OutputWindowOutputWindow, EM_SETSEL,
               (WPARAM)-1, (LPARAM)-1 );
  // Append the text to the control
  SendMessageA( vtkWin32OutputWindowOutputWindow, EM_REPLACESEL,
                0, (LPARAM)someText );
#endif
}

//----------------------------------------------------------------------------
// initialize the output window with an EDIT control and
// a container window.
//
int vtkWin32OutputWindow::Initialize()
{
  // check to see if it is already initialized
  if(vtkWin32OutputWindowOutputWindow)
    {
    return 1;
    }

  // Initialize the output window

  WNDCLASS wndClass;
  // has the class been registered ?
#ifdef UNICODE
  if (!GetClassInfo(GetModuleHandle(NULL),L"vtkOutputWindow",&wndClass))
#else
  if (!GetClassInfo(GetModuleHandle(NULL),"vtkOutputWindow",&wndClass))
#endif
  {
    wndClass.style = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = vtkWin32OutputWindowWndProc;
    wndClass.cbClsExtra = 0;
    wndClass.hInstance = GetModuleHandle(NULL);
#ifndef _WIN32_WCE
    wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
#endif
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wndClass.lpszMenuName = NULL;
#ifdef UNICODE
    wndClass.lpszClassName = L"vtkOutputWindow";
#else
    wndClass.lpszClassName = "vtkOutputWindow";
#endif
    // vtk doesn't use these extra bytes, but app writers
    // may want them, so we provide them -- big enough for
    // one run time pointer: 4 bytes on 32-bit builds, 8 bytes
    // on 64-bit builds
    wndClass.cbWndExtra = sizeof(vtkLONG);
    RegisterClass(&wndClass);
    }

  // create parent container window
#ifdef _WIN32_WCE
  HWND win = CreateWindow(
    L"vtkOutputWindow", L"vtkOutputWindow",
    WS_OVERLAPPED | WS_CLIPCHILDREN,
    0, 0, 800, 512,
    NULL, NULL, GetModuleHandle(NULL), NULL);
#elif UNICODE
  HWND win = CreateWindow(
    L"vtkOutputWindow", L"vtkOutputWindow",
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
    0, 0, 800, 512,
    NULL, NULL, GetModuleHandle(NULL), NULL);
#else
  HWND win = CreateWindow(
    "vtkOutputWindow", "vtkOutputWindow",
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
    0, 0, 800, 512,
    NULL, NULL, GetModuleHandle(NULL), NULL);
#endif

  // Now create child window with text display box
  CREATESTRUCT lpParam;
  lpParam.hInstance = GetModuleHandle(NULL);
  lpParam.hMenu = NULL;
  lpParam.hwndParent = win;
  lpParam.cx = 800;
  lpParam.cy = 512;
  lpParam.x = 0;
  lpParam.y = 0;
#if defined(_WIN32_WCE) || defined(UNICODE)
  lpParam.lpszName = L"Output Control";
  lpParam.lpszClass = L"EDIT"; // use the RICHEDIT control widget
#else
  lpParam.lpszName = "Output Control";
  lpParam.lpszClass = "EDIT"; // use the RICHEDIT control widget
#endif

#ifdef _WIN32_WCE
  lpParam.style = ES_MULTILINE | ES_READONLY | WS_CHILD
    | ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_VISIBLE
    | WS_VSCROLL | WS_HSCROLL;
#else
  lpParam.style = ES_MULTILINE | ES_READONLY | WS_CHILD
    | ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_VISIBLE | WS_MAXIMIZE
    | WS_VSCROLL | WS_HSCROLL;
#endif

  lpParam.dwExStyle = 0;
  // Create the EDIT window as a child of win
#if defined(_WIN32_WCE) || defined(UNICODE)
  vtkWin32OutputWindowOutputWindow = CreateWindow(
    lpParam.lpszClass,  // pointer to registered class name
    L"", // pointer to window name
    lpParam.style,        // window style
    lpParam.x,                // horizontal position of window
    lpParam.y,                // vertical position of window
    lpParam.cx,           // window width
    lpParam.cy,          // window height
    lpParam.hwndParent,      // handle to parent or owner window
    NULL,          // handle to menu or child-window identifier
    lpParam.hInstance,     // handle to application instance
    &lpParam        // pointer to window-creation data
    );
#else
  vtkWin32OutputWindowOutputWindow = CreateWindow(
    lpParam.lpszClass,  // pointer to registered class name
    "", // pointer to window name
    lpParam.style,        // window style
    lpParam.x,                // horizontal position of window
    lpParam.y,                // vertical position of window
    lpParam.cx,           // window width
    lpParam.cy,          // window height
    lpParam.hwndParent,      // handle to parent or owner window
    NULL,          // handle to menu or child-window identifier
    lpParam.hInstance,     // handle to application instance
    &lpParam        // pointer to window-creation data
    );
#endif

  const int maxsize = 5242880;

#ifdef UNICODE
  SendMessageW(vtkWin32OutputWindowOutputWindow,
               EM_LIMITTEXT, maxsize, 0L);
#else
  SendMessageA(vtkWin32OutputWindowOutputWindow,
               EM_LIMITTEXT, maxsize, 0L);
#endif

  // show the top level container window
  ShowWindow(win, SW_SHOW);
  return 1;
}

//----------------------------------------------------------------------------
void vtkWin32OutputWindow::PromptText(const char* someText)
{
  char *vtkmsg = new char [strlen(someText) + 100];
  sprintf(vtkmsg,"%s\nPress Cancel to suppress any further messages.",
          someText);
#ifdef UNICODE
  wchar_t *wmsg = new wchar_t [mbstowcs(NULL, vtkmsg, 32000)+1];
  mbstowcs(wmsg, vtkmsg, 32000);
  if (MessageBox(NULL, wmsg, L"Error",
                 MB_ICONERROR | MB_OKCANCEL) == IDCANCEL)
    {
    vtkObject::GlobalWarningDisplayOff();
    }
  delete [] wmsg;
#else
  if (MessageBox(NULL, vtkmsg, "Error",
                 MB_ICONERROR | MB_OKCANCEL) == IDCANCEL)
    {
    vtkObject::GlobalWarningDisplayOff();
    }
#endif
  delete [] vtkmsg;
}

//----------------------------------------------------------------------------
void vtkWin32OutputWindow::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  if (vtkWin32OutputWindowOutputWindow)
    {
    os << indent << "OutputWindow: "
       << vtkWin32OutputWindowOutputWindow << "\n";
    }
  else
    {
    os << indent << "OutputWindow: (null)\n";
    }

  os << indent << "SendToStdErr: " << this->SendToStdErr << "\n";
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
<commit_msg>Add L1 procedures for p9a and makefiles<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config_thermal.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9a_mss_eff_config_thermal.H
/// @brief Perform thermal calculations as part of the effective configuration
///
// *HWP HWP Owner: Andre A. Marin  <aamarin@us.ibm.com>
// *HWP HWP Backup: Michael Pardeik <pardeik@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#ifndef P9A_MSS_EFF_CONFIG_THERMAL_H_
#define P9A_MSS_EFF_CONFIG_THERMAL_H_

#include <fapi2.H>
#include <vector>

typedef fapi2::ReturnCode (*p9a_mss_eff_config_thermal_FP_t) (const std::vector
        <fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>>&);

extern "C"
{

    ///
    /// @brief Perform thermal calculations as part of the effective configuration
    /// @param[in] i_targets vector of ports (e.g., MEM_PORT) all on the same VDDR domain
    /// @return FAPI2_RC_SUCCESS iff ok
    /// @note sets ATTR_MSS_MEM_WATT_TARGET, ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT and _PER_SLOT, and ATTR_MSS_PORT_MAXPOWER
    ///
    fapi2::ReturnCode p9a_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> >&
            i_targets );

}

#endif
<|endoftext|>


<commit_before>
#include "typedatabase.h"
#include "../customtypes.h"

#include <QDebug>

#include <qfile.h>
#include <qxml.h>
#include "handler.h"
#include "../reporthandler.h"

static void addRemoveFunctionToTemplates(TypeDatabase *db);

TypeDatabase::TypeDatabase() : m_suppressWarnings(true), m_includeEclipseWarnings(false) {
    addType(new StringTypeEntry("QString"));

    StringTypeEntry *e = new StringTypeEntry("QLatin1String");
    e->setPreferredConversion(false);
    addType(e);

    // We need the generator to perform type conversion in C++ with the
    //  construct:
    // QString qstring = QString("string"); QStringRef(&qstring)"
    //  not with:
    // (const QStringRef &)QString("string")
    StringRefTypeEntry *sr = new StringRefTypeEntry("QStringRef");
    addType(sr);
    // TODO: Use of StringRefTypeEntry for QXmlStreamStringRef has not been tested,
    //  I am sure the previous code would cause a crash.
    sr = new StringRefTypeEntry("QXmlStreamStringRef");
    sr->setPreferredConversion(false);
    addType(sr);

    addType(new CharTypeEntry("QChar"));

    CharTypeEntry *c = new CharTypeEntry("QLatin1Char");
    c->setPreferredConversion(false);
    addType(c);

    {
        VariantTypeEntry *qvariant = new VariantTypeEntry("QVariant");
        qvariant->setCodeGeneration(TypeEntry::GenerateNothing);
        addType(qvariant);
    }

    {
        JObjectWrapperTypeEntry *wrapper = new JObjectWrapperTypeEntry("JObjectWrapper");
        wrapper->setCodeGeneration(TypeEntry::GenerateNothing);
        addType(wrapper);
    }

    addType(new ThreadTypeEntry());
    addType(new VoidTypeEntry());

    // Predefined containers...
    addType(new ContainerTypeEntry("QList", ContainerTypeEntry::ListContainer));
    addType(new ContainerTypeEntry("QStringList", ContainerTypeEntry::StringListContainer));
    addType(new ContainerTypeEntry("QLinkedList", ContainerTypeEntry::LinkedListContainer));
    addType(new ContainerTypeEntry("QVector", ContainerTypeEntry::VectorContainer));
    addType(new ContainerTypeEntry("QStack", ContainerTypeEntry::StackContainer));
    addType(new ContainerTypeEntry("QSet", ContainerTypeEntry::SetContainer));
    addType(new ContainerTypeEntry("QMap", ContainerTypeEntry::MapContainer));
    addType(new ContainerTypeEntry("QHash", ContainerTypeEntry::HashContainer));
    addType(new ContainerTypeEntry("QPair", ContainerTypeEntry::PairContainer));
    addType(new ContainerTypeEntry("QQueue", ContainerTypeEntry::QueueContainer));
    addType(new ContainerTypeEntry("QMultiMap", ContainerTypeEntry::MultiMapContainer));

    // Custom types...
    addType(new QModelIndexTypeEntry());

    addRemoveFunctionToTemplates(this);
}

TypeDatabase *TypeDatabase::instance() {
    static TypeDatabase *db = new TypeDatabase();
    return db;
}

TypeEntry *TypeDatabase::findType(const QString &name) const {
    QList<TypeEntry *> entries = findTypes(name);
    foreach(TypeEntry *entry, entries) {
        //qDebug()<<"findType()"<<entry;
        if (entry != 0 &&
                (!entry->isPrimitive() ||
                 static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())) {
            return entry;
        }
    }
    return 0;
}

SingleTypeEntryHash TypeDatabase::entries() {
    TypeEntryHash entries = allEntries();

    SingleTypeEntryHash returned;
    QList<QString> keys = entries.keys();

    foreach(QString key, keys) {
        returned[key] = findType(key);
    }

    return returned;
}

bool TypeDatabase::isSuppressedWarning(const QString &s) {
    if (!m_suppressWarnings)
        return false;

    foreach(const QString &_warning, m_suppressedWarnings) {
        QString warning(QString(_warning).replace("\\*", "&place_holder_for_asterisk;"));

        QStringList segs = warning.split("*", QString::SkipEmptyParts);
        if (segs.size() == 0)
            continue ;

        int i = 0;
        int pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*"));
        //qDebug() << "s == " << s << ", warning == " << segs;
        while (pos != -1) {
            if (i == segs.size())
                return true;
            pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*"), pos);
        }
    }

    return false;
}

PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString &name) {
    QList<TypeEntry *> entries = findTypes(name);

    foreach(TypeEntry *entry, entries) {
        if (entry != 0 && entry->isPrimitive() && static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())
            return static_cast<PrimitiveTypeEntry *>(entry);
    }

    return 0;
}

ComplexTypeEntry *TypeDatabase::findComplexType(const QString &name) {
    TypeEntry *entry = findType(name);
    if (entry != 0 && entry->isComplex())
        return static_cast<ComplexTypeEntry *>(entry);
    else
        return 0;
}

ObjectTypeEntry *TypeDatabase::findObjectType(const QString &name) {
    TypeEntry *entry = findType(name);
    if (entry != 0 && entry->isObject())
        return static_cast<ObjectTypeEntry *>(entry);
    else
        return 0;
}

NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString &name) {
    TypeEntry *entry = findType(name);
    if (entry != 0 && entry->isNamespace())
        return static_cast<NamespaceTypeEntry *>(entry);
    else
        return 0;
}

bool TypeDatabase::parseFile(const QString &filename, const QString &importInputDirectory, bool generate) {
    qDebug() << "Parsing file: " << filename;
    QFile file(filename);
    Q_ASSERT(file.exists());
    QXmlInputSource source(&file);

    int count = m_entries.size();

    QXmlSimpleReader reader;
    Handler handler(this, generate);
    if (!importInputDirectory.isNull())
        handler.setImportInputDirectory(importInputDirectory);

    reader.setContentHandler(&handler);
    reader.setErrorHandler(&handler);

    bool ok = reader.parse(&source, false);
    int newCount = m_entries.size();

    QString string = QString::fromLatin1("Parsed: '%1', %2 new entries")
                     .arg(filename)
                     .arg(newCount - count);
    qDebug() << string;
    //ReportHandler::debugSparse(string);

    return ok;
}

ContainerTypeEntry *TypeDatabase::findContainerType(const QString &name) {
    QString template_name = name;

    int pos = name.indexOf('<');
    if (pos > 0)
        template_name = name.left(pos);

    TypeEntry *type_entry = findType(template_name);
    if (type_entry && type_entry->isContainer())
        return static_cast<ContainerTypeEntry *>(type_entry);
    return 0;
}

PrimitiveTypeEntry *TypeDatabase::findTargetLangPrimitiveType(const QString &java_name) {
    foreach(QList<TypeEntry *> entries, m_entries.values()) {
        foreach(TypeEntry *e, entries) {
            if (e && e->isPrimitive()) {
                PrimitiveTypeEntry *pe = static_cast<PrimitiveTypeEntry *>(e);
                if (pe->targetLangName() == java_name && pe->preferredConversion())
                    return pe;
            }
        }
    }

    return 0;
}

IncludeList TypeDatabase::extraIncludes(const QString &className) {
    ComplexTypeEntry *typeEntry = findComplexType(className);
    if (typeEntry != 0)
        return typeEntry->extraIncludes();
    else
        return IncludeList();
}

void TypeDatabase::addRejection(const QString &class_name, const QString &function_name,
                                const QString &field_name, const QString &enum_name) {
    TypeRejection r;
    r.class_name = class_name;
    r.function_name = function_name;
    r.field_name = field_name;
    r.enum_name = enum_name;

    m_rejections << r;
}

bool TypeDatabase::isClassRejected(const QString &class_name) {
    if (!m_rebuild_classes.isEmpty())
        return !m_rebuild_classes.contains(class_name);

    foreach(const TypeRejection &r, m_rejections)
    if (r.class_name == class_name && r.function_name == "*" && r.field_name == "*" && r.enum_name == "*") {
        return true;
    }
    return false;
}

bool TypeDatabase::isEnumRejected(const QString &class_name, const QString &enum_name) {
    foreach(const TypeRejection &r, m_rejections) {
        if (r.enum_name == enum_name
                && (r.class_name == class_name || r.class_name == "*")) {
            return true;
        }
    }

    return false;
}

bool TypeDatabase::isFunctionRejected(const QString &class_name, const QString &function_name) {
    foreach(const TypeRejection &r, m_rejections)
    if (r.function_name == function_name &&
            (r.class_name == class_name || r.class_name == "*"))
        return true;
    return false;
}

bool TypeDatabase::isFieldRejected(const QString &class_name, const QString &field_name) {
    foreach(const TypeRejection &r, m_rejections)
    if (r.field_name == field_name &&
            (r.class_name == class_name || r.class_name == "*"))
        return true;
    return false;
}

FlagsTypeEntry *TypeDatabase::findFlagsType(const QString &name) const {
    FlagsTypeEntry *fte = (FlagsTypeEntry *) findType(name);
    return fte ? fte : (FlagsTypeEntry *) m_flags_entries.value(name);
}

QString TypeDatabase::globalNamespaceClassName(const TypeEntry * /*entry*/) {
    return QLatin1String("Global");
}

static void removeFunction(ComplexTypeEntry *e, const char *signature) {
    FunctionModification mod;
    mod.signature = QMetaObject::normalizedSignature(signature);
    mod.removal = TypeSystem::All;

    e->addFunctionModification(mod);
}

static void injectCode(ComplexTypeEntry *e,
                       const char *signature,
                       const QByteArray &code,
                       const ArgumentMap &args) {
    CodeSnip snip;
    snip.language = TypeSystem::NativeCode;
    snip.position = CodeSnip::Beginning;
    snip.addCode(QString::fromLatin1(code));
    snip.argumentMap = args;

    FunctionModification mod;
    mod.signature = QMetaObject::normalizedSignature(signature);
    mod.snips << snip;
    mod.modifiers = Modification::CodeInjection;
    e->addFunctionModification(mod);
}

static void addRemoveFunctionToTemplates(TypeDatabase *db) {
    ContainerTypeEntry *qvector = db->findContainerType(QLatin1String("QVector"));
    removeFunction(qvector, "constData() const");
    removeFunction(qvector, "data() const");
    removeFunction(qvector, "data()");
    removeFunction(qvector, "first()");
    removeFunction(qvector, "last()");
    removeFunction(qvector, "operator[](int)");
    removeFunction(qvector, "operator[](int) const");
    removeFunction(qvector, "operator=(QVector<T>)");

    ContainerTypeEntry *qlist = db->findContainerType(QLatin1String("QList"));
    removeFunction(qlist, "constData() const");
    removeFunction(qlist, "data() const");
    removeFunction(qlist, "data()");
    removeFunction(qlist, "back()");
    removeFunction(qlist, "front()");
    removeFunction(qlist, "first()");
    removeFunction(qlist, "last()");
    removeFunction(qlist, "operator[](int)");
    removeFunction(qlist, "operator[](int) const");
    removeFunction(qlist, "operator=(QList<T>)");

    ContainerTypeEntry *qqueue = db->findContainerType(QLatin1String("QQueue"));
    removeFunction(qqueue, "head() const");

    ArgumentMap args1;
    args1[1] = QLatin1String("$1");
    ArgumentMap args2 = args1;
    args2[2] = QLatin1String("$2");

    QByteArray code =
        "\nif ($1 >= __qt_this->size() || $1 < 0) {"
        "\n   __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\"),"
        "\n                       QString::fromLatin1(\"Accessing container of size %3 at %4\")"
        "\n                       .arg(__qt_this->size()).arg($1).toLatin1());"
        "\n   return;"
        "\n}";

    QByteArray code_with_return = QByteArray(code).replace("return;", "return 0;");

    QByteArray code_index_length =
        "\nif ($1 < 0 || $2 < 0 || ($1 + $2) >= __qt_this->size()) {"
        "\n   __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\"),"
        "\n                       QString::fromLatin1(\"Accessing container of size %3 from %4 to %5\")"
        "\n                       .arg(__qt_this->size()).arg($1).arg($1+$2).toLatin1());"
        "\n   return;"
        "\n}";

    QByteArray code_non_empty =
        "\nif (__qt_this->isEmpty()) {"
        "\n   __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\"),"
        "\n                       QString::fromLatin1(\"Accessing empty container...\").toLatin1());"
        "\n   return;"
        "\n}";

    QByteArray code_two_indices =
        "\nif ($1 < 0 || $2 < 0 || $1 >= __qt_this->size() || $2 >= __qt_this->size()) {"
        "\n   __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\"),"
        "\n                       QString::fromLatin1(\"Accessing container of size %3 at %4 and at %5\")"
        "\n                       .arg(__qt_this->size()).arg($1).arg($1+$2).toLatin1());"
        "\n   return;"
        "\n}";

    { // QVector safty...
        injectCode(qvector, "at(int) const", code_with_return, args1);
        injectCode(qvector, "replace(int,T)", code, args1);
        injectCode(qvector, "remove(int)", code, args1);
        injectCode(qvector, "remove(int, int)", code_index_length, args2);
        injectCode(qvector, "pop_back()", code_non_empty, ArgumentMap());
        injectCode(qvector, "pop_front()", code_non_empty, ArgumentMap());
    }

    { // QList safty...
        injectCode(qlist, "at(int) const", code_with_return, args1);
        injectCode(qlist, "replace(int, T)", code, args1);
        injectCode(qlist, "pop_back()", code_non_empty, ArgumentMap());
        injectCode(qlist, "pop_front()", code_non_empty, ArgumentMap());
        injectCode(qlist, "swap(int, int)", code_two_indices, args2);
        injectCode(qlist, "move(int, int)", code_two_indices, args2);
        injectCode(qlist, "removeAt(int)", code, args1);
        injectCode(qlist, "takeAt(int)", code_with_return, args1);
    }

}

<commit_msg>(split) remove extra addition from exception message text so that message text has correct values<commit_after>
#include "typedatabase.h"
#include "../customtypes.h"

#include <QDebug>

#include <qfile.h>
#include <qxml.h>
#include "handler.h"
#include "../reporthandler.h"

static void addRemoveFunctionToTemplates(TypeDatabase *db);

TypeDatabase::TypeDatabase() : m_suppressWarnings(true), m_includeEclipseWarnings(false) {
    addType(new StringTypeEntry("QString"));

    StringTypeEntry *e = new StringTypeEntry("QLatin1String");
    e->setPreferredConversion(false);
    addType(e);

    // We need the generator to perform type conversion in C++ with the
    //  construct:
    // QString qstring = QString("string"); QStringRef(&qstring)"
    //  not with:
    // (const QStringRef &)QString("string")
    StringRefTypeEntry *sr = new StringRefTypeEntry("QStringRef");
    addType(sr);
    // TODO: Use of StringRefTypeEntry for QXmlStreamStringRef has not been tested,
    //  I am sure the previous code would cause a crash.
    sr = new StringRefTypeEntry("QXmlStreamStringRef");
    sr->setPreferredConversion(false);
    addType(sr);

    addType(new CharTypeEntry("QChar"));

    CharTypeEntry *c = new CharTypeEntry("QLatin1Char");
    c->setPreferredConversion(false);
    addType(c);

    {
        VariantTypeEntry *qvariant = new VariantTypeEntry("QVariant");
        qvariant->setCodeGeneration(TypeEntry::GenerateNothing);
        addType(qvariant);
    }

    {
        JObjectWrapperTypeEntry *wrapper = new JObjectWrapperTypeEntry("JObjectWrapper");
        wrapper->setCodeGeneration(TypeEntry::GenerateNothing);
        addType(wrapper);
    }

    addType(new ThreadTypeEntry());
    addType(new VoidTypeEntry());

    // Predefined containers...
    addType(new ContainerTypeEntry("QList", ContainerTypeEntry::ListContainer));
    addType(new ContainerTypeEntry("QStringList", ContainerTypeEntry::StringListContainer));
    addType(new ContainerTypeEntry("QLinkedList", ContainerTypeEntry::LinkedListContainer));
    addType(new ContainerTypeEntry("QVector", ContainerTypeEntry::VectorContainer));
    addType(new ContainerTypeEntry("QStack", ContainerTypeEntry::StackContainer));
    addType(new ContainerTypeEntry("QSet", ContainerTypeEntry::SetContainer));
    addType(new ContainerTypeEntry("QMap", ContainerTypeEntry::MapContainer));
    addType(new ContainerTypeEntry("QHash", ContainerTypeEntry::HashContainer));
    addType(new ContainerTypeEntry("QPair", ContainerTypeEntry::PairContainer));
    addType(new ContainerTypeEntry("QQueue", ContainerTypeEntry::QueueContainer));
    addType(new ContainerTypeEntry("QMultiMap", ContainerTypeEntry::MultiMapContainer));

    // Custom types...
    addType(new QModelIndexTypeEntry());

    addRemoveFunctionToTemplates(this);
}

TypeDatabase *TypeDatabase::instance() {
    static TypeDatabase *db = new TypeDatabase();
    return db;
}

TypeEntry *TypeDatabase::findType(const QString &name) const {
    QList<TypeEntry *> entries = findTypes(name);
    foreach(TypeEntry *entry, entries) {
        //qDebug()<<"findType()"<<entry;
        if (entry != 0 &&
                (!entry->isPrimitive() ||
                 static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())) {
            return entry;
        }
    }
    return 0;
}

SingleTypeEntryHash TypeDatabase::entries() {
    TypeEntryHash entries = allEntries();

    SingleTypeEntryHash returned;
    QList<QString> keys = entries.keys();

    foreach(QString key, keys) {
        returned[key] = findType(key);
    }

    return returned;
}

bool TypeDatabase::isSuppressedWarning(const QString &s) {
    if (!m_suppressWarnings)
        return false;

    foreach(const QString &_warning, m_suppressedWarnings) {
        QString warning(QString(_warning).replace("\\*", "&place_holder_for_asterisk;"));

        QStringList segs = warning.split("*", QString::SkipEmptyParts);
        if (segs.size() == 0)
            continue ;

        int i = 0;
        int pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*"));
        //qDebug() << "s == " << s << ", warning == " << segs;
        while (pos != -1) {
            if (i == segs.size())
                return true;
            pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*"), pos);
        }
    }

    return false;
}

PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString &name) {
    QList<TypeEntry *> entries = findTypes(name);

    foreach(TypeEntry *entry, entries) {
        if (entry != 0 && entry->isPrimitive() && static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())
            return static_cast<PrimitiveTypeEntry *>(entry);
    }

    return 0;
}

ComplexTypeEntry *TypeDatabase::findComplexType(const QString &name) {
    TypeEntry *entry = findType(name);
    if (entry != 0 && entry->isComplex())
        return static_cast<ComplexTypeEntry *>(entry);
    else
        return 0;
}

ObjectTypeEntry *TypeDatabase::findObjectType(const QString &name) {
    TypeEntry *entry = findType(name);
    if (entry != 0 && entry->isObject())
        return static_cast<ObjectTypeEntry *>(entry);
    else
        return 0;
}

NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString &name) {
    TypeEntry *entry = findType(name);
    if (entry != 0 && entry->isNamespace())
        return static_cast<NamespaceTypeEntry *>(entry);
    else
        return 0;
}

bool TypeDatabase::parseFile(const QString &filename, const QString &importInputDirectory, bool generate) {
    qDebug() << "Parsing file: " << filename;
    QFile file(filename);
    Q_ASSERT(file.exists());
    QXmlInputSource source(&file);

    int count = m_entries.size();

    QXmlSimpleReader reader;
    Handler handler(this, generate);
    if (!importInputDirectory.isNull())
        handler.setImportInputDirectory(importInputDirectory);

    reader.setContentHandler(&handler);
    reader.setErrorHandler(&handler);

    bool ok = reader.parse(&source, false);
    int newCount = m_entries.size();

    QString string = QString::fromLatin1("Parsed: '%1', %2 new entries")
                     .arg(filename)
                     .arg(newCount - count);
    qDebug() << string;
    //ReportHandler::debugSparse(string);

    return ok;
}

ContainerTypeEntry *TypeDatabase::findContainerType(const QString &name) {
    QString template_name = name;

    int pos = name.indexOf('<');
    if (pos > 0)
        template_name = name.left(pos);

    TypeEntry *type_entry = findType(template_name);
    if (type_entry && type_entry->isContainer())
        return static_cast<ContainerTypeEntry *>(type_entry);
    return 0;
}

PrimitiveTypeEntry *TypeDatabase::findTargetLangPrimitiveType(const QString &java_name) {
    foreach(QList<TypeEntry *> entries, m_entries.values()) {
        foreach(TypeEntry *e, entries) {
            if (e && e->isPrimitive()) {
                PrimitiveTypeEntry *pe = static_cast<PrimitiveTypeEntry *>(e);
                if (pe->targetLangName() == java_name && pe->preferredConversion())
                    return pe;
            }
        }
    }

    return 0;
}

IncludeList TypeDatabase::extraIncludes(const QString &className) {
    ComplexTypeEntry *typeEntry = findComplexType(className);
    if (typeEntry != 0)
        return typeEntry->extraIncludes();
    else
        return IncludeList();
}

void TypeDatabase::addRejection(const QString &class_name, const QString &function_name,
                                const QString &field_name, const QString &enum_name) {
    TypeRejection r;
    r.class_name = class_name;
    r.function_name = function_name;
    r.field_name = field_name;
    r.enum_name = enum_name;

    m_rejections << r;
}

bool TypeDatabase::isClassRejected(const QString &class_name) {
    if (!m_rebuild_classes.isEmpty())
        return !m_rebuild_classes.contains(class_name);

    foreach(const TypeRejection &r, m_rejections)
    if (r.class_name == class_name && r.function_name == "*" && r.field_name == "*" && r.enum_name == "*") {
        return true;
    }
    return false;
}

bool TypeDatabase::isEnumRejected(const QString &class_name, const QString &enum_name) {
    foreach(const TypeRejection &r, m_rejections) {
        if (r.enum_name == enum_name
                && (r.class_name == class_name || r.class_name == "*")) {
            return true;
        }
    }

    return false;
}

bool TypeDatabase::isFunctionRejected(const QString &class_name, const QString &function_name) {
    foreach(const TypeRejection &r, m_rejections)
    if (r.function_name == function_name &&
            (r.class_name == class_name || r.class_name == "*"))
        return true;
    return false;
}

bool TypeDatabase::isFieldRejected(const QString &class_name, const QString &field_name) {
    foreach(const TypeRejection &r, m_rejections)
    if (r.field_name == field_name &&
            (r.class_name == class_name || r.class_name == "*"))
        return true;
    return false;
}

FlagsTypeEntry *TypeDatabase::findFlagsType(const QString &name) const {
    FlagsTypeEntry *fte = (FlagsTypeEntry *) findType(name);
    return fte ? fte : (FlagsTypeEntry *) m_flags_entries.value(name);
}

QString TypeDatabase::globalNamespaceClassName(const TypeEntry * /*entry*/) {
    return QLatin1String("Global");
}

static void removeFunction(ComplexTypeEntry *e, const char *signature) {
    FunctionModification mod;
    mod.signature = QMetaObject::normalizedSignature(signature);
    mod.removal = TypeSystem::All;

    e->addFunctionModification(mod);
}

static void injectCode(ComplexTypeEntry *e,
                       const char *signature,
                       const QByteArray &code,
                       const ArgumentMap &args) {
    CodeSnip snip;
    snip.language = TypeSystem::NativeCode;
    snip.position = CodeSnip::Beginning;
    snip.addCode(QString::fromLatin1(code));
    snip.argumentMap = args;

    FunctionModification mod;
    mod.signature = QMetaObject::normalizedSignature(signature);
    mod.snips << snip;
    mod.modifiers = Modification::CodeInjection;
    e->addFunctionModification(mod);
}

static void addRemoveFunctionToTemplates(TypeDatabase *db) {
    ContainerTypeEntry *qvector = db->findContainerType(QLatin1String("QVector"));
    removeFunction(qvector, "constData() const");
    removeFunction(qvector, "data() const");
    removeFunction(qvector, "data()");
    removeFunction(qvector, "first()");
    removeFunction(qvector, "last()");
    removeFunction(qvector, "operator[](int)");
    removeFunction(qvector, "operator[](int) const");
    removeFunction(qvector, "operator=(QVector<T>)");

    ContainerTypeEntry *qlist = db->findContainerType(QLatin1String("QList"));
    removeFunction(qlist, "constData() const");
    removeFunction(qlist, "data() const");
    removeFunction(qlist, "data()");
    removeFunction(qlist, "back()");
    removeFunction(qlist, "front()");
    removeFunction(qlist, "first()");
    removeFunction(qlist, "last()");
    removeFunction(qlist, "operator[](int)");
    removeFunction(qlist, "operator[](int) const");
    removeFunction(qlist, "operator=(QList<T>)");

    ContainerTypeEntry *qqueue = db->findContainerType(QLatin1String("QQueue"));
    removeFunction(qqueue, "head() const");

    ArgumentMap args1;
    args1[1] = QLatin1String("$1");
    ArgumentMap args2 = args1;
    args2[2] = QLatin1String("$2");

    QByteArray code =
        "\nif ($1 >= __qt_this->size() || $1 < 0) {"
        "\n   __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\"),"
        "\n                       QString::fromLatin1(\"Accessing container of size %3 at %4\")"
        "\n                       .arg(__qt_this->size()).arg($1).toLatin1());"
        "\n   return;"
        "\n}";

    QByteArray code_with_return = QByteArray(code).replace("return;", "return 0;");

    QByteArray code_index_length =
        "\nif ($1 < 0 || $2 < 0 || ($1 + $2) >= __qt_this->size()) {"
        "\n   __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\"),"
        "\n                       QString::fromLatin1(\"Accessing container of size %3 from %4 to %5\")"
        "\n                       .arg(__qt_this->size()).arg($1).arg($1+$2).toLatin1());"
        "\n   return;"
        "\n}";

    QByteArray code_non_empty =
        "\nif (__qt_this->isEmpty()) {"
        "\n   __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\"),"
        "\n                       QString::fromLatin1(\"Accessing empty container...\").toLatin1());"
        "\n   return;"
        "\n}";

    QByteArray code_two_indices =
        "\nif ($1 < 0 || $2 < 0 || $1 >= __qt_this->size() || $2 >= __qt_this->size()) {"
        "\n   __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\"),"
        "\n                       QString::fromLatin1(\"Accessing container of size %3 at %4 and at %5\")"
        "\n                       .arg(__qt_this->size()).arg($1).arg($2).toLatin1());"
        "\n   return;"
        "\n}";

    { // QVector safty...
        injectCode(qvector, "at(int) const", code_with_return, args1);
        injectCode(qvector, "replace(int,T)", code, args1);
        injectCode(qvector, "remove(int)", code, args1);
        injectCode(qvector, "remove(int, int)", code_index_length, args2);
        injectCode(qvector, "pop_back()", code_non_empty, ArgumentMap());
        injectCode(qvector, "pop_front()", code_non_empty, ArgumentMap());
    }

    { // QList safty...
        injectCode(qlist, "at(int) const", code_with_return, args1);
        injectCode(qlist, "replace(int, T)", code, args1);
        injectCode(qlist, "pop_back()", code_non_empty, ArgumentMap());
        injectCode(qlist, "pop_front()", code_non_empty, ArgumentMap());
        injectCode(qlist, "swap(int, int)", code_two_indices, args2);
        injectCode(qlist, "move(int, int)", code_two_indices, args2);
        injectCode(qlist, "removeAt(int)", code, args1);
        injectCode(qlist, "takeAt(int)", code_with_return, args1);
    }

}

<|endoftext|>


<commit_before>#include "text_element.hpp"
#include "screen.hpp"
#include "resource_cache.hpp"
#include "resource_manager.hpp"
#include "overlay_renderer.hpp"
#include "glyph.hpp"
#include "resource.hpp"

#include "../base/logging.hpp"

namespace graphics
{
  TextElement::TextElement(Params const & p)
    : OverlayElement(p),
      m_fontDesc(p.m_fontDesc),
      m_auxFontDesc(p.m_auxFontDesc),
      m_logText(p.m_logText),
      m_auxLogText(p.m_auxLogText),
      m_log2vis(p.m_log2vis)
  {
    if (m_log2vis)
    {
      m_visText = p.m_glyphCache->log2vis(m_logText);
      if (!m_auxLogText.empty())
        m_auxVisText = p.m_glyphCache->log2vis(m_auxLogText);
    }
    else
    {
      m_visText = m_logText;
      m_auxVisText = m_auxLogText;
    }
  }

  strings::UniString const & TextElement::logText() const
  {
    return m_logText;
  }

  strings::UniString const & TextElement::auxLogText() const
  {
    return m_auxLogText;
  }

  strings::UniString const & TextElement::visText() const
  {
    return m_visText;
  }

  strings::UniString const & TextElement::auxVisText() const
  {
    return m_auxVisText;
  }

  FontDesc const & TextElement::fontDesc() const
  {
    return m_fontDesc;
  }

  FontDesc const & TextElement::auxFontDesc() const
  {
    return m_auxFontDesc;
  }

  bool TextElement::isBidi() const
  {
    return m_logText != m_visText;
  }

  bool TextElement::isAuxBidi() const
  {
    return m_auxLogText != m_auxVisText;
  }

  void TextElement::drawTextImpl(GlyphLayout const & layout,
                                 OverlayRenderer * screen,
                                 math::Matrix<double, 3, 3> const & m,
                                 bool doTransformPivotOnly,
                                 bool doAlignPivot,
                                 FontDesc const & fontDesc,
                                 double depth) const
  {
    if (!fontDesc.IsValid())
      return;

    m2::PointD pv = layout.pivot();
    m2::PointD offs = layout.offset();
    double deltaA = 0;

    if (doTransformPivotOnly)
      pv *= m;
    else
    {
      double k = (sqrt((m(0, 0) * m(0, 0) + m(0, 1) * m(0, 1) + m(1, 0) * m(1, 0) + m(1, 1) * m(1, 1)) / 2));

      if ((k > 1.1) || (k < 1 / 1.1))
        return;

      deltaA = (ang::AngleD(0) * m).val();
    }

    size_t cnt = layout.entries().size();

    buffer_vector<Glyph::Info, 32> glyphInfos(cnt);
    buffer_vector<Resource::Info const *, 32> resInfos(cnt);
    buffer_vector<uint32_t, 32> glyphIDs(cnt);

    unsigned firstVis = layout.firstVisible();
    unsigned lastVis = layout.lastVisible();

    /// collecting all glyph infos in one array and packing them as a whole.
    for (unsigned i = firstVis; i < lastVis; ++i)
    {
      GlyphKey glyphKey(layout.entries()[i].m_sym,
                        fontDesc.m_size,
                        fontDesc.m_isMasked,
                        fontDesc.m_isMasked ? fontDesc.m_maskColor : fontDesc.m_color);

      glyphInfos[i] = Glyph::Info(glyphKey, screen->glyphCache());
      resInfos[i] = &glyphInfos[i];
    }

    if ((firstVis != lastVis)
    && !screen->mapInfo(&resInfos[firstVis],
                            &glyphIDs[firstVis],
                            lastVis - firstVis))
    {
      LOG(LINFO, ("cannot render string", lastVis - firstVis, "characters long"));
      return;
    }

    for (unsigned i = firstVis; i < lastVis; ++i)
    {
      GlyphLayoutElem const & elem = layout.entries()[i];
      Glyph const * glyph = static_cast<Glyph const *>(screen->fromID(glyphIDs[i]));

      m2::PointD glyphPt;
      ang::AngleD glyphAngle;

      if (doTransformPivotOnly)
      {
        m2::PointD offsPt = offs + elem.m_pt;
        m2::PointD fullPt = pv + offs + elem.m_pt;

        offsPt.x -= fullPt.x - floor(fullPt.x);
        offsPt.y -= fullPt.y - floor(fullPt.y);

        screen->drawStraightGlyph(pv, offsPt, glyph, depth);
      }
      else
      {
        glyphPt = (pv + offs + elem.m_pt) * m;
        glyphAngle = ang::AngleD(elem.m_angle.val() + deltaA);

        screen->drawGlyph(glyphPt, m2::PointD(0.0, 0.0), glyphAngle, 0, glyph, depth);
      }
    }
  }
}
<commit_msg>[graphics] remove text jittering on drag<commit_after>#include "text_element.hpp"
#include "screen.hpp"
#include "resource_cache.hpp"
#include "resource_manager.hpp"
#include "overlay_renderer.hpp"
#include "glyph.hpp"
#include "resource.hpp"

#include "../base/logging.hpp"

namespace graphics
{
  TextElement::TextElement(Params const & p)
    : OverlayElement(p),
      m_fontDesc(p.m_fontDesc),
      m_auxFontDesc(p.m_auxFontDesc),
      m_logText(p.m_logText),
      m_auxLogText(p.m_auxLogText),
      m_log2vis(p.m_log2vis)
  {
    if (m_log2vis)
    {
      m_visText = p.m_glyphCache->log2vis(m_logText);
      if (!m_auxLogText.empty())
        m_auxVisText = p.m_glyphCache->log2vis(m_auxLogText);
    }
    else
    {
      m_visText = m_logText;
      m_auxVisText = m_auxLogText;
    }
  }

  strings::UniString const & TextElement::logText() const
  {
    return m_logText;
  }

  strings::UniString const & TextElement::auxLogText() const
  {
    return m_auxLogText;
  }

  strings::UniString const & TextElement::visText() const
  {
    return m_visText;
  }

  strings::UniString const & TextElement::auxVisText() const
  {
    return m_auxVisText;
  }

  FontDesc const & TextElement::fontDesc() const
  {
    return m_fontDesc;
  }

  FontDesc const & TextElement::auxFontDesc() const
  {
    return m_auxFontDesc;
  }

  bool TextElement::isBidi() const
  {
    return m_logText != m_visText;
  }

  bool TextElement::isAuxBidi() const
  {
    return m_auxLogText != m_auxVisText;
  }

  void TextElement::drawTextImpl(GlyphLayout const & layout,
                                 OverlayRenderer * screen,
                                 math::Matrix<double, 3, 3> const & m,
                                 bool doTransformPivotOnly,
                                 bool doAlignPivot,
                                 FontDesc const & fontDesc,
                                 double depth) const
  {
    if (!fontDesc.IsValid())
      return;

    m2::PointD pv = layout.pivot();
    m2::PointD offs = layout.offset();
    double deltaA = 0;

    if (doTransformPivotOnly)
      pv *= m;
    else
    {
      double k = (sqrt((m(0, 0) * m(0, 0) + m(0, 1) * m(0, 1) + m(1, 0) * m(1, 0) + m(1, 1) * m(1, 1)) / 2));

      if ((k > 1.1) || (k < 1 / 1.1))
        return;

      deltaA = (ang::AngleD(0) * m).val();
    }

    size_t cnt = layout.entries().size();

    buffer_vector<Glyph::Info, 32> glyphInfos(cnt);
    buffer_vector<Resource::Info const *, 32> resInfos(cnt);
    buffer_vector<uint32_t, 32> glyphIDs(cnt);

    unsigned firstVis = layout.firstVisible();
    unsigned lastVis = layout.lastVisible();

    /// collecting all glyph infos in one array and packing them as a whole.
    for (unsigned i = firstVis; i < lastVis; ++i)
    {
      GlyphKey glyphKey(layout.entries()[i].m_sym,
                        fontDesc.m_size,
                        fontDesc.m_isMasked,
                        fontDesc.m_isMasked ? fontDesc.m_maskColor : fontDesc.m_color);

      glyphInfos[i] = Glyph::Info(glyphKey, screen->glyphCache());
      resInfos[i] = &glyphInfos[i];
    }

    if ((firstVis != lastVis)
    && !screen->mapInfo(&resInfos[firstVis],
                            &glyphIDs[firstVis],
                            lastVis - firstVis))
    {
      LOG(LINFO, ("cannot render string", lastVis - firstVis, "characters long"));
      return;
    }

    for (unsigned i = firstVis; i < lastVis; ++i)
    {
      GlyphLayoutElem const & elem = layout.entries()[i];
      Glyph const * glyph = static_cast<Glyph const *>(screen->fromID(glyphIDs[i]));

      m2::PointD glyphPt;
      ang::AngleD glyphAngle;

      if (doTransformPivotOnly)
      {
        m2::PointD offsPt = offs + elem.m_pt;
        screen->drawStraightGlyph(pv, offsPt, glyph, depth);
      }
      else
      {
        glyphPt = (pv + offs + elem.m_pt) * m;
        glyphAngle = ang::AngleD(elem.m_angle.val() + deltaA);

        screen->drawGlyph(glyphPt, m2::PointD(0.0, 0.0), glyphAngle, 0, glyph, depth);
      }
    }
  }
}
<|endoftext|>