<commit_before>#ifndef MODEL_HPP
#define MODEL_HPP

#include <vector>
#include <iostream>
#include <utility>
#include <cmath>

#include "../inc/quat.hpp"
#include "../inc/dual.hpp"

namespace Model {

	template<typename R = float>
	std::ostream& operator<<(std::ostream& lhs,
			quat<R> const& rhs) {
		quat<R> singlet = rhs.w;
		if(rhs == singlet) {return lhs << rhs.w;}
		return lhs << "[" << rhs.w << ", " << rhs.x
			<< ", " << rhs.y << ", " << rhs.z << "]";
	}

	template<typename R = float>
	std::ostream& operator<<(std::ostream& lhs, dual<R> const& rhs) {
		return lhs << "{" << rhs.u << ", " << rhs.v << "}";
	}

	int test(void);
}

#endif
<commit_msg>Added simple model container<commit_after>#ifndef MODEL_HPP
#define MODEL_HPP

#include <map>
#include <vector>
#include <functional>
#include <iostream>
#include <utility>
#include <cmath>

#include "../inc/quat.hpp"
#include "../inc/dual.hpp"

namespace Model {

	template<typename R = float>
	struct model {
		static unsigned int nextID;
		const unsigned int uid;
		bool operator<(model<R> const& rhs) const {
			return uid < rhs.uid;
		}
		std::map<model<R>,dual<R>> subs;
		model(void): uid(nextID++), subs{} {}
	};
	template<typename R = float>
	std::ostream& operator<<(std::ostream& lhs, model<R> const& rhs) {
		for(auto &entry : rhs.subs) {
			lhs << entry.second << ": " << entry.first << "\r\n";
		}
		return lhs;
	}

	template<typename R = float>
	std::ostream& operator<<(std::ostream& lhs,
			quat<R> const& rhs) {
		quat<R> singlet = rhs.w;
		if(rhs == singlet) {return lhs << rhs.w;}
		return lhs << "[" << rhs.w << ", " << rhs.x
			<< ", " << rhs.y << ", " << rhs.z << "]";
	}

	template<typename R = float>
	std::ostream& operator<<(std::ostream& lhs, dual<R> const& rhs) {
		return lhs << "{" << rhs.u << ", " << rhs.v << "}";
	}

	int test(void);
}

#endif
<|endoftext|>


<commit_before>//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2006 ProfitFuel Inc.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2006 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

#ifdef HAVE_SPEEX // [

// SYSTEM INCLUDES
#include <speex/speex_echo.h>
#include <speex/speex_types.h>

// APPLICATION INCLUDES
#include "os/OsDefs.h"
#include "mp/MpMisc.h"
#include "mp/MpBuf.h"
#include "mp/MpBufPool.h"
#include "mp/MpBufferMsg.h"
#include "mp/MprSpeexEchoCancel.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
MprSpeexEchoCancel::MprSpeexEchoCancel(const UtlString& rName,
                                       int samplesPerFrame, int samplesPerSec,
                                       int filterLength,
                                       int echoResiduePoolSize)
: MpAudioResource(rName, 1, 1, 1, 2, samplesPerFrame, samplesPerSec)
, mEchoResiduePool( MpArrayBuf::getHeaderSize() + sizeof(spx_int32_t)*(samplesPerFrame + 1),
                   echoResiduePoolSize)
{
   //Initilize Speex Echo state with framesize and number of frames for length of buffer
   mpEchoState = speex_echo_state_init(samplesPerFrame,
                                       samplesPerSec*filterLength/1000);

   //mpEchoResidue = (spx_int32_t*)malloc(sizeof(spx_int32_t) * (samplesPerFrame + 1));
   mStartedCanceling = false; // Debug Use only
}

// Destructor
MprSpeexEchoCancel::~MprSpeexEchoCancel()
{
   if (mpEchoState != NULL) {
      speex_echo_state_destroy(mpEchoState);
      mpEchoState = NULL;
   }
}

/* ============================ MANIPULATORS ============================== */

/* ============================ ACCESSORS ================================= */

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

UtlBoolean MprSpeexEchoCancel::doProcessFrame(MpBufPtr inBufs[],
                                              MpBufPtr outBufs[],
                                              int inBufsSize,
                                              int outBufsSize,
                                              UtlBoolean isEnabled,
                                              int samplesPerFrame,
                                              int samplesPerSecond)
{
   MpAudioBufPtr   outBuffer;
   MpAudioBufPtr   inputBuffer;
   MpAudioBufPtr   echoRefBuffer;
   MpArrayBufPtr   echoResidueBuffer;
   MpBufferMsg*    bufferMsg;
   spx_int32_t*    pEchoResidue;

   // We don't need to do anything if we don't have an output.
   if (!isOutputConnected(0) && !isOutputConnected(1))
      return FALSE;

   // If disabled pass buffer through
   if (!isEnabled) {
      outBufs[0].swap(inBufs[0]);
      return TRUE;
   }

   // Get incoming data
   inputBuffer.swap(inBufs[0]);

   // If the object is not enabled or we don't have valid input,
   // pass input to output
   if (  inputBuffer.isValid()
      && (inputBuffer->getSamplesNumber() == samplesPerFrame))
   {
      // This buffer will be modified in place. Make sure we're the only owner.
      assert(inputBuffer.requestWrite());

      // Try to get a reference frame for echo cancelation.  21 = MAX_SPKR_BUFFERS(12) +
      if (MpMisc.pEchoQ->numMsgs() > MAX_ECHO_QUEUE) {

         // Flush queue
         while ( (MpMisc.pEchoQ->receive((OsMsg*&) bufferMsg, OsTime::NO_WAIT_TIME) == OS_SUCCESS)
               && MpMisc.pEchoQ->numMsgs() > MAX_ECHO_QUEUE)
         {
            bufferMsg->releaseMsg();
         }

         // Get buffer from the message and free message
         echoRefBuffer = bufferMsg->getBuffer();
         assert(echoRefBuffer.isValid());
         bufferMsg->releaseMsg();

         if (echoRefBuffer->getSamplesNumber() == samplesPerFrame) {
            mStartedCanceling = true;

            // Get new buffer
            outBuffer = MpMisc.RawAudioPool->getBuffer();
            assert(outBuffer.isValid());
            outBuffer->setSamplesNumber(samplesPerFrame);
            outBuffer->setSpeechType(inputBuffer->getSpeechType());

            if (isOutputConnected(1)) {
               echoResidueBuffer = mEchoResiduePool.getBuffer();
               assert(outBuffer.isValid());
            }

            if (outBuffer.isValid()) {
               pEchoResidue = (spx_int32_t*)echoResidueBuffer->getDataWritePtr();
            }

            // Do echo cancelation
            speex_echo_cancel(mpEchoState,
                              (spx_int16_t*)inputBuffer->getSamplesPtr(),
                              (spx_int16_t*)echoRefBuffer->getSamplesPtr(),
                              (spx_int16_t*)outBuffer->getSamplesPtr(),
                              pEchoResidue);
         } else {
            //The sample count didn't match so we can't echo cancel.  Pass the frame.
            outBuffer = inputBuffer;
            assert(!mStartedCanceling);
         }
      } else {
         //There was no speaker data to match.  Pass the frame.
         outBuffer = inputBuffer;
//         osPrintf("SpeexEchoCancel: No frame to match...\n");
//         assert (!mStartedCanceling);
      }
   }

   outBufs[0].swap(outBuffer);
   outBufs[1].swap(echoResidueBuffer);
   return TRUE;
}

/* ============================ FUNCTIONS ================================= */

#endif // HAVE_SPEEX ]

<commit_msg>Moved inputBuffer.requestWrite() out of assert in MprSpeexEchoCancel.<commit_after>//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2006 ProfitFuel Inc.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2006 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

#ifdef HAVE_SPEEX // [

// SYSTEM INCLUDES
#include <speex/speex_echo.h>
#include <speex/speex_types.h>

// APPLICATION INCLUDES
#include "os/OsDefs.h"
#include "mp/MpMisc.h"
#include "mp/MpBuf.h"
#include "mp/MpBufPool.h"
#include "mp/MpBufferMsg.h"
#include "mp/MprSpeexEchoCancel.h"

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

// Constructor
MprSpeexEchoCancel::MprSpeexEchoCancel(const UtlString& rName,
                                       int samplesPerFrame, int samplesPerSec,
                                       int filterLength,
                                       int echoResiduePoolSize)
: MpAudioResource(rName, 1, 1, 1, 2, samplesPerFrame, samplesPerSec)
, mEchoResiduePool( MpArrayBuf::getHeaderSize() + sizeof(spx_int32_t)*(samplesPerFrame + 1),
                   echoResiduePoolSize)
{
   //Initilize Speex Echo state with framesize and number of frames for length of buffer
   mpEchoState = speex_echo_state_init(samplesPerFrame,
                                       samplesPerSec*filterLength/1000);

   //mpEchoResidue = (spx_int32_t*)malloc(sizeof(spx_int32_t) * (samplesPerFrame + 1));
   mStartedCanceling = false; // Debug Use only
}

// Destructor
MprSpeexEchoCancel::~MprSpeexEchoCancel()
{
   if (mpEchoState != NULL) {
      speex_echo_state_destroy(mpEchoState);
      mpEchoState = NULL;
   }
}

/* ============================ MANIPULATORS ============================== */

/* ============================ ACCESSORS ================================= */

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

/* //////////////////////////// PRIVATE /////////////////////////////////// */

UtlBoolean MprSpeexEchoCancel::doProcessFrame(MpBufPtr inBufs[],
                                              MpBufPtr outBufs[],
                                              int inBufsSize,
                                              int outBufsSize,
                                              UtlBoolean isEnabled,
                                              int samplesPerFrame,
                                              int samplesPerSecond)
{
   MpAudioBufPtr   outBuffer;
   MpAudioBufPtr   inputBuffer;
   MpAudioBufPtr   echoRefBuffer;
   MpArrayBufPtr   echoResidueBuffer;
   MpBufferMsg*    bufferMsg;
   spx_int32_t*    pEchoResidue;
   bool            res = false;

   // We don't need to do anything if we don't have an output.
   if (!isOutputConnected(0) && !isOutputConnected(1))
      return FALSE;

   // If disabled pass buffer through
   if (!isEnabled) {
      outBufs[0].swap(inBufs[0]);
      return TRUE;
   }

   // Get incoming data
   inputBuffer.swap(inBufs[0]);

   // If the object is not enabled or we don't have valid input,
   // pass input to output
   if (  inputBuffer.isValid()
      && (inputBuffer->getSamplesNumber() == samplesPerFrame))
   {
      // This buffer will be modified in place. Make sure we're the only owner.
      res = inputBuffer.requestWrite();
      assert(res);

      // Try to get a reference frame for echo cancelation.  21 = MAX_SPKR_BUFFERS(12) +
      if (MpMisc.pEchoQ->numMsgs() > MAX_ECHO_QUEUE) {

         // Flush queue
         while ( (MpMisc.pEchoQ->receive((OsMsg*&) bufferMsg, OsTime::NO_WAIT_TIME) == OS_SUCCESS)
               && MpMisc.pEchoQ->numMsgs() > MAX_ECHO_QUEUE)
         {
            bufferMsg->releaseMsg();
         }

         // Get buffer from the message and free message
         echoRefBuffer = bufferMsg->getBuffer();
         assert(echoRefBuffer.isValid());
         bufferMsg->releaseMsg();

         if (echoRefBuffer->getSamplesNumber() == samplesPerFrame) {
            mStartedCanceling = true;

            // Get new buffer
            outBuffer = MpMisc.RawAudioPool->getBuffer();
            assert(outBuffer.isValid());
            outBuffer->setSamplesNumber(samplesPerFrame);
            outBuffer->setSpeechType(inputBuffer->getSpeechType());

            if (isOutputConnected(1)) {
               echoResidueBuffer = mEchoResiduePool.getBuffer();
               assert(outBuffer.isValid());
            }

            if (outBuffer.isValid()) {
               pEchoResidue = (spx_int32_t*)echoResidueBuffer->getDataWritePtr();
            }

            // Do echo cancelation
            speex_echo_cancel(mpEchoState,
                              (spx_int16_t*)inputBuffer->getSamplesPtr(),
                              (spx_int16_t*)echoRefBuffer->getSamplesPtr(),
                              (spx_int16_t*)outBuffer->getSamplesPtr(),
                              pEchoResidue);
         } else {
            //The sample count didn't match so we can't echo cancel.  Pass the frame.
            outBuffer = inputBuffer;
            assert(!mStartedCanceling);
         }
      } else {
         //There was no speaker data to match.  Pass the frame.
         outBuffer = inputBuffer;
//         osPrintf("SpeexEchoCancel: No frame to match...\n");
//         assert (!mStartedCanceling);
      }
   }

   outBufs[0].swap(outBuffer);
   outBufs[1].swap(echoResidueBuffer);
   return TRUE;
}

/* ============================ FUNCTIONS ================================= */

#endif // HAVE_SPEEX ]

<|endoftext|>


<commit_before>#include "hill_climbing.h"
#include <iostream>
#include <cmath> //for fabs()
using namespace std;

namespace mo {

Hill_climbing::Hill_climbing(const double& h0, const double& eps, const double& delta)
    : h0_{h0}, eps_{eps}, delta_{delta}
{

}

void Hill_climbing::compute(){

}

double Hill_climbing::linear_search(double (*f)(const double&), double(*df)(const double&), const double& x0){
    double h = h0_;
    double x = x0;

    while(fabs(df(x)) > eps_){
        //        h =
    }

    return x;
}

} //namespace mo
<commit_msg>implement sgn() in analysis.<commit_after>#include "hill_climbing.h"
#include <iostream>
#include <cmath> //for fabs()
#include "../../analysis/src/analysis.h" //for sgn()
using namespace std;

namespace mo {

Hill_climbing::Hill_climbing(const double& h0, const double& eps, const double& delta)
    : h0_{h0}, eps_{eps}, delta_{delta}
{

}

void Hill_climbing::compute(){

}

double Hill_climbing::linear_search(double (*f)(const double&), double(*df)(const double&), const double& x0){
    double h = h0_;
    double x = x0;

    while(fabs(df(x)) > eps_){
        h *= sgn(df(x));
    }

    return x;
}

} //namespace mo
<|endoftext|>


<commit_before>// Copyright (c) 2009 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 "chrome/browser/download/download_shelf.h"

#include "app/l10n_util.h"
#include "base/file_util.h"
#include "chrome/browser/dom_ui/downloads_ui.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"

#if defined(OS_WIN)
#include "chrome/browser/download/download_util.h"
#elif defined(OS_POSIX)
#include "chrome/common/temp_scaffolding_stubs.h"
#endif

// DownloadShelf ---------------------------------------------------------------

void DownloadShelf::ShowAllDownloads() {
  Profile* profile = tab_contents_->profile();
  if (profile)
    UserMetrics::RecordAction(L"ShowDownloads", profile);
  tab_contents_->OpenURL(GURL(chrome::kChromeUIDownloadsURL), GURL(),
                         SINGLETON_TAB, PageTransition::AUTO_BOOKMARK);
}

void DownloadShelf::ChangeTabContents(TabContents* old_contents,
                                      TabContents* new_contents) {
  DCHECK(old_contents == tab_contents_);
  tab_contents_ = new_contents;
}

// DownloadShelfContextMenu ----------------------------------------------------

DownloadShelfContextMenu::DownloadShelfContextMenu(
    BaseDownloadItemModel* download_model)
    : download_(download_model->download()),
      model_(download_model) {
}

DownloadShelfContextMenu::~DownloadShelfContextMenu() {
}

bool DownloadShelfContextMenu::ItemIsChecked(int id) const {
  switch (id) {
    case OPEN_WHEN_COMPLETE:
      return download_->open_when_complete();
    case ALWAYS_OPEN_TYPE: {
      const FilePath::StringType extension =
          file_util::GetFileExtensionFromPath(download_->full_path());
      return download_->manager()->ShouldOpenFileExtension(extension);
    }
  }
  return false;
}

bool DownloadShelfContextMenu::ItemIsDefault(int id) const {
  return id == OPEN_WHEN_COMPLETE;
}

std::wstring DownloadShelfContextMenu::GetItemLabel(int id) const {
  switch (id) {
    case SHOW_IN_FOLDER:
      return l10n_util::GetString(IDS_DOWNLOAD_LINK_SHOW);
    case OPEN_WHEN_COMPLETE:
      if (download_->state() == DownloadItem::IN_PROGRESS)
        return l10n_util::GetString(IDS_DOWNLOAD_MENU_OPEN_WHEN_COMPLETE);
      return l10n_util::GetString(IDS_DOWNLOAD_MENU_OPEN);
    case ALWAYS_OPEN_TYPE:
      return l10n_util::GetString(IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE);
    case CANCEL:
      return l10n_util::GetString(IDS_DOWNLOAD_MENU_CANCEL);
    default:
      NOTREACHED();
  }
  return std::wstring();
}

bool DownloadShelfContextMenu::IsItemCommandEnabled(int id) const {
  switch (id) {
    case SHOW_IN_FOLDER:
    case OPEN_WHEN_COMPLETE:
      return download_->state() != DownloadItem::CANCELLED;
    case ALWAYS_OPEN_TYPE:
#if defined(OS_WIN)
      return download_util::CanOpenDownload(download_);
#else
      // TODO(port): port download_util
      NOTIMPLEMENTED();
      return true;
#endif
    case CANCEL:
      return download_->state() == DownloadItem::IN_PROGRESS;
    default:
      return id > 0 && id < MENU_LAST;
  }
}

void DownloadShelfContextMenu::ExecuteItemCommand(int id) {
  switch (id) {
    case SHOW_IN_FOLDER:
      download_->manager()->ShowDownloadInShell(download_);
      break;
    case OPEN_WHEN_COMPLETE:
#if defined(OS_WIN)
      download_util::OpenDownload(download_);
#else
      // TODO(port): port download_util
      NOTIMPLEMENTED();
#endif
      break;
    case ALWAYS_OPEN_TYPE: {
      const FilePath::StringType extension =
          file_util::GetFileExtensionFromPath(download_->full_path());
      download_->manager()->OpenFilesOfExtension(
          extension, !ItemIsChecked(ALWAYS_OPEN_TYPE));
      break;
    }
    case CANCEL:
      model_->CancelTask();
      break;
    default:
      NOTREACHED();
  }
}
<commit_msg>Remove one more notimpl.<commit_after>// Copyright (c) 2009 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 "chrome/browser/download/download_shelf.h"

#include "app/l10n_util.h"
#include "base/file_util.h"
#include "chrome/browser/dom_ui/downloads_ui.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"

#if defined(OS_WIN)
#include "chrome/browser/download/download_util.h"
#elif defined(OS_POSIX)
#include "chrome/common/temp_scaffolding_stubs.h"
#endif

// DownloadShelf ---------------------------------------------------------------

void DownloadShelf::ShowAllDownloads() {
  Profile* profile = tab_contents_->profile();
  if (profile)
    UserMetrics::RecordAction(L"ShowDownloads", profile);
  tab_contents_->OpenURL(GURL(chrome::kChromeUIDownloadsURL), GURL(),
                         SINGLETON_TAB, PageTransition::AUTO_BOOKMARK);
}

void DownloadShelf::ChangeTabContents(TabContents* old_contents,
                                      TabContents* new_contents) {
  DCHECK(old_contents == tab_contents_);
  tab_contents_ = new_contents;
}

// DownloadShelfContextMenu ----------------------------------------------------

DownloadShelfContextMenu::DownloadShelfContextMenu(
    BaseDownloadItemModel* download_model)
    : download_(download_model->download()),
      model_(download_model) {
}

DownloadShelfContextMenu::~DownloadShelfContextMenu() {
}

bool DownloadShelfContextMenu::ItemIsChecked(int id) const {
  switch (id) {
    case OPEN_WHEN_COMPLETE:
      return download_->open_when_complete();
    case ALWAYS_OPEN_TYPE: {
      const FilePath::StringType extension =
          file_util::GetFileExtensionFromPath(download_->full_path());
      return download_->manager()->ShouldOpenFileExtension(extension);
    }
  }
  return false;
}

bool DownloadShelfContextMenu::ItemIsDefault(int id) const {
  return id == OPEN_WHEN_COMPLETE;
}

std::wstring DownloadShelfContextMenu::GetItemLabel(int id) const {
  switch (id) {
    case SHOW_IN_FOLDER:
      return l10n_util::GetString(IDS_DOWNLOAD_LINK_SHOW);
    case OPEN_WHEN_COMPLETE:
      if (download_->state() == DownloadItem::IN_PROGRESS)
        return l10n_util::GetString(IDS_DOWNLOAD_MENU_OPEN_WHEN_COMPLETE);
      return l10n_util::GetString(IDS_DOWNLOAD_MENU_OPEN);
    case ALWAYS_OPEN_TYPE:
      return l10n_util::GetString(IDS_DOWNLOAD_MENU_ALWAYS_OPEN_TYPE);
    case CANCEL:
      return l10n_util::GetString(IDS_DOWNLOAD_MENU_CANCEL);
    default:
      NOTREACHED();
  }
  return std::wstring();
}

bool DownloadShelfContextMenu::IsItemCommandEnabled(int id) const {
  switch (id) {
    case SHOW_IN_FOLDER:
    case OPEN_WHEN_COMPLETE:
      return download_->state() != DownloadItem::CANCELLED;
    case ALWAYS_OPEN_TYPE:
#if defined(OS_WIN)
      return download_util::CanOpenDownload(download_);
#elif defined(OS_LINUX)
      // Need to implement dangerous download stuff: http://crbug.com/11780
      return false;
#endif
    case CANCEL:
      return download_->state() == DownloadItem::IN_PROGRESS;
    default:
      return id > 0 && id < MENU_LAST;
  }
}

void DownloadShelfContextMenu::ExecuteItemCommand(int id) {
  switch (id) {
    case SHOW_IN_FOLDER:
      download_->manager()->ShowDownloadInShell(download_);
      break;
    case OPEN_WHEN_COMPLETE:
#if defined(OS_WIN)
      download_util::OpenDownload(download_);
#else
      // TODO(port): port download_util
      NOTIMPLEMENTED();
#endif
      break;
    case ALWAYS_OPEN_TYPE: {
      const FilePath::StringType extension =
          file_util::GetFileExtensionFromPath(download_->full_path());
      download_->manager()->OpenFilesOfExtension(
          extension, !ItemIsChecked(ALWAYS_OPEN_TYPE));
      break;
    }
    case CANCEL:
      model_->CancelTask();
      break;
    default:
      NOTREACHED();
  }
}
<|endoftext|>


<commit_before>#include "sudokuJudger.h"
#include "sudokuGenerator.h"
#include "sudokuPrinter.h"
#include <stdlib.h>
#include <iostream>
using namespace std;

int main() {
    int input[9][9];
    int i, j;

    bool signal = false;
    SudokuGenerator sudokuGenerator;
    while (!signal) {
        signal = sudokuGenerator.Generator();
    }
    SudokuPrinter sudokuPrinter;
    sudokuPrinter.Printer(sudokuGenerator.solution);

    /*for (i = 0; i < 9; i++) {
        for (j = 0; j < 9; j++) {
            cin >> input[i][j];
        }
    }
    SudokuJudger sudokuJudger1;
    bool sudokuResult = sudokuJudger1.SudokuisSolved(input);
    if (sudokuResult) {
        cout << "Congratulations!" << endl;
    }*/
    return 0;
}<commit_msg>update main.cpp: add arguments<commit_after>#include "sudokuJudger.h"
#include "sudokuGenerator.h"
#include "sudokuPrinter.h"
#include <stdlib.h>
#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {
    if (argc < 3) {
        cout << "Error occurs when parsing arguments." << endl;
        cout << "Usage: sudoku.exe -c [N]" << endl;
        return 1;
    }

    int solutionNumber = atoi(argv[2]);

    SudokuGenerator sudokuGenerator;
    SudokuPrinter sudokuPrinter;

    bool signal = false;

    for (int i = 0; i < solutionNumber; i++) {
        signal = sudokuGenerator.Generator();
        if (signal) {
            sudokuPrinter.Printer(sudokuGenerator.solution);
        } else {
            cout << "Error occurs when applying sudokuGenerator." << endl;
            return 1;
        }
    }

    return 0;
}<|endoftext|>


<commit_before>// Copyright (c) 2011 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/base_paths.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "base/test/test_file_util.h"
#include "base/test/test_timeouts.h"
#include "base/values.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/net_util.h"
#include "net/test/test_server.h"
#include "ui/gfx/native_widget_types.h"

namespace {

class BrowserTest : public UITest {
};

class VisibleBrowserTest : public UITest {
 protected:
  VisibleBrowserTest() : UITest() {
    show_window_ = true;
  }
};

}  // namespace

// The browser should quit quickly if it receives a WM_ENDSESSION message
// on Windows, or SIGTERM on posix.
TEST_F(BrowserTest, SessionEnd) {
  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("title1.html");

  NavigateToURL(net::FilePathToFileURL(test_file));
  TerminateBrowser();
}

// WindowOpenClose is flaky on ChromeOS and fails consistently on linux views.
// See http://crbug.com/85763.
#if defined (OS_CHROMEOS)
#define MAYBE_WindowOpenClose FLAKY_WindowOpenClose
#elif defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
#define MAYBE_WindowOpenClose FAILS_WindowOpenClose
#else
#define MAYBE_WindowOpenClose WindowOpenClose
#endif

TEST_F(VisibleBrowserTest, MAYBE_WindowOpenClose) {
  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("window.close.html");

  NavigateToURLBlockUntilNavigationsComplete(
      net::FilePathToFileURL(test_file), 2);
  EXPECT_EQ(L"Title Of Awesomeness", GetActiveTabTitle());
}

class ShowModalDialogTest : public UITest {
 public:
  ShowModalDialogTest() {
    launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking);
  }
};

// Flakiness returned. Re-opened crbug.com/17806
// TODO(estade): remove flaky label if prospective fix works.
TEST_F(ShowModalDialogTest, FLAKY_BasicTest) {
  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("showmodaldialog.html");

  // This navigation should show a modal dialog that will be immediately
  // closed, but the fact that it was shown should be recorded.
  NavigateToURL(net::FilePathToFileURL(test_file));
  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(1));

  // Verify that we set a mark on successful dialog show.
  scoped_refptr<BrowserProxy> browser = automation()->GetBrowserWindow(0);
  ASSERT_TRUE(browser.get());
  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  std::wstring title;
  ASSERT_TRUE(tab->GetTabTitle(&title));
  ASSERT_EQ(L"SUCCESS", title);
}

class SecurityTest : public UITest {
};

TEST_F(SecurityTest, DisallowFileUrlUniversalAccessTest) {
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());

  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("fileurl_universalaccess.html");

  GURL url = net::FilePathToFileURL(test_file);
  ASSERT_TRUE(tab->NavigateToURL(url));

  std::string value = WaitUntilCookieNonEmpty(tab.get(), url,
        "status", TestTimeouts::action_max_timeout_ms());
  ASSERT_STREQ("Disallowed", value.c_str());
}

#if !defined(OS_MACOSX)
class KioskModeTest : public UITest {
 public:
  KioskModeTest() {
    launch_arguments_.AppendSwitch(switches::kKioskMode);
  }
};

TEST_F(KioskModeTest, EnableKioskModeTest) {
  // Load a local file.
  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("title1.html");

  // Verify that the window is present.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  // Check if browser is in fullscreen mode.
  bool is_visible;
  ASSERT_TRUE(browser->IsFullscreen(&is_visible));
  EXPECT_TRUE(is_visible);
  ASSERT_TRUE(browser->IsFullscreenBubbleVisible(&is_visible));
  EXPECT_FALSE(is_visible);
}
#endif  // !defined(OS_MACOSX)

#if defined(OS_WIN)
// This test verifies that Chrome can be launched with a user-data-dir path
// which contains non ASCII characters.
class LaunchBrowserWithNonAsciiUserDatadir : public UITest {
public:
  void SetUp() {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    FilePath tmp_profile = temp_dir_.path().AppendASCII("tmp_profile");
    tmp_profile = tmp_profile.Append(L"Test Chrome G�raldine");

    ASSERT_TRUE(file_util::CreateDirectory(tmp_profile));

    launch_arguments_.AppendSwitchPath(switches::kUserDataDir, tmp_profile);
  }

  bool LaunchAppWithProfile() {
    UITest::SetUp();
    return true;
  }

public:
  ScopedTempDir temp_dir_;
};

TEST_F(LaunchBrowserWithNonAsciiUserDatadir, TestNonAsciiUserDataDir) {
  ASSERT_TRUE(LaunchAppWithProfile());
  // Verify that the window is present.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
}
#endif  // defined(OS_WIN)

// Tests to ensure that the browser continues running in the background after
// the last window closes.
class RunInBackgroundTest : public UITest {
 public:
  RunInBackgroundTest() {
    launch_arguments_.AppendSwitch(switches::kKeepAliveForTest);
  }
};

TEST_F(RunInBackgroundTest, RunInBackgroundBasicTest) {
  // Close the browser window, then open a new one - the browser should keep
  // running.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  int window_count;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(1, window_count);
  ASSERT_TRUE(browser->RunCommand(IDC_CLOSE_WINDOW));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(0, window_count);
  ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_TABBED, true));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(1, window_count);
  // Set the shutdown type to 'SESSION_ENDING' since we are running in
  // background mode and neither closing all the windows nor quitting will
  // shut down the browser.
  set_shutdown_type(ProxyLauncher::SESSION_ENDING);
}

// Tests to ensure that the browser continues running in the background after
// the last window closes.
class NoStartupWindowTest : public UITest {
 public:
  NoStartupWindowTest() {
    launch_arguments_.AppendSwitch(switches::kNoStartupWindow);
    launch_arguments_.AppendSwitch(switches::kKeepAliveForTest);
  }
};

TEST_F(NoStartupWindowTest, NoStartupWindowBasicTest) {
  // No browser window should be started by default.
  int window_count;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(0, window_count);

  // Starting a browser window should work just fine.
  ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_TABBED, true));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(1, window_count);
}

// This test needs to be placed outside the anonymouse namespace because we
// need to access private type of Browser.
class AppModeTest : public UITest {
 public:
  AppModeTest() {
    // Load a local file.
    FilePath test_file(test_data_directory_);
    test_file = test_file.AppendASCII("title1.html");
    GURL test_file_url(net::FilePathToFileURL(test_file));

    launch_arguments_.AppendSwitchASCII(switches::kApp, test_file_url.spec());
  }
};

TEST_F(AppModeTest, EnableAppModeTest) {
  // Test that an application browser window loads correctly.

  // Verify that the window is present.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  // Verify the browser is in application mode.
  bool is_application;
  ASSERT_TRUE(browser->IsApplication(&is_application));
  EXPECT_TRUE(is_application);
}
<commit_msg>ShowModalDialogTest: Remove FLAKE label from BasicTest.<commit_after>// Copyright (c) 2012 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/base_paths.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "base/test/test_file_util.h"
#include "base/test/test_timeouts.h"
#include "base/values.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/net_util.h"
#include "net/test/test_server.h"
#include "ui/gfx/native_widget_types.h"

namespace {

class BrowserTest : public UITest {
};

class VisibleBrowserTest : public UITest {
 protected:
  VisibleBrowserTest() : UITest() {
    show_window_ = true;
  }
};

}  // namespace

// The browser should quit quickly if it receives a WM_ENDSESSION message
// on Windows, or SIGTERM on posix.
TEST_F(BrowserTest, SessionEnd) {
  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("title1.html");

  NavigateToURL(net::FilePathToFileURL(test_file));
  TerminateBrowser();
}

// WindowOpenClose is flaky on ChromeOS and fails consistently on linux views.
// See http://crbug.com/85763.
#if defined (OS_CHROMEOS)
#define MAYBE_WindowOpenClose FLAKY_WindowOpenClose
#elif defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
#define MAYBE_WindowOpenClose FAILS_WindowOpenClose
#else
#define MAYBE_WindowOpenClose WindowOpenClose
#endif

TEST_F(VisibleBrowserTest, MAYBE_WindowOpenClose) {
  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("window.close.html");

  NavigateToURLBlockUntilNavigationsComplete(
      net::FilePathToFileURL(test_file), 2);
  EXPECT_EQ(L"Title Of Awesomeness", GetActiveTabTitle());
}

class ShowModalDialogTest : public UITest {
 public:
  ShowModalDialogTest() {
    launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking);
  }
};

TEST_F(ShowModalDialogTest, BasicTest) {
  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("showmodaldialog.html");

  // This navigation should show a modal dialog that will be immediately
  // closed, but the fact that it was shown should be recorded.
  NavigateToURL(net::FilePathToFileURL(test_file));
  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(1));

  // Verify that we set a mark on successful dialog show.
  scoped_refptr<BrowserProxy> browser = automation()->GetBrowserWindow(0);
  ASSERT_TRUE(browser.get());
  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  std::wstring title;
  ASSERT_TRUE(tab->GetTabTitle(&title));
  ASSERT_EQ(L"SUCCESS", title);
}

class SecurityTest : public UITest {
};

TEST_F(SecurityTest, DisallowFileUrlUniversalAccessTest) {
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());

  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("fileurl_universalaccess.html");

  GURL url = net::FilePathToFileURL(test_file);
  ASSERT_TRUE(tab->NavigateToURL(url));

  std::string value = WaitUntilCookieNonEmpty(tab.get(), url,
        "status", TestTimeouts::action_max_timeout_ms());
  ASSERT_STREQ("Disallowed", value.c_str());
}

#if !defined(OS_MACOSX)
class KioskModeTest : public UITest {
 public:
  KioskModeTest() {
    launch_arguments_.AppendSwitch(switches::kKioskMode);
  }
};

TEST_F(KioskModeTest, EnableKioskModeTest) {
  // Load a local file.
  FilePath test_file(test_data_directory_);
  test_file = test_file.AppendASCII("title1.html");

  // Verify that the window is present.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  // Check if browser is in fullscreen mode.
  bool is_visible;
  ASSERT_TRUE(browser->IsFullscreen(&is_visible));
  EXPECT_TRUE(is_visible);
  ASSERT_TRUE(browser->IsFullscreenBubbleVisible(&is_visible));
  EXPECT_FALSE(is_visible);
}
#endif  // !defined(OS_MACOSX)

#if defined(OS_WIN)
// This test verifies that Chrome can be launched with a user-data-dir path
// which contains non ASCII characters.
class LaunchBrowserWithNonAsciiUserDatadir : public UITest {
public:
  void SetUp() {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    FilePath tmp_profile = temp_dir_.path().AppendASCII("tmp_profile");
    tmp_profile = tmp_profile.Append(L"Test Chrome G�raldine");

    ASSERT_TRUE(file_util::CreateDirectory(tmp_profile));

    launch_arguments_.AppendSwitchPath(switches::kUserDataDir, tmp_profile);
  }

  bool LaunchAppWithProfile() {
    UITest::SetUp();
    return true;
  }

public:
  ScopedTempDir temp_dir_;
};

TEST_F(LaunchBrowserWithNonAsciiUserDatadir, TestNonAsciiUserDataDir) {
  ASSERT_TRUE(LaunchAppWithProfile());
  // Verify that the window is present.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
}
#endif  // defined(OS_WIN)

// Tests to ensure that the browser continues running in the background after
// the last window closes.
class RunInBackgroundTest : public UITest {
 public:
  RunInBackgroundTest() {
    launch_arguments_.AppendSwitch(switches::kKeepAliveForTest);
  }
};

TEST_F(RunInBackgroundTest, RunInBackgroundBasicTest) {
  // Close the browser window, then open a new one - the browser should keep
  // running.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  int window_count;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(1, window_count);
  ASSERT_TRUE(browser->RunCommand(IDC_CLOSE_WINDOW));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(0, window_count);
  ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_TABBED, true));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(1, window_count);
  // Set the shutdown type to 'SESSION_ENDING' since we are running in
  // background mode and neither closing all the windows nor quitting will
  // shut down the browser.
  set_shutdown_type(ProxyLauncher::SESSION_ENDING);
}

// Tests to ensure that the browser continues running in the background after
// the last window closes.
class NoStartupWindowTest : public UITest {
 public:
  NoStartupWindowTest() {
    launch_arguments_.AppendSwitch(switches::kNoStartupWindow);
    launch_arguments_.AppendSwitch(switches::kKeepAliveForTest);
  }
};

TEST_F(NoStartupWindowTest, NoStartupWindowBasicTest) {
  // No browser window should be started by default.
  int window_count;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(0, window_count);

  // Starting a browser window should work just fine.
  ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_TABBED, true));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  EXPECT_EQ(1, window_count);
}

// This test needs to be placed outside the anonymouse namespace because we
// need to access private type of Browser.
class AppModeTest : public UITest {
 public:
  AppModeTest() {
    // Load a local file.
    FilePath test_file(test_data_directory_);
    test_file = test_file.AppendASCII("title1.html");
    GURL test_file_url(net::FilePathToFileURL(test_file));

    launch_arguments_.AppendSwitchASCII(switches::kApp, test_file_url.spec());
  }
};

TEST_F(AppModeTest, EnableAppModeTest) {
  // Test that an application browser window loads correctly.

  // Verify that the window is present.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  // Verify the browser is in application mode.
  bool is_application;
  ASSERT_TRUE(browser->IsApplication(&is_application));
  EXPECT_TRUE(is_application);
}
<|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/message_loop.h"
#include "base/process_util.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/main_function_params.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

// TODO(port): Bring up this test this on other platforms.
#if defined(OS_POSIX)

using base::ProcessHandle;

const char kRendererTestChannelName[] = "test";

extern int RendererMain(const MainFunctionParams& parameters);

// TODO(port): The IPC Channel tests have a class with extremely similar
// functionality, we should combine them.
class RendererMainTest : public base::MultiProcessTest {
 protected:
  RendererMainTest() {}

  // Create a new MessageLoopForIO For each test.
  virtual void SetUp();
  virtual void TearDown();

  // Spawns a child process of the specified type
  base::ProcessHandle SpawnChild(const std::string& procname,
                                 IPC::Channel* channel);

  // Created around each test instantiation.
  MessageLoopForIO *message_loop_;
};

void RendererMainTest::SetUp() {
  MultiProcessTest::SetUp();

  // Construct a fresh IO Message loop for the duration of each test.
  message_loop_ = new MessageLoopForIO();
}

void RendererMainTest::TearDown() {
  delete message_loop_;
  message_loop_ = NULL;

  MultiProcessTest::TearDown();
}

ProcessHandle RendererMainTest::SpawnChild(const std::string& procname,
                                           IPC::Channel* channel) {
  base::file_handle_mapping_vector fds_to_map;
  const int ipcfd = channel->GetClientFileDescriptor();
  if (ipcfd > -1) {
    fds_to_map.push_back(std::pair<int,int>(ipcfd, 3));
  }

  return MultiProcessTest::SpawnChild(procname, fds_to_map, false);
}

// Listener class that kills the message loop when it connects.
class SuicidalListener : public IPC::Channel::Listener {
 public:
  explicit SuicidalListener(bool* suicide_success)
      : suicide_success_(suicide_success) {}

  void OnChannelConnected(int32 peer_pid) {
    *suicide_success_ = true;
    MessageLoop::current()->Quit();
  }

  void OnMessageReceived(const IPC::Message& message) {
    // We shouldn't receive any messages
    ASSERT_TRUE(false);
  }

  // A flag that we set when we have successfully suicided.
  bool* suicide_success_;
};

MULTIPROCESS_TEST_MAIN(SimpleRenderer) {
  SandboxInitWrapper dummy_sandbox_init;
  CommandLine cl(*CommandLine::ForCurrentProcess());
  cl.AppendSwitchASCII(switches::kProcessChannelID, kRendererTestChannelName);

  MainFunctionParams dummy_params(cl, dummy_sandbox_init, NULL);
  return RendererMain(dummy_params);
}

TEST_F(RendererMainTest, CreateDestroy) {
  bool suicide_success = false;
  SuicidalListener listener(&suicide_success);
  IPC::Channel control_channel(kRendererTestChannelName,
                               IPC::Channel::MODE_SERVER,
                               &listener);
  base::ProcessHandle renderer_pid = SpawnChild("SimpleRenderer",
                                                &control_channel);

  ASSERT_TRUE(control_channel.Connect());

  // The SuicidalListener *should* cause the following MessageLoop run
  // to quit, but just in case it doesn't, insert a QuitTask at the back
  // of the queue.
  MessageLoop::current()->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask,
                                          TestTimeouts::action_timeout_ms());
  MessageLoop::current()->Run();
  ASSERT_TRUE(suicide_success);

  // The renderer should exit when we close the channel.
  control_channel.Close();

  EXPECT_TRUE(base::WaitForSingleProcess(renderer_pid,
                                         TestTimeouts::action_timeout_ms()));
}
#endif  // defined(OS_POSIX)
<commit_msg>Revert most of my recent changes to RendererMainTest.<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/message_loop.h"
#include "base/process_util.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/main_function_params.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

// TODO(port): Bring up this test this on other platforms.
#if defined(OS_POSIX)

using base::ProcessHandle;

const char kRendererTestChannelName[] = "test";

extern int RendererMain(const MainFunctionParams& parameters);

// TODO(port): The IPC Channel tests have a class with extremely similar
// functionality, we should combine them.
class RendererMainTest : public base::MultiProcessTest {
 protected:
  RendererMainTest() {}

  // Create a new MessageLoopForIO For each test.
  virtual void SetUp();
  virtual void TearDown();

  // Spawns a child process of the specified type
  base::ProcessHandle SpawnChild(const std::string& procname,
                                 IPC::Channel* channel);

  // Created around each test instantiation.
  MessageLoopForIO *message_loop_;
};

void RendererMainTest::SetUp() {
  MultiProcessTest::SetUp();

  // Construct a fresh IO Message loop for the duration of each test.
  message_loop_ = new MessageLoopForIO();
}

void RendererMainTest::TearDown() {
  delete message_loop_;
  message_loop_ = NULL;

  MultiProcessTest::TearDown();
}

ProcessHandle RendererMainTest::SpawnChild(const std::string& procname,
                                           IPC::Channel* channel) {
  base::file_handle_mapping_vector fds_to_map;
  const int ipcfd = channel->GetClientFileDescriptor();
  if (ipcfd > -1) {
    fds_to_map.push_back(std::pair<int,int>(ipcfd, 3));
  }

  return MultiProcessTest::SpawnChild(procname, fds_to_map, false);
}

// Listener class that kills the message loop when it connects.
class SuicidalListener : public IPC::Channel::Listener {
 public:
  void OnChannelConnected(int32 peer_pid) {
    MessageLoop::current()->Quit();
  }

  void OnMessageReceived(const IPC::Message& message) {
    // We shouldn't receive any messages
    ASSERT_TRUE(false);
  }
};

MULTIPROCESS_TEST_MAIN(SimpleRenderer) {
  SandboxInitWrapper dummy_sandbox_init;
  CommandLine cl(*CommandLine::ForCurrentProcess());
  cl.AppendSwitchASCII(switches::kProcessChannelID, kRendererTestChannelName);

  MainFunctionParams dummy_params(cl, dummy_sandbox_init, NULL);
  return RendererMain(dummy_params);
}

TEST_F(RendererMainTest, CreateDestroy) {
  SuicidalListener listener;
  IPC::Channel control_channel(kRendererTestChannelName,
                               IPC::Channel::MODE_SERVER,
                               &listener);
  base::ProcessHandle renderer_pid = SpawnChild("SimpleRenderer",
                                                &control_channel);

  ASSERT_TRUE(control_channel.Connect());

  MessageLoop::current()->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask,
                                          TestTimeouts::action_timeout_ms());
  MessageLoop::current()->Run();

  // The renderer should exit when we close the channel.
  control_channel.Close();

  EXPECT_TRUE(base::WaitForSingleProcess(renderer_pid,
                                         TestTimeouts::action_timeout_ms()));
}
#endif  // defined(OS_POSIX)
<|endoftext|>


<commit_before>// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved.
//
// 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.

#include "iceoryx_binding_c/internal/cpp2c_subscriber.hpp"
#include "iceoryx_binding_c/types.h"
#include "iceoryx_posh/internal/mepoo/memory_manager.hpp"
#include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp"
#include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp"
#include "iceoryx_posh/internal/popo/ports/subscriber_port_single_producer.hpp"
#include "iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp"
#include "iceoryx_posh/mepoo/mepoo_config.hpp"
#include "mocks/wait_set_mock.hpp"

using namespace iox;
using namespace iox::popo;
using namespace iox::capro;
using namespace iox::mepoo;
using namespace iox::cxx;
using namespace iox::posix;

extern "C" {
#include "iceoryx_binding_c/subscriber.h"
}

#include "test.hpp"

using namespace ::testing;

class iox_sub_test : public Test
{
  public:
    const iox::capro::ServiceDescription TEST_SERVICE_DESCRIPTION{"a", "b", "c"};

  protected:
    iox_sub_test()
    {
        m_mempoolconf.addMemPool({CHUNK_SIZE, NUM_CHUNKS_IN_POOL});
        m_memoryManager.configureMemoryManager(m_mempoolconf, &m_memoryAllocator, &m_memoryAllocator);
        m_subscriber->m_portData = &m_portPtr;
    }

    void SetUp()
    {
        m_triggerCallbackLatestArgument = nullptr;
    }

    void TearDown()
    {
    }

    void Subscribe(SubscriberPortData* ptr)
    {
        uint64_t queueCapacity = MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY;
        iox_sub_subscribe(m_sut, queueCapacity);

        SubscriberPortSingleProducer(ptr).tryGetCaProMessage();
        iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::ACK, TEST_SERVICE_DESCRIPTION);
        SubscriberPortSingleProducer(ptr).dispatchCaProMessageAndGetPossibleResponse(caproMessage);
    }

    static void triggerCallback(iox_sub_t sub)
    {
        m_triggerCallbackLatestArgument = sub;
    }

    static iox_sub_t m_triggerCallbackLatestArgument;
    static constexpr size_t MEMORY_SIZE = 1024 * 1024 * 100;
    uint8_t m_memory[MEMORY_SIZE];
    static constexpr uint32_t NUM_CHUNKS_IN_POOL = MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY + 2;
    static constexpr uint32_t CHUNK_SIZE = 128;

    Allocator m_memoryAllocator{m_memory, MEMORY_SIZE};
    MePooConfig m_mempoolconf;
    MemoryManager m_memoryManager;

    iox::cxx::GenericRAII m_uniqueRouDiId{[] { iox::popo::internal::setUniqueRouDiId(0); },
                                          [] { iox::popo::internal::unsetUniqueRouDiId(); }};
    iox::popo::SubscriberPortData m_portPtr{
        TEST_SERVICE_DESCRIPTION, "myApp", iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer};
    ChunkQueuePusher<SubscriberPortData::ChunkQueueData_t> m_chunkPusher{&m_portPtr.m_chunkReceiverData};
    std::unique_ptr<cpp2c_Subscriber> m_subscriber{new cpp2c_Subscriber};
    iox_sub_t m_sut = m_subscriber.get();

    ConditionVariableData m_condVar;
    std::unique_ptr<WaitSetMock> m_waitSet{new WaitSetMock(&m_condVar)};
};

iox_sub_t iox_sub_test::m_triggerCallbackLatestArgument = nullptr;

TEST_F(iox_sub_test, initialStateNotSubscribed)
{
    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_NOT_SUBSCRIBED);
}

TEST_F(iox_sub_test, offerLeadsToSubscibeRequestedState)
{
    uint64_t queueCapacity = 1u;
    iox_sub_subscribe(m_sut, queueCapacity);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();

    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_SUBSCRIBE_REQUESTED);
}

TEST_F(iox_sub_test, NACKResponseLeadsToSubscribeWaitForOfferState)
{
    uint64_t queueCapacity = 1u;
    iox_sub_subscribe(m_sut, queueCapacity);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();
    iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::NACK, TEST_SERVICE_DESCRIPTION);
    SubscriberPortSingleProducer(&m_portPtr).dispatchCaProMessageAndGetPossibleResponse(caproMessage);

    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_WAIT_FOR_OFFER);
}

TEST_F(iox_sub_test, ACKResponseLeadsToSubscribedState)
{
    uint64_t queueCapacity = 1u;
    iox_sub_subscribe(m_sut, queueCapacity);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();
    iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::ACK, TEST_SERVICE_DESCRIPTION);
    SubscriberPortSingleProducer(&m_portPtr).dispatchCaProMessageAndGetPossibleResponse(caproMessage);

    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_SUBSCRIBED);
}

TEST_F(iox_sub_test, UnsubscribeLeadsToUnscribeRequestedState)
{
    uint64_t queueCapacity = 1u;
    iox_sub_subscribe(m_sut, queueCapacity);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();
    iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::ACK, TEST_SERVICE_DESCRIPTION);
    SubscriberPortSingleProducer(&m_portPtr).dispatchCaProMessageAndGetPossibleResponse(caproMessage);

    iox_sub_unsubscribe(m_sut);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();

    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_UNSUBSCRIBE_REQUESTED);
}

TEST_F(iox_sub_test, initialStateNoChunksAvailable)
{
    const void* chunk = nullptr;
    EXPECT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_NO_CHUNK_RECEIVED);
}

TEST_F(iox_sub_test, receiveChunkWhenThereIsOne)
{
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    const void* chunk = nullptr;
    EXPECT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_SUCCESS);
}

TEST_F(iox_sub_test, receiveChunkWithContent)
{
    this->Subscribe(&m_portPtr);
    struct data_t
    {
        int value;
    };

    auto sharedChunk = m_memoryManager.getChunk(100);
    static_cast<data_t*>(sharedChunk.getPayload())->value = 1234;
    m_chunkPusher.tryPush(sharedChunk);

    const void* chunk = nullptr;

    ASSERT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_SUCCESS);
    EXPECT_THAT(static_cast<const data_t*>(chunk)->value, Eq(1234));
}

TEST_F(iox_sub_test, receiveChunkWhenToManyChunksAreHold)
{
    this->Subscribe(&m_portPtr);
    const void* chunk = nullptr;
    for (uint64_t i = 0; i < MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY + 1; ++i)
    {
        m_chunkPusher.tryPush(m_memoryManager.getChunk(100));
        iox_sub_get_chunk(m_sut, &chunk);
    }

    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));
    EXPECT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_TOO_MANY_CHUNKS_HELD_IN_PARALLEL);
}

TEST_F(iox_sub_test, releaseChunkWorks)
{
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    const void* chunk = nullptr;
    iox_sub_get_chunk(m_sut, &chunk);

    EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(1u));
    iox_sub_release_chunk(m_sut, chunk);
    EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(0u));
}

TEST_F(iox_sub_test, releaseChunkQueuedChunksWorks)
{
    this->Subscribe(&m_portPtr);
    for (uint64_t i = 0; i < MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY; ++i)
    {
        m_chunkPusher.tryPush(m_memoryManager.getChunk(100));
    }

    EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY));
    iox_sub_release_queued_chunks(m_sut);
    EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(0u));
}

TEST_F(iox_sub_test, initialStateHasNewChunksFalse)
{
    EXPECT_FALSE(iox_sub_has_new_chunks(m_sut));
}

TEST_F(iox_sub_test, receivingChunkLeadsToHasNewChunksTrue)
{
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    EXPECT_TRUE(iox_sub_has_new_chunks(m_sut));
}

TEST_F(iox_sub_test, initialStateHasNoLostChunks)
{
    EXPECT_FALSE(iox_sub_has_lost_chunks(m_sut));
}

TEST_F(iox_sub_test, sendingTooMuchLeadsToLostChunks)
{
    this->Subscribe(&m_portPtr);
    for (uint64_t i = 0; i < DefaultChunkQueueConfig::MAX_QUEUE_CAPACITY + 1; ++i)
    {
        m_chunkPusher.tryPush(m_memoryManager.getChunk(100));
    }

    EXPECT_TRUE(iox_sub_has_lost_chunks(m_sut));
}

TEST_F(iox_sub_test, attachingToWaitSetWorks)
{
    EXPECT_EQ(iox_sub_attach_to_waitset(m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, NULL),
              WaitSetResult_SUCCESS);
    EXPECT_EQ(m_waitSet->size(), 1U);
}

TEST_F(iox_sub_test, attachingToAnotherWaitsetCleansupAtOriginalWaitset)
{
    WaitSetMock m_waitSet2{&m_condVar};
    iox_sub_attach_to_waitset(m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, NULL);

    EXPECT_EQ(iox_sub_attach_to_waitset(m_sut, &m_waitSet2, SubscriberEvent_HAS_NEW_SAMPLES, 0, NULL),
              WaitSetResult_SUCCESS);
    EXPECT_EQ(m_waitSet->size(), 0U);
    EXPECT_EQ(m_waitSet2.size(), 1U);
}

TEST_F(iox_sub_test, detachingFromWaitSetWorks)
{
    iox_sub_attach_to_waitset(m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, NULL);
    iox_sub_detach_event(m_sut, SubscriberEvent_HAS_NEW_SAMPLES);
    EXPECT_EQ(m_waitSet->size(), 0U);
}

TEST_F(iox_sub_test, hasNewSamplesTriggersWaitSetWithCorrectTriggerId)
{
    iox_sub_attach_to_waitset(m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 587, NULL);
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    auto triggerVector = m_waitSet->wait();

    ASSERT_EQ(triggerVector.size(), 1U);
    EXPECT_EQ(triggerVector[0].getTriggerId(), 587U);
}

TEST_F(iox_sub_test, hasNewSamplesTriggersWaitSetWithCorrectCallback)
{
    iox_sub_attach_to_waitset(
        m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, iox_sub_test::triggerCallback);
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    auto triggerVector = m_waitSet->wait();

    ASSERT_EQ(triggerVector.size(), 1U);
    triggerVector[0]();
    EXPECT_EQ(m_triggerCallbackLatestArgument, m_sut);
}

TEST_F(iox_sub_test, deinitSubscriberDetachesTriggerFromWaitSet)
{
    iox_sub_attach_to_waitset(
        m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, iox_sub_test::triggerCallback);

    iox_sub_deinit(m_sut);

    EXPECT_EQ(m_waitSet->size(), 0U);
    m_subscriber.reset();
    m_sut = nullptr;
}
<commit_msg>iox-#14 fix subscriber test take 2<commit_after>// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved.
//
// 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.

#include "iceoryx_binding_c/internal/cpp2c_subscriber.hpp"
#include "iceoryx_binding_c/types.h"
#include "iceoryx_posh/internal/mepoo/memory_manager.hpp"
#include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp"
#include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp"
#include "iceoryx_posh/internal/popo/ports/subscriber_port_single_producer.hpp"
#include "iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp"
#include "iceoryx_posh/mepoo/mepoo_config.hpp"
#include "mocks/wait_set_mock.hpp"

using namespace iox;
using namespace iox::popo;
using namespace iox::capro;
using namespace iox::mepoo;
using namespace iox::cxx;
using namespace iox::posix;

extern "C" {
#include "iceoryx_binding_c/subscriber.h"
}

#include "test.hpp"

using namespace ::testing;

class iox_sub_test : public Test
{
  public:
    const iox::capro::ServiceDescription TEST_SERVICE_DESCRIPTION{"a", "b", "c"};

  protected:
    iox_sub_test()
    {
        m_mempoolconf.addMemPool({CHUNK_SIZE, NUM_CHUNKS_IN_POOL});
        m_memoryManager.configureMemoryManager(m_mempoolconf, &m_memoryAllocator, &m_memoryAllocator);
        m_subscriber->m_portData = &m_portPtr;
    }

    void SetUp()
    {
        m_triggerCallbackLatestArgument = nullptr;
    }

    void TearDown()
    {
    }

    void Subscribe(SubscriberPortData* ptr)
    {
        uint64_t queueCapacity = MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY;
        iox_sub_subscribe(m_sut, queueCapacity);

        SubscriberPortSingleProducer(ptr).tryGetCaProMessage();
        iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::ACK, TEST_SERVICE_DESCRIPTION);
        SubscriberPortSingleProducer(ptr).dispatchCaProMessageAndGetPossibleResponse(caproMessage);
    }

    static void triggerCallback(iox_sub_t sub)
    {
        m_triggerCallbackLatestArgument = sub;
    }

    static iox_sub_t m_triggerCallbackLatestArgument;
    static constexpr size_t MEMORY_SIZE = 1024 * 1024 * 100;
    uint8_t m_memory[MEMORY_SIZE];
    static constexpr uint32_t NUM_CHUNKS_IN_POOL = MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY + 2;
    static constexpr uint32_t CHUNK_SIZE = 128;

    Allocator m_memoryAllocator{m_memory, MEMORY_SIZE};
    MePooConfig m_mempoolconf;
    MemoryManager m_memoryManager;

    iox::cxx::GenericRAII m_uniqueRouDiId{[] { iox::popo::internal::setUniqueRouDiId(0); },
                                          [] { iox::popo::internal::unsetUniqueRouDiId(); }};
    iox::popo::SubscriberPortData m_portPtr{
        TEST_SERVICE_DESCRIPTION, "myApp", iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer};
    ChunkQueuePusher<SubscriberPortData::ChunkQueueData_t> m_chunkPusher{&m_portPtr.m_chunkReceiverData};
    std::unique_ptr<cpp2c_Subscriber> m_subscriber{new cpp2c_Subscriber};
    iox_sub_t m_sut = m_subscriber.get();

    ConditionVariableData m_condVar;
    std::unique_ptr<WaitSetMock> m_waitSet{new WaitSetMock(&m_condVar)};
};

iox_sub_t iox_sub_test::m_triggerCallbackLatestArgument = nullptr;

TEST_F(iox_sub_test, initialStateNotSubscribed)
{
    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_NOT_SUBSCRIBED);
}

TEST_F(iox_sub_test, offerLeadsToSubscibeRequestedState)
{
    uint64_t queueCapacity = 1u;
    iox_sub_subscribe(m_sut, queueCapacity);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();

    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_SUBSCRIBE_REQUESTED);
}

TEST_F(iox_sub_test, NACKResponseLeadsToSubscribeWaitForOfferState)
{
    uint64_t queueCapacity = 1u;
    iox_sub_subscribe(m_sut, queueCapacity);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();
    iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::NACK, TEST_SERVICE_DESCRIPTION);
    SubscriberPortSingleProducer(&m_portPtr).dispatchCaProMessageAndGetPossibleResponse(caproMessage);

    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_WAIT_FOR_OFFER);
}

TEST_F(iox_sub_test, ACKResponseLeadsToSubscribedState)
{
    uint64_t queueCapacity = 1u;
    iox_sub_subscribe(m_sut, queueCapacity);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();
    iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::ACK, TEST_SERVICE_DESCRIPTION);
    SubscriberPortSingleProducer(&m_portPtr).dispatchCaProMessageAndGetPossibleResponse(caproMessage);

    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_SUBSCRIBED);
}

TEST_F(iox_sub_test, UnsubscribeLeadsToUnscribeRequestedState)
{
    uint64_t queueCapacity = 1u;
    iox_sub_subscribe(m_sut, queueCapacity);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();
    iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::ACK, TEST_SERVICE_DESCRIPTION);
    SubscriberPortSingleProducer(&m_portPtr).dispatchCaProMessageAndGetPossibleResponse(caproMessage);

    iox_sub_unsubscribe(m_sut);

    SubscriberPortSingleProducer(&m_portPtr).tryGetCaProMessage();

    EXPECT_EQ(iox_sub_get_subscription_state(m_sut), SubscribeState_UNSUBSCRIBE_REQUESTED);
}

TEST_F(iox_sub_test, initialStateNoChunksAvailable)
{
    const void* chunk = nullptr;
    EXPECT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_NO_CHUNK_RECEIVED);
}

TEST_F(iox_sub_test, receiveChunkWhenThereIsOne)
{
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    const void* chunk = nullptr;
    EXPECT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_SUCCESS);
}

TEST_F(iox_sub_test, receiveChunkWithContent)
{
    this->Subscribe(&m_portPtr);
    struct data_t
    {
        int value;
    };

    auto sharedChunk = m_memoryManager.getChunk(100);
    static_cast<data_t*>(sharedChunk.getPayload())->value = 1234;
    m_chunkPusher.tryPush(sharedChunk);

    const void* chunk = nullptr;

    ASSERT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_SUCCESS);
    EXPECT_THAT(static_cast<const data_t*>(chunk)->value, Eq(1234));
}

TEST_F(iox_sub_test, receiveChunkWhenToManyChunksAreHold)
{
    this->Subscribe(&m_portPtr);
    const void* chunk = nullptr;
    for (uint64_t i = 0; i < MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY + 1; ++i)
    {
        m_chunkPusher.tryPush(m_memoryManager.getChunk(100));
        iox_sub_get_chunk(m_sut, &chunk);
    }

    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));
    EXPECT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_TOO_MANY_CHUNKS_HELD_IN_PARALLEL);
}

TEST_F(iox_sub_test, releaseChunkWorks)
{
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    const void* chunk = nullptr;
    iox_sub_get_chunk(m_sut, &chunk);

    EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(1u));
    iox_sub_release_chunk(m_sut, chunk);
    EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(0u));
}

TEST_F(iox_sub_test, releaseChunkQueuedChunksWorks)
{
    this->Subscribe(&m_portPtr);
    for (uint64_t i = 0; i < MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY; ++i)
    {
        m_chunkPusher.tryPush(m_memoryManager.getChunk(100));
    }

    EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY));
    iox_sub_release_queued_chunks(m_sut);
    EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(0u));
}

TEST_F(iox_sub_test, initialStateHasNewChunksFalse)
{
    EXPECT_FALSE(iox_sub_has_new_chunks(m_sut));
}

TEST_F(iox_sub_test, receivingChunkLeadsToHasNewChunksTrue)
{
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    EXPECT_TRUE(iox_sub_has_new_chunks(m_sut));
}

TEST_F(iox_sub_test, initialStateHasNoLostChunks)
{
    EXPECT_FALSE(iox_sub_has_lost_chunks(m_sut));
}

TEST_F(iox_sub_test, sendingTooMuchLeadsToLostChunks)
{
    this->Subscribe(&m_portPtr);
    for (uint64_t i = 0; i < DefaultChunkQueueConfig::MAX_QUEUE_CAPACITY + 1; ++i)
    {
        m_chunkPusher.tryPush(m_memoryManager.getChunk(100));
    }

    EXPECT_TRUE(iox_sub_has_lost_chunks(m_sut));
}

TEST_F(iox_sub_test, attachingToWaitSetWorks)
{
    EXPECT_EQ(iox_sub_attach_to_waitset(m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, NULL),
              WaitSetResult_SUCCESS);
    EXPECT_EQ(m_waitSet->size(), 1U);
}

TEST_F(iox_sub_test, attachingToAnotherWaitsetCleansupAtOriginalWaitset)
{
    WaitSetMock m_waitSet2{&m_condVar};
    iox_sub_attach_to_waitset(m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, NULL);

    EXPECT_EQ(iox_sub_attach_to_waitset(m_sut, &m_waitSet2, SubscriberEvent_HAS_NEW_SAMPLES, 0, NULL),
              WaitSetResult_SUCCESS);
    EXPECT_EQ(m_waitSet->size(), 0U);
    EXPECT_EQ(m_waitSet2.size(), 1U);
}

TEST_F(iox_sub_test, detachingFromWaitSetWorks)
{
    iox_sub_attach_to_waitset(m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, NULL);
    iox_sub_detach_event(m_sut, SubscriberEvent_HAS_NEW_SAMPLES);
    EXPECT_EQ(m_waitSet->size(), 0U);
}

TEST_F(iox_sub_test, hasNewSamplesTriggersWaitSetWithCorrectTriggerId)
{
    iox_sub_attach_to_waitset(m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 587, NULL);
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    auto triggerVector = m_waitSet->wait();

    ASSERT_EQ(triggerVector.size(), 1U);
    EXPECT_EQ(triggerVector[0].getTriggerId(), 587U);
}

TEST_F(iox_sub_test, hasNewSamplesTriggersWaitSetWithCorrectCallback)
{
    iox_sub_attach_to_waitset(
        m_sut, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, iox_sub_test::triggerCallback);
    this->Subscribe(&m_portPtr);
    m_chunkPusher.tryPush(m_memoryManager.getChunk(100));

    auto triggerVector = m_waitSet->wait();

    ASSERT_EQ(triggerVector.size(), 1U);
    triggerVector[0]();
    EXPECT_EQ(m_triggerCallbackLatestArgument, m_sut);
}

TEST_F(iox_sub_test, deinitSubscriberDetachesTriggerFromWaitSet)
{
    // malloc is used since iox_sub_deinit calls the d'tor of cpp2c_Subscriber
    auto subscriber = new (malloc(sizeof(cpp2c_Subscriber))) cpp2c_Subscriber();
    subscriber->m_portData = &m_portPtr;

    iox_sub_attach_to_waitset(
        subscriber, m_waitSet.get(), SubscriberEvent_HAS_NEW_SAMPLES, 0, iox_sub_test::triggerCallback);

    iox_sub_deinit(subscriber);

    EXPECT_EQ(m_waitSet->size(), 0U);

    free(subscriber);
}
<|endoftext|>


<commit_before>//===--- Errors.cpp - Demangling library error handling ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Provides the demangling library with its own error handling functions.
// This is necessary because it isn't always linked with the runtime, so
// it can't use the runtime's error handling.
//
//===----------------------------------------------------------------------===//

#include "swift/Demangling/Errors.h"
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_WIN32)
#include <io.h>
#endif

#if SWIFT_STDLIB_HAS_ASL
#include <asl.h>
#elif defined(__ANDROID__)
#include <android/log.h>
#endif

#if SWIFT_HAVE_CRASHREPORTERCLIENT
#include <atomic>
#include <malloc/malloc.h>

#include "swift/Runtime/Atomic.h"

#include "CrashReporter.h"
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT

// -- Declarations -----------------------------------------------------------

static SWIFT_NORETURN void demangleFatal(uint32_t flags, const char *format,
                                         va_list val);
static void demangleWarn(uint32_t flags, const char *format, va_list val);

static int demangle_vasprintf(char **strp, const char *format, va_list val);

#if SWIFT_HAVE_CRASHREPORTERCLIENT
static int demangle_asprintf(char **strp, const char *format, ...);
#endif

// -- Crash reporter integration ---------------------------------------------

// Report a message to any forthcoming crash log.
static void reportOnCrash(uint32_t flags, const char *message) {
#if SWIFT_HAVE_CRASHREPORTERCLIENT
  char *oldMessage = nullptr;
  char *newMessage = nullptr;

  oldMessage = std::atomic_load_explicit(
    (volatile std::atomic<char *> *)&gCRAnnotations.message,
    SWIFT_MEMORY_ORDER_CONSUME);

  do {
    if (newMessage) {
      free(newMessage);
      newMessage = nullptr;
    }

    if (oldMessage) {
      demangle_asprintf(&newMessage, "%s%s", oldMessage, message);
    } else {
      newMessage = strdup(message);
    }
  } while (!std::atomic_compare_exchange_strong_explicit(
             (volatile std::atomic<char *> *)&gCRAnnotations.message,
             &oldMessage, newMessage,
             std::memory_order_release,
             SWIFT_MEMORY_ORDER_CONSUME));

  if (oldMessage && malloc_size(oldMessage))
    free(oldMessage);
#else
  // empty
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT
}

// -- Utility functions ------------------------------------------------------

// Report a message to system console and stderr.
static void reportNow(uint32_t flags, const char *message) {
#if defined(_WIN32)
#define STDERR_FILENO 2
  _write(STDERR_FILENO, message, strlen(message));
#else
  fputs(message, stderr);
  fflush(stderr);
#endif
#if SWIFT_STDLIB_HAS_ASL
  asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", message);
#elif defined(__ANDROID__)
  __android_log_print(ANDROID_LOG_FATAL, "SwiftDemangle", "%s", message);
#endif
}

/// Report a fatal error to system console, stderr, and crash logs.
/// Does not crash by itself.
static void reportError(uint32_t flags, const char *message) {
  reportNow(flags, message);
  reportOnCrash(flags, message);
}

/// Not everything has vasprintf()
SWIFT_VFORMAT(2)
static int demangle_vasprintf(char **strp, const char *format, va_list args) {
  va_list args_for_len;

  va_copy(args_for_len, args);
  int len = vsnprintf(nullptr, 0, format, args_for_len);
  va_end(args_for_len);

  *strp = nullptr;

  if (len < 0)
    return -1;

  size_t bufsiz = len + 1;
  char *buffer = reinterpret_cast<char *>(malloc(bufsiz));
  if (!buffer)
    return -1;

  int result = vsnprintf(buffer, bufsiz, format, args);
  if (result < 0) {
    free(buffer);
    return -1;
  }

  *strp = buffer;
  return result;
}

#if SWIFT_HAVE_CRASHREPORTERCLIENT
SWIFT_FORMAT(2,3)
static int demangle_asprintf(char **strp, const char *format, ...) {
  va_list val;

  va_start(val, format);
  int ret = demangle_vasprintf(strp, format, val);
  va_end(val);

  return ret;
}
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT

// -- Implementation ---------------------------------------------------------

static SWIFT_NORETURN void demangleFatal(uint32_t flags, const char *format,
                                         va_list val) {
  char *message;

  if (demangle_vasprintf(&message, format, val) < 0) {
    reportError(flags, "unable to format fatal error message");
    abort();
  }

  reportError(flags, message);
  abort();
}

static void demangleWarn(uint32_t flags, const char *format, va_list val) {
  char *message;

  if (demangle_vasprintf(&message, format, val) < 0) {
    reportNow(flags, "unable to format warning message");
    return;
  }

  reportNow(flags, message);
  free(message);
}

// -- Public API -------------------------------------------------------------

namespace swift {
namespace Demangle {
SWIFT_BEGIN_INLINE_NAMESPACE

SWIFT_NORETURN void fatal(uint32_t flags, const char *format, ...) {
  va_list val;

  va_start(val, format);
  fatalv(flags, format, val);
}

void warn(uint32_t flags, const char *format, ...) {
  va_list val;

  va_start(val, format);
  warnv(flags, format, val);
  va_end(val);
}

SWIFT_NORETURN void fatalv(uint32_t flags, const char *format, va_list val) {
  demangleFatal(flags, format, val);
}

void warnv(uint32_t flags, const char *format, va_list val) {
  demangleWarn(flags, format, val);
}

SWIFT_END_INLINE_NAMESPACE
} // end namespace Demangle
} // end namespace swift
<commit_msg>[Demangler] Fix a couple of warnings.<commit_after>//===--- Errors.cpp - Demangling library error handling ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Provides the demangling library with its own error handling functions.
// This is necessary because it isn't always linked with the runtime, so
// it can't use the runtime's error handling.
//
//===----------------------------------------------------------------------===//

#include "swift/Demangling/Errors.h"
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_WIN32)
#include <io.h>
#endif

#if SWIFT_STDLIB_HAS_ASL
#include <asl.h>
#elif defined(__ANDROID__)
#include <android/log.h>
#endif

#if SWIFT_HAVE_CRASHREPORTERCLIENT
#include <atomic>
#include <malloc/malloc.h>

#include "swift/Runtime/Atomic.h"

#include "CrashReporter.h"
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT

// -- Declarations -----------------------------------------------------------

static SWIFT_NORETURN void demangleFatal(uint32_t flags, const char *format,
                                         va_list val);
static void demangleWarn(uint32_t flags, const char *format, va_list val);

static int demangle_vasprintf(char **strp, const char *format, va_list val);

#if SWIFT_HAVE_CRASHREPORTERCLIENT
static int demangle_asprintf(char **strp, const char *format, ...);
#endif

// -- Crash reporter integration ---------------------------------------------

// Report a message to any forthcoming crash log.
static void reportOnCrash(uint32_t flags, const char *message) {
#if SWIFT_HAVE_CRASHREPORTERCLIENT
  char *oldMessage = nullptr;
  char *newMessage = nullptr;

  oldMessage = std::atomic_load_explicit(
    (volatile std::atomic<char *> *)&gCRAnnotations.message,
    SWIFT_MEMORY_ORDER_CONSUME);

  do {
    if (newMessage) {
      free(newMessage);
      newMessage = nullptr;
    }

    if (oldMessage) {
      demangle_asprintf(&newMessage, "%s%s", oldMessage, message);
    } else {
      newMessage = strdup(message);
    }
  } while (!std::atomic_compare_exchange_strong_explicit(
             (volatile std::atomic<char *> *)&gCRAnnotations.message,
             &oldMessage, newMessage,
             std::memory_order_release,
             SWIFT_MEMORY_ORDER_CONSUME));

  if (oldMessage && malloc_size(oldMessage))
    free(oldMessage);
#else
  // empty
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT
}

// -- Utility functions ------------------------------------------------------

// Report a message to system console and stderr.
static void reportNow(uint32_t flags, const char *message) {
#if defined(_WIN32)
#define STDERR_FILENO 2
  _write(STDERR_FILENO, message, strlen(message));
#else
  fputs(message, stderr);
  fflush(stderr);
#endif
#if SWIFT_STDLIB_HAS_ASL
  asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", message);
#elif defined(__ANDROID__)
  __android_log_print(ANDROID_LOG_FATAL, "SwiftDemangle", "%s", message);
#endif
}

/// Report a fatal error to system console, stderr, and crash logs.
/// Does not crash by itself.
static void reportError(uint32_t flags, const char *message) {
  reportNow(flags, message);
  reportOnCrash(flags, message);
}

/// Not everything has vasprintf()
SWIFT_VFORMAT(2)
static int demangle_vasprintf(char **strp, const char *format, va_list args) {
  va_list args_for_len;

  va_copy(args_for_len, args);
  int len = vsnprintf(nullptr, 0, format, args_for_len);
  va_end(args_for_len);

  *strp = nullptr;

  if (len < 0)
    return -1;

  size_t bufsiz = len + 1;
  char *buffer = reinterpret_cast<char *>(malloc(bufsiz));
  if (!buffer)
    return -1;

  int result = vsnprintf(buffer, bufsiz, format, args);
  if (result < 0) {
    free(buffer);
    return -1;
  }

  *strp = buffer;
  return result;
}

#if SWIFT_HAVE_CRASHREPORTERCLIENT
SWIFT_FORMAT(2,3)
static int demangle_asprintf(char **strp, const char *format, ...) {
  va_list val;

  va_start(val, format);
  int ret = demangle_vasprintf(strp, format, val);
  va_end(val);

  return ret;
}
#endif // SWIFT_HAVE_CRASHREPORTERCLIENT

// -- Implementation ---------------------------------------------------------

SWIFT_VFORMAT(2)
static SWIFT_NORETURN void demangleFatal(uint32_t flags, const char *format,
                                         va_list val) {
  char *message;

  if (demangle_vasprintf(&message, format, val) < 0) {
    reportError(flags, "unable to format fatal error message");
    abort();
  }

  reportError(flags, message);
  abort();
}

SWIFT_VFORMAT(2)
static void demangleWarn(uint32_t flags, const char *format, va_list val) {
  char *message;

  if (demangle_vasprintf(&message, format, val) < 0) {
    reportNow(flags, "unable to format warning message");
    return;
  }

  reportNow(flags, message);
  free(message);
}

// -- Public API -------------------------------------------------------------

namespace swift {
namespace Demangle {
SWIFT_BEGIN_INLINE_NAMESPACE

SWIFT_FORMAT(2, 3)
SWIFT_NORETURN void fatal(uint32_t flags, const char *format, ...) {
  va_list val;

  va_start(val, format);
  fatalv(flags, format, val);
}

SWIFT_FORMAT(2, 3)
void warn(uint32_t flags, const char *format, ...) {
  va_list val;

  va_start(val, format);
  warnv(flags, format, val);
  va_end(val);
}

SWIFT_VFORMAT(2)
SWIFT_NORETURN void fatalv(uint32_t flags, const char *format, va_list val) {
  demangleFatal(flags, format, val);
}

SWIFT_VFORMAT(2)
void warnv(uint32_t flags, const char *format, va_list val) {
  demangleWarn(flags, format, val);
}

SWIFT_END_INLINE_NAMESPACE
} // end namespace Demangle
} // end namespace swift
<|endoftext|>


<commit_before>//===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTImporter.h"

using namespace clang;

ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI,
                                               llvm::StringRef InFile) {
  return AdaptedAction->CreateASTConsumer(CI, InFile);
}

bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI,
                                           llvm::StringRef Filename) {
  // FIXME: This is a hack. We need a better way to communicate the
  // AST file, compiler instance, and file name than member variables
  // of FrontendAction.
  AdaptedAction->setCurrentFile(getCurrentFile(), takeCurrentASTUnit());
  AdaptedAction->setCompilerInstance(&CI);
  return AdaptedAction->BeginSourceFileAction(CI, Filename);
}

void ASTMergeAction::ExecuteAction() {
  CompilerInstance &CI = getCompilerInstance();
  CI.getDiagnostics().getClient()->BeginSourceFile(
                                         CI.getASTContext().getLangOptions());
  CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
                                       &CI.getASTContext());
  for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
    ASTUnit *Unit = ASTUnit::LoadFromPCHFile(ASTFiles[I], CI.getDiagnostics(),
                                             false, true);
    if (!Unit)
      continue;

    ASTImporter Importer(CI.getDiagnostics(),
                         CI.getASTContext(),
                         CI.getFileManager(),
                         Unit->getASTContext(),
                         Unit->getFileManager());

    TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
    for (DeclContext::decl_iterator D = TU->decls_begin(),
                                 DEnd = TU->decls_end();
         D != DEnd; ++D) {
      // FIXME: We only merge variables whose names start with x and functions
      // whose names start with 'f'. Why would anyone want anything else?
      if (VarDecl *VD = dyn_cast<VarDecl>(*D)) {
        if (VD->getIdentifier() &&
            *VD->getIdentifier()->getNameStart() == 'x') {
          Decl *Merged = Importer.Import(VD);
          (void)Merged;
        }
      } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*D)) {
        if (FD->getIdentifier() &&
            *FD->getIdentifier()->getNameStart() == 'f') {
          Decl *Merged = Importer.Import(FD);
          (void)Merged;
        }
      }
    }

    delete Unit;
  }

  AdaptedAction->ExecuteAction();
  CI.getDiagnostics().getClient()->EndSourceFile();
}

void ASTMergeAction::EndSourceFileAction() {
  return AdaptedAction->EndSourceFileAction();
}

ASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction,
                               std::string *ASTFiles, unsigned NumASTFiles)
  : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles, ASTFiles + NumASTFiles) {
  assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
}

ASTMergeAction::~ASTMergeAction() {
  delete AdaptedAction;
}

bool ASTMergeAction::usesPreprocessorOnly() const {
  return AdaptedAction->usesPreprocessorOnly();
}

bool ASTMergeAction::usesCompleteTranslationUnit() {
  return AdaptedAction->usesCompleteTranslationUnit();
}

bool ASTMergeAction::hasPCHSupport() const {
  return AdaptedAction->hasPCHSupport();
}

bool ASTMergeAction::hasASTSupport() const {
  return AdaptedAction->hasASTSupport();
}

bool ASTMergeAction::hasCodeCompletionSupport() const {
  return AdaptedAction->hasCodeCompletionSupport();
}
<commit_msg>Tell ASTMerge to merge every declaration it sees, rather than cherry-picking those declarations that we know will work.<commit_after>//===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTImporter.h"

using namespace clang;

ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI,
                                               llvm::StringRef InFile) {
  return AdaptedAction->CreateASTConsumer(CI, InFile);
}

bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI,
                                           llvm::StringRef Filename) {
  // FIXME: This is a hack. We need a better way to communicate the
  // AST file, compiler instance, and file name than member variables
  // of FrontendAction.
  AdaptedAction->setCurrentFile(getCurrentFile(), takeCurrentASTUnit());
  AdaptedAction->setCompilerInstance(&CI);
  return AdaptedAction->BeginSourceFileAction(CI, Filename);
}

void ASTMergeAction::ExecuteAction() {
  CompilerInstance &CI = getCompilerInstance();
  CI.getDiagnostics().getClient()->BeginSourceFile(
                                         CI.getASTContext().getLangOptions());
  CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
                                       &CI.getASTContext());
  for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
    ASTUnit *Unit = ASTUnit::LoadFromPCHFile(ASTFiles[I], CI.getDiagnostics(),
                                             false, true);
    if (!Unit)
      continue;

    ASTImporter Importer(CI.getDiagnostics(),
                         CI.getASTContext(),
                         CI.getFileManager(),
                         Unit->getASTContext(),
                         Unit->getFileManager());

    TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
    for (DeclContext::decl_iterator D = TU->decls_begin(),
                                 DEnd = TU->decls_end();
         D != DEnd; ++D) {
      Importer.Import(*D);
    }

    delete Unit;
  }

  AdaptedAction->ExecuteAction();
  CI.getDiagnostics().getClient()->EndSourceFile();
}

void ASTMergeAction::EndSourceFileAction() {
  return AdaptedAction->EndSourceFileAction();
}

ASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction,
                               std::string *ASTFiles, unsigned NumASTFiles)
  : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles, ASTFiles + NumASTFiles) {
  assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
}

ASTMergeAction::~ASTMergeAction() {
  delete AdaptedAction;
}

bool ASTMergeAction::usesPreprocessorOnly() const {
  return AdaptedAction->usesPreprocessorOnly();
}

bool ASTMergeAction::usesCompleteTranslationUnit() {
  return AdaptedAction->usesCompleteTranslationUnit();
}

bool ASTMergeAction::hasPCHSupport() const {
  return AdaptedAction->hasPCHSupport();
}

bool ASTMergeAction::hasASTSupport() const {
  return AdaptedAction->hasASTSupport();
}

bool ASTMergeAction::hasCodeCompletionSupport() const {
  return AdaptedAction->hasCodeCompletionSupport();
}
<|endoftext|>