<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2010 Miklos Vajna.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_
#include <cppuhelper/implementationentry.hxx>
#endif
#include <osl/module.hxx>
#include <tools/solar.h>
#include <RtfFilter.hxx>
#include <comphelper/mediadescriptor.hxx>
#include <dmapper/DomainMapper.hxx>
#include <rtftok/RTFDocument.hxx>

using namespace ::rtl;
using namespace ::cppu;
using namespace ::com::sun::star;
using ::comphelper::MediaDescriptor;

RtfFilter::RtfFilter( const uno::Reference< uno::XComponentContext >& rxContext)  :
    m_xContext( rxContext )
{
}

RtfFilter::~RtfFilter()
{
}

sal_Bool RtfFilter::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor )
   throw (uno::RuntimeException)
{
    OSL_TRACE("%s", OSL_THIS_FUNC);
    if( m_xSrcDoc.is() )
    {
        uno::Reference< lang::XMultiServiceFactory > xMSF(m_xContext->getServiceManager(), uno::UNO_QUERY_THROW);
        uno::Reference< uno::XInterface > xIfc( xMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.RtfExport" ))), uno::UNO_QUERY_THROW);
        if (!xIfc.is())
            return sal_False;
        uno::Reference< document::XExporter > xExprtr(xIfc, uno::UNO_QUERY_THROW);
        uno::Reference< document::XFilter > xFltr(xIfc, uno::UNO_QUERY_THROW);
        if (!xExprtr.is() || !xFltr.is())
            return sal_False;
        xExprtr->setSourceDocument(m_xSrcDoc);
        return xFltr->filter(aDescriptor);
    }
    else if ( m_xDstDoc.is() )
    {
        MediaDescriptor aMediaDesc( aDescriptor );
#ifdef DEBUG_IMPORT
        OUString sURL = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL(), OUString() );
        ::std::string sURLc = OUStringToOString(sURL, RTL_TEXTENCODING_ASCII_US).getStr();

        writerfilter::TagLogger::Pointer_t dmapperLogger
        (writerfilter::TagLogger::getInstance("DOMAINMAPPER"));
        dmapperLogger->setFileName(sURLc);
        dmapperLogger->startDocument();
#endif
        uno::Reference< io::XInputStream > xInputStream;

        aMediaDesc.addInputStream();
        aMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ] >>= xInputStream;

        writerfilter::Stream::Pointer_t pStream(
                new writerfilter::dmapper::DomainMapper(m_xContext, xInputStream, m_xDstDoc, writerfilter::dmapper::DOCUMENT_RTF));
        writerfilter::rtftok::RTFDocument::Pointer_t const pDocument(
                writerfilter::rtftok::RTFDocumentFactory::createDocument(xInputStream) );
        pDocument->resolve(*pStream);
#ifdef DEBUG_IMPORT
        dmapperLogger->endDocument();
#endif
        return sal_True;
    }
    return sal_False;
}

void RtfFilter::cancel(  ) throw (uno::RuntimeException)
{
}

void RtfFilter::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
   throw (lang::IllegalArgumentException, uno::RuntimeException)
{
   m_xSrcDoc = xDoc;
}

void RtfFilter::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
   throw (lang::IllegalArgumentException, uno::RuntimeException)
{
   m_xDstDoc = xDoc;
}

void RtfFilter::initialize( const uno::Sequence< uno::Any >& /*aArguments*/ ) throw (uno::Exception, uno::RuntimeException)
{
    // The DOCX exporter here extracts 'type' of the filter, ie 'Word' or
    // 'Word Template' but we don't need it for RTF.
}

OUString RtfFilter::getImplementationName(  ) throw (uno::RuntimeException)
{
   return RtfFilter_getImplementationName();
}

#define SERVICE_NAME1 "com.sun.star.document.ImportFilter"
#define SERVICE_NAME2 "com.sun.star.document.ExportFilter"
sal_Bool RtfFilter::supportsService( const OUString& rServiceName ) throw (uno::RuntimeException)
{
    return (rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) ) ||
            rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME2 ) ));
}

uno::Sequence< OUString > RtfFilter::getSupportedServiceNames(  ) throw (uno::RuntimeException)
{
    return RtfFilter_getSupportedServiceNames();
}

/* Helpers, used by shared lib exports. */

OUString RtfFilter_getImplementationName () throw (uno::RuntimeException)
{
   return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.RtfFilter" ) );
}

uno::Sequence< OUString > RtfFilter_getSupportedServiceNames(  ) throw (uno::RuntimeException)
{
   uno::Sequence < OUString > aRet(2);
   OUString* pArray = aRet.getArray();
   pArray[0] =  OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
   pArray[1] =  OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME2 ) );
   return aRet;
}
#undef SERVICE_NAME1
#undef SERVICE_NAME2

uno::Reference< uno::XInterface > RtfFilter_createInstance( const uno::Reference< uno::XComponentContext >& xContext)
                throw( uno::Exception )
{
   return (cppu::OWeakObject*) new RtfFilter( xContext );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Make it easy to disable the new importer<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2010 Miklos Vajna.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_
#include <cppuhelper/implementationentry.hxx>
#endif
#include <osl/module.hxx>
#include <tools/solar.h>
#include <RtfFilter.hxx>
#include <comphelper/mediadescriptor.hxx>
#include <dmapper/DomainMapper.hxx>
#include <rtftok/RTFDocument.hxx>

using namespace ::rtl;
using namespace ::cppu;
using namespace ::com::sun::star;
using ::comphelper::MediaDescriptor;

RtfFilter::RtfFilter( const uno::Reference< uno::XComponentContext >& rxContext)  :
    m_xContext( rxContext )
{
}

RtfFilter::~RtfFilter()
{
}

sal_Bool RtfFilter::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor )
   throw (uno::RuntimeException)
{
    OSL_TRACE("%s", OSL_THIS_FUNC);
    if( m_xSrcDoc.is() )
    {
        uno::Reference< lang::XMultiServiceFactory > xMSF(m_xContext->getServiceManager(), uno::UNO_QUERY_THROW);
        uno::Reference< uno::XInterface > xIfc( xMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.RtfExport" ))), uno::UNO_QUERY_THROW);
        if (!xIfc.is())
            return sal_False;
        uno::Reference< document::XExporter > xExprtr(xIfc, uno::UNO_QUERY_THROW);
        uno::Reference< document::XFilter > xFltr(xIfc, uno::UNO_QUERY_THROW);
        if (!xExprtr.is() || !xFltr.is())
            return sal_False;
        xExprtr->setSourceDocument(m_xSrcDoc);
        return xFltr->filter(aDescriptor);
    }
    else if ( m_xDstDoc.is() )
    {
        bool bUseDomainMapper = true;
        if (bUseDomainMapper)
        {
            MediaDescriptor aMediaDesc( aDescriptor );
#ifdef DEBUG_IMPORT
            OUString sURL = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL(), OUString() );
            ::std::string sURLc = OUStringToOString(sURL, RTL_TEXTENCODING_ASCII_US).getStr();

            writerfilter::TagLogger::Pointer_t dmapperLogger
            (writerfilter::TagLogger::getInstance("DOMAINMAPPER"));
            dmapperLogger->setFileName(sURLc);
            dmapperLogger->startDocument();
#endif
            uno::Reference< io::XInputStream > xInputStream;

            aMediaDesc.addInputStream();
            aMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ] >>= xInputStream;

            writerfilter::Stream::Pointer_t pStream(
                    new writerfilter::dmapper::DomainMapper(m_xContext, xInputStream, m_xDstDoc, writerfilter::dmapper::DOCUMENT_RTF));
            writerfilter::rtftok::RTFDocument::Pointer_t const pDocument(
                    writerfilter::rtftok::RTFDocumentFactory::createDocument(xInputStream) );
            pDocument->resolve(*pStream);
#ifdef DEBUG_IMPORT
            dmapperLogger->endDocument();
#endif
            return sal_True;
        }

        // if not, then use the old importer
        uno::Reference< lang::XMultiServiceFactory > xMSF(m_xContext->getServiceManager(), uno::UNO_QUERY_THROW);
        uno::Reference< uno::XInterface > xIfc( xMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.RtfImport" ))), uno::UNO_QUERY_THROW);
        if (!xIfc.is())
            return sal_False;
        uno::Reference< document::XImporter > xImprtr(xIfc, uno::UNO_QUERY_THROW);
        uno::Reference< document::XFilter > xFltr(xIfc, uno::UNO_QUERY_THROW);
        if (!xImprtr.is() || !xFltr.is())
            return sal_False;
        xImprtr->setTargetDocument(m_xDstDoc);
        return xFltr->filter(aDescriptor);
    }
    return sal_False;
}

void RtfFilter::cancel(  ) throw (uno::RuntimeException)
{
}

void RtfFilter::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
   throw (lang::IllegalArgumentException, uno::RuntimeException)
{
   m_xSrcDoc = xDoc;
}

void RtfFilter::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
   throw (lang::IllegalArgumentException, uno::RuntimeException)
{
   m_xDstDoc = xDoc;
}

void RtfFilter::initialize( const uno::Sequence< uno::Any >& /*aArguments*/ ) throw (uno::Exception, uno::RuntimeException)
{
    // The DOCX exporter here extracts 'type' of the filter, ie 'Word' or
    // 'Word Template' but we don't need it for RTF.
}

OUString RtfFilter::getImplementationName(  ) throw (uno::RuntimeException)
{
   return RtfFilter_getImplementationName();
}

#define SERVICE_NAME1 "com.sun.star.document.ImportFilter"
#define SERVICE_NAME2 "com.sun.star.document.ExportFilter"
sal_Bool RtfFilter::supportsService( const OUString& rServiceName ) throw (uno::RuntimeException)
{
    return (rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) ) ||
            rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME2 ) ));
}

uno::Sequence< OUString > RtfFilter::getSupportedServiceNames(  ) throw (uno::RuntimeException)
{
    return RtfFilter_getSupportedServiceNames();
}

/* Helpers, used by shared lib exports. */

OUString RtfFilter_getImplementationName () throw (uno::RuntimeException)
{
   return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.RtfFilter" ) );
}

uno::Sequence< OUString > RtfFilter_getSupportedServiceNames(  ) throw (uno::RuntimeException)
{
   uno::Sequence < OUString > aRet(2);
   OUString* pArray = aRet.getArray();
   pArray[0] =  OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
   pArray[1] =  OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME2 ) );
   return aRet;
}
#undef SERVICE_NAME1
#undef SERVICE_NAME2

uno::Reference< uno::XInterface > RtfFilter_createInstance( const uno::Reference< uno::XComponentContext >& xContext)
                throw( uno::Exception )
{
   return (cppu::OWeakObject*) new RtfFilter( xContext );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>//===- FileCheck.cpp - Check that File's Contents match what is expected --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// FileCheck does a line-by line check of a file that validates whether it
// contains the expected content.  This is useful for regression tests etc.
//
// This program exits with an error status of 2 on error, exit status of 0 if
// the file matched the expected contents, and exit status of 1 if it did not
// contain the expected contents.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
using namespace llvm;

static cl::opt<std::string>
CheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required);

static cl::opt<std::string>
InputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
              cl::init("-"), cl::value_desc("filename"));

static cl::opt<std::string>
CheckPrefix("check-prefix", cl::init("CHECK"),
            cl::desc("Prefix to use from check file (defaults to 'CHECK')"));

static cl::opt<bool>
NoCanonicalizeWhiteSpace("strict-whitespace",
              cl::desc("Do not treat all horizontal whitespace as equivalent"));

/// CheckString - This is a check that we found in the input file.
struct CheckString {
  /// Str - The string to match.
  std::string Str;

  /// Loc - The location in the match file that the check string was specified.
  SMLoc Loc;

  /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed
  /// to a CHECK: directive.
  bool IsCheckNext;

  /// NotStrings - These are all of the strings that are disallowed from
  /// occurring between this match string and the previous one (or start of
  /// file).
  std::vector<std::pair<SMLoc, std::string> > NotStrings;

  CheckString(const std::string &S, SMLoc L, bool isCheckNext)
    : Str(S), Loc(L), IsCheckNext(isCheckNext) {}
};

/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings.  The strings are added to the CheckStrings vector.
static bool ReadCheckFile(SourceMgr &SM,
                          std::vector<CheckString> &CheckStrings) {
  // Open the check file, and tell SourceMgr about it.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open check file '" << CheckFilename << "': "
           << ErrorStr << '\n';
    return true;
  }
  SM.AddNewSourceBuffer(F, SMLoc());

  // Find all instances of CheckPrefix followed by : in the file.
  StringRef Buffer = F->getBuffer();

  std::vector<std::pair<SMLoc, std::string> > NotMatches;

  while (1) {
    // See if Prefix occurs in the memory buffer.
    Buffer = Buffer.substr(Buffer.find(CheckPrefix));

    // If we didn't find a match, we're done.
    if (Buffer.empty())
      break;

    const char *CheckPrefixStart = Buffer.data();

    // When we find a check prefix, keep track of whether we find CHECK: or
    // CHECK-NEXT:
    bool IsCheckNext = false, IsCheckNot = false;

    // Verify that the : is present after the prefix.
    if (Buffer[CheckPrefix.size()] == ':') {
      Buffer = Buffer.substr(CheckPrefix.size()+1);
    } else if (Buffer.size() > CheckPrefix.size()+6 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+7);
      IsCheckNext = true;
    } else if (Buffer.size() > CheckPrefix.size()+5 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+6);
      IsCheckNot = true;
    } else {
      Buffer = Buffer.substr(1);
      continue;
    }

    // Okay, we found the prefix, yay.  Remember the rest of the line, but
    // ignore leading and trailing whitespace.
    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));

    // Scan ahead to the end of line.
    size_t EOL = Buffer.find_first_of("\n\r");
    if (EOL == StringRef::npos) EOL = Buffer.size();

    // Ignore trailing whitespace.
    while (EOL && (Buffer[EOL-1] == ' ' || Buffer[EOL-1] == '\t'))
      --EOL;

    // Check that there is something on the line.
    if (EOL == 0) {
      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                      "found empty check string with prefix '"+CheckPrefix+":'",
                      "error");
      return true;
    }

    StringRef PatternStr = Buffer.substr(0, EOL);

    // Handle CHECK-NOT.
    if (IsCheckNot) {
      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
                                          PatternStr.str()));
      Buffer = Buffer.substr(EOL);
      continue;
    }

    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
    if (IsCheckNext && CheckStrings.empty()) {
      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
                      CheckPrefix+ ": line", "error");
      return true;
    }

    // Okay, add the string we captured to the output vector and move on.
    CheckStrings.push_back(CheckString(PatternStr.str(),
                                       SMLoc::getFromPointer(Buffer.data()),
                                       IsCheckNext));
    std::swap(NotMatches, CheckStrings.back().NotStrings);

    Buffer = Buffer.substr(EOL);
  }

  if (CheckStrings.empty()) {
    errs() << "error: no check strings found with prefix '" << CheckPrefix
           << ":'\n";
    return true;
  }

  if (!NotMatches.empty()) {
    errs() << "error: '" << CheckPrefix
           << "-NOT:' not supported after last check line.\n";
    return true;
  }

  return false;
}

// CanonicalizeCheckStrings - Replace all sequences of horizontal whitespace in
// the check strings with a single space.
static void CanonicalizeCheckStrings(std::vector<CheckString> &CheckStrings) {
  for (unsigned i = 0, e = CheckStrings.size(); i != e; ++i) {
    std::string &Str = CheckStrings[i].Str;

    for (unsigned C = 0; C != Str.size(); ++C) {
      // If C is not a horizontal whitespace, skip it.
      if (Str[C] != ' ' && Str[C] != '\t')
        continue;

      // Replace the character with space, then remove any other space
      // characters after it.
      Str[C] = ' ';

      while (C+1 != Str.size() &&
             (Str[C+1] == ' ' || Str[C+1] == '\t'))
        Str.erase(Str.begin()+C+1);
    }
  }
}

/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified
/// memory buffer, free it, and return a new one.
static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
  SmallVector<char, 16> NewFile;
  NewFile.reserve(MB->getBufferSize());

  for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
       Ptr != End; ++Ptr) {
    // If C is not a horizontal whitespace, skip it.
    if (*Ptr != ' ' && *Ptr != '\t') {
      NewFile.push_back(*Ptr);
      continue;
    }

    // Otherwise, add one space and advance over neighboring space.
    NewFile.push_back(' ');
    while (Ptr+1 != End &&
           (Ptr[1] == ' ' || Ptr[1] == '\t'))
      ++Ptr;
  }

  // Free the old buffer and return a new one.
  MemoryBuffer *MB2 =
    MemoryBuffer::getMemBufferCopy(NewFile.data(),
                                   NewFile.data() + NewFile.size(),
                                   MB->getBufferIdentifier());

  delete MB;
  return MB2;
}

static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
                             StringRef Buffer) {
  // Otherwise, we have an error, emit an error message.
  SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
                  "error");

  // Print the "scanning from here" line.  If the current position is at the
  // end of a line, advance to the start of the next line.
  Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));

  SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
                  "note");
}

/// CountNumNewlinesBetween - Count the number of newlines in the specified
/// range.
static unsigned CountNumNewlinesBetween(StringRef Range) {
  unsigned NumNewLines = 0;
  while (1) {
    // Scan for newline.
    Range = Range.substr(Range.find_first_of("\n\r"));
    if (Range.empty()) return NumNewLines;

    ++NumNewLines;

    // Handle \n\r and \r\n as a single newline.
    if (Range.size() > 1 &&
        (Range[1] == '\n' || Range[1] == '\r') &&
        (Range[0] != Range[1]))
      Range = Range.substr(1);
    Range = Range.substr(1);
  }
}

int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  cl::ParseCommandLineOptions(argc, argv);

  SourceMgr SM;

  // Read the expected strings from the check file.
  std::vector<CheckString> CheckStrings;
  if (ReadCheckFile(SM, CheckStrings))
    return 2;

  // Remove duplicate spaces in the check strings if requested.
  if (!NoCanonicalizeWhiteSpace)
    CanonicalizeCheckStrings(CheckStrings);

  // Open the file to check and add it to SourceMgr.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open input file '" << InputFilename << "': "
           << ErrorStr << '\n';
    return true;
  }

  // Remove duplicate spaces in the input file if requested.
  if (!NoCanonicalizeWhiteSpace)
    F = CanonicalizeInputFile(F);

  SM.AddNewSourceBuffer(F, SMLoc());

  // Check that we have all of the expected strings, in order, in the input
  // file.
  StringRef Buffer = F->getBuffer();

  const char *LastMatch = Buffer.data();

  for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
    const CheckString &CheckStr = CheckStrings[StrNo];

    StringRef SearchFrom = Buffer;

    // Find StrNo in the file.
    Buffer = Buffer.substr(Buffer.find(CheckStr.Str));

    // If we didn't find a match, reject the input.
    if (Buffer.empty()) {
      PrintCheckFailed(SM, CheckStr, SearchFrom);
      return 1;
    }

    StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch);

    // If this check is a "CHECK-NEXT", verify that the previous match was on
    // the previous line (i.e. that there is one newline between them).
    if (CheckStr.IsCheckNext) {
      // Count the number of newlines between the previous match and this one.
      assert(LastMatch != F->getBufferStart() &&
             "CHECK-NEXT can't be the first check in a file");

      unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
      if (NumNewLines == 0) {
        SM.PrintMessage(CheckStr.Loc,
                    CheckPrefix+"-NEXT: is on the same line as previous match",
                        "error");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        "'next' match was here", "note");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
                        "previous match was here", "note");
        return 1;
      }

      if (NumNewLines != 1) {
        SM.PrintMessage(CheckStr.Loc,
                        CheckPrefix+
                        "-NEXT: is not on the line after the previous match",
                        "error");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        "'next' match was here", "note");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
                        "previous match was here", "note");
        return 1;
      }
    }

    // If this match had "not strings", verify that they don't exist in the
    // skipped region.
    for (unsigned i = 0, e = CheckStr.NotStrings.size(); i != e; ++i) {
      size_t Pos = SkippedRegion.find(CheckStr.NotStrings[i].second);
      if (Pos == StringRef::npos) continue;

      SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos),
                      CheckPrefix+"-NOT: string occurred!", "error");
      SM.PrintMessage(CheckStr.NotStrings[i].first,
                      CheckPrefix+"-NOT: pattern specified here", "note");
      return 1;
    }

    // Otherwise, everything is good.  Remember this as the last match and move
    // on to the next one.
    LastMatch = Buffer.data();
    Buffer = Buffer.substr(CheckStr.Str.size());
  }

  return 0;
}
<commit_msg>fix a FileCheck bug where:<commit_after>//===- FileCheck.cpp - Check that File's Contents match what is expected --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// FileCheck does a line-by line check of a file that validates whether it
// contains the expected content.  This is useful for regression tests etc.
//
// This program exits with an error status of 2 on error, exit status of 0 if
// the file matched the expected contents, and exit status of 1 if it did not
// contain the expected contents.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
using namespace llvm;

static cl::opt<std::string>
CheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required);

static cl::opt<std::string>
InputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
              cl::init("-"), cl::value_desc("filename"));

static cl::opt<std::string>
CheckPrefix("check-prefix", cl::init("CHECK"),
            cl::desc("Prefix to use from check file (defaults to 'CHECK')"));

static cl::opt<bool>
NoCanonicalizeWhiteSpace("strict-whitespace",
              cl::desc("Do not treat all horizontal whitespace as equivalent"));

/// CheckString - This is a check that we found in the input file.
struct CheckString {
  /// Str - The string to match.
  std::string Str;

  /// Loc - The location in the match file that the check string was specified.
  SMLoc Loc;

  /// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed
  /// to a CHECK: directive.
  bool IsCheckNext;

  /// NotStrings - These are all of the strings that are disallowed from
  /// occurring between this match string and the previous one (or start of
  /// file).
  std::vector<std::pair<SMLoc, std::string> > NotStrings;

  CheckString(const std::string &S, SMLoc L, bool isCheckNext)
    : Str(S), Loc(L), IsCheckNext(isCheckNext) {}
};

/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings.  The strings are added to the CheckStrings vector.
static bool ReadCheckFile(SourceMgr &SM,
                          std::vector<CheckString> &CheckStrings) {
  // Open the check file, and tell SourceMgr about it.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open check file '" << CheckFilename << "': "
           << ErrorStr << '\n';
    return true;
  }
  SM.AddNewSourceBuffer(F, SMLoc());

  // Find all instances of CheckPrefix followed by : in the file.
  StringRef Buffer = F->getBuffer();

  std::vector<std::pair<SMLoc, std::string> > NotMatches;

  while (1) {
    // See if Prefix occurs in the memory buffer.
    Buffer = Buffer.substr(Buffer.find(CheckPrefix));

    // If we didn't find a match, we're done.
    if (Buffer.empty())
      break;

    const char *CheckPrefixStart = Buffer.data();

    // When we find a check prefix, keep track of whether we find CHECK: or
    // CHECK-NEXT:
    bool IsCheckNext = false, IsCheckNot = false;

    // Verify that the : is present after the prefix.
    if (Buffer[CheckPrefix.size()] == ':') {
      Buffer = Buffer.substr(CheckPrefix.size()+1);
    } else if (Buffer.size() > CheckPrefix.size()+6 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+7);
      IsCheckNext = true;
    } else if (Buffer.size() > CheckPrefix.size()+5 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+6);
      IsCheckNot = true;
    } else {
      Buffer = Buffer.substr(1);
      continue;
    }

    // Okay, we found the prefix, yay.  Remember the rest of the line, but
    // ignore leading and trailing whitespace.
    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));

    // Scan ahead to the end of line.
    size_t EOL = Buffer.find_first_of("\n\r");
    if (EOL == StringRef::npos) EOL = Buffer.size();

    // Ignore trailing whitespace.
    while (EOL && (Buffer[EOL-1] == ' ' || Buffer[EOL-1] == '\t'))
      --EOL;

    // Check that there is something on the line.
    if (EOL == 0) {
      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                      "found empty check string with prefix '"+CheckPrefix+":'",
                      "error");
      return true;
    }

    StringRef PatternStr = Buffer.substr(0, EOL);

    // Handle CHECK-NOT.
    if (IsCheckNot) {
      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
                                          PatternStr.str()));
      Buffer = Buffer.substr(EOL);
      continue;
    }

    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
    if (IsCheckNext && CheckStrings.empty()) {
      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
                      CheckPrefix+ ": line", "error");
      return true;
    }

    // Okay, add the string we captured to the output vector and move on.
    CheckStrings.push_back(CheckString(PatternStr.str(),
                                       SMLoc::getFromPointer(Buffer.data()),
                                       IsCheckNext));
    std::swap(NotMatches, CheckStrings.back().NotStrings);

    Buffer = Buffer.substr(EOL);
  }

  if (CheckStrings.empty()) {
    errs() << "error: no check strings found with prefix '" << CheckPrefix
           << ":'\n";
    return true;
  }

  if (!NotMatches.empty()) {
    errs() << "error: '" << CheckPrefix
           << "-NOT:' not supported after last check line.\n";
    return true;
  }

  return false;
}

// CanonicalizeCheckStrings - Replace all sequences of horizontal whitespace in
// the check strings with a single space.
static void CanonicalizeCheckStrings(std::vector<CheckString> &CheckStrings) {
  for (unsigned i = 0, e = CheckStrings.size(); i != e; ++i) {
    std::string &Str = CheckStrings[i].Str;

    for (unsigned C = 0; C != Str.size(); ++C) {
      // If C is not a horizontal whitespace, skip it.
      if (Str[C] != ' ' && Str[C] != '\t')
        continue;

      // Replace the character with space, then remove any other space
      // characters after it.
      Str[C] = ' ';

      while (C+1 != Str.size() &&
             (Str[C+1] == ' ' || Str[C+1] == '\t'))
        Str.erase(Str.begin()+C+1);
    }
  }
}

/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified
/// memory buffer, free it, and return a new one.
static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
  SmallVector<char, 16> NewFile;
  NewFile.reserve(MB->getBufferSize());

  for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
       Ptr != End; ++Ptr) {
    // If C is not a horizontal whitespace, skip it.
    if (*Ptr != ' ' && *Ptr != '\t') {
      NewFile.push_back(*Ptr);
      continue;
    }

    // Otherwise, add one space and advance over neighboring space.
    NewFile.push_back(' ');
    while (Ptr+1 != End &&
           (Ptr[1] == ' ' || Ptr[1] == '\t'))
      ++Ptr;
  }

  // Free the old buffer and return a new one.
  MemoryBuffer *MB2 =
    MemoryBuffer::getMemBufferCopy(NewFile.data(),
                                   NewFile.data() + NewFile.size(),
                                   MB->getBufferIdentifier());

  delete MB;
  return MB2;
}

static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
                             StringRef Buffer) {
  // Otherwise, we have an error, emit an error message.
  SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
                  "error");

  // Print the "scanning from here" line.  If the current position is at the
  // end of a line, advance to the start of the next line.
  Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));

  SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
                  "note");
}

/// CountNumNewlinesBetween - Count the number of newlines in the specified
/// range.
static unsigned CountNumNewlinesBetween(StringRef Range) {
  unsigned NumNewLines = 0;
  while (1) {
    // Scan for newline.
    Range = Range.substr(Range.find_first_of("\n\r"));
    if (Range.empty()) return NumNewLines;

    ++NumNewLines;

    // Handle \n\r and \r\n as a single newline.
    if (Range.size() > 1 &&
        (Range[1] == '\n' || Range[1] == '\r') &&
        (Range[0] != Range[1]))
      Range = Range.substr(1);
    Range = Range.substr(1);
  }
}

int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  cl::ParseCommandLineOptions(argc, argv);

  SourceMgr SM;

  // Read the expected strings from the check file.
  std::vector<CheckString> CheckStrings;
  if (ReadCheckFile(SM, CheckStrings))
    return 2;

  // Remove duplicate spaces in the check strings if requested.
  if (!NoCanonicalizeWhiteSpace)
    CanonicalizeCheckStrings(CheckStrings);

  // Open the file to check and add it to SourceMgr.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open input file '" << InputFilename << "': "
           << ErrorStr << '\n';
    return true;
  }

  // Remove duplicate spaces in the input file if requested.
  if (!NoCanonicalizeWhiteSpace)
    F = CanonicalizeInputFile(F);

  SM.AddNewSourceBuffer(F, SMLoc());

  // Check that we have all of the expected strings, in order, in the input
  // file.
  StringRef Buffer = F->getBuffer();

  const char *LastMatch = Buffer.data();

  for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
    const CheckString &CheckStr = CheckStrings[StrNo];

    StringRef SearchFrom = Buffer;

    // Find StrNo in the file.
    Buffer = Buffer.substr(Buffer.find(CheckStr.Str));

    // If we didn't find a match, reject the input.
    if (Buffer.empty()) {
      PrintCheckFailed(SM, CheckStr, SearchFrom);
      return 1;
    }

    StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch);

    // If this check is a "CHECK-NEXT", verify that the previous match was on
    // the previous line (i.e. that there is one newline between them).
    if (CheckStr.IsCheckNext) {
      // Count the number of newlines between the previous match and this one.
      assert(LastMatch != F->getBufferStart() &&
             "CHECK-NEXT can't be the first check in a file");

      unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
      if (NumNewLines == 0) {
        SM.PrintMessage(CheckStr.Loc,
                    CheckPrefix+"-NEXT: is on the same line as previous match",
                        "error");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        "'next' match was here", "note");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
                        "previous match was here", "note");
        return 1;
      }

      if (NumNewLines != 1) {
        SM.PrintMessage(CheckStr.Loc,
                        CheckPrefix+
                        "-NEXT: is not on the line after the previous match",
                        "error");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        "'next' match was here", "note");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
                        "previous match was here", "note");
        return 1;
      }
    }

    // If this match had "not strings", verify that they don't exist in the
    // skipped region.
    for (unsigned i = 0, e = CheckStr.NotStrings.size(); i != e; ++i) {
      size_t Pos = SkippedRegion.find(CheckStr.NotStrings[i].second);
      if (Pos == StringRef::npos) continue;

      SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos),
                      CheckPrefix+"-NOT: string occurred!", "error");
      SM.PrintMessage(CheckStr.NotStrings[i].first,
                      CheckPrefix+"-NOT: pattern specified here", "note");
      return 1;
    }

    // Otherwise, everything is good.  Step over the matched text and remember
    // the position after the match as the end of the last match.
    Buffer = Buffer.substr(CheckStr.Str.size());
    LastMatch = Buffer.data();
  }

  return 0;
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_OPENCL_IS_MATRIX_CL_HPP
#define STAN_MATH_OPENCL_IS_MATRIX_CL_HPP
#ifdef STAN_OPENCL

#include <stan/math/prim/meta.hpp>
#include <type_traits>

namespace stan {

namespace math {
 /**
  * Dummy class to instantiate matrix_cl to enable for specific types.
  * @ingroup matrix_cl_group
  */
template <typename T, typename = void>
class matrix_cl {
 public:
  using Scalar = T;
  using type = T;
};
}  // namespace math

namespace internal {

/** \ingroup type_traits
 * @internal
 * This underlying implementation is used when the type is not an std vector.
 */
template <typename T>
struct is_matrix_cl_impl : std::false_type {};

/** \ingroup type_traits
 * @internal
 * This specialization implementation has a static member named value when the
 * template type is an std vector.
 */
template <typename... Args>
struct is_matrix_cl_impl<stan::math::matrix_cl<Args...>> : std::true_type {};

}  // namespace internal

template <typename T, typename = void>
struct is_matrix_cl : std::false_type {};

/** \ingroup type_traits
 * Checks if the decayed type of T is a matrix_cl.
 */
template <typename T>
struct is_matrix_cl<
    T, std::enable_if_t<internal::is_matrix_cl_impl<std::decay_t<T>>::value>>
    : std::true_type {};

STAN_ADD_REQUIRE_UNARY(matrix_cl, is_matrix_cl, matrix_cl_group);
STAN_ADD_REQUIRE_CONTAINER(matrix_cl, is_matrix_cl, matrix_cl_group);

}  // namespace stan
#endif
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 6.0.0<commit_after>#ifndef STAN_MATH_OPENCL_IS_MATRIX_CL_HPP
#define STAN_MATH_OPENCL_IS_MATRIX_CL_HPP
#ifdef STAN_OPENCL

#include <stan/math/prim/meta.hpp>
#include <type_traits>

namespace stan {

namespace math {
/**
 * Dummy class to instantiate matrix_cl to enable for specific types.
 * @ingroup matrix_cl_group
 */
template <typename T, typename = void>
class matrix_cl {
 public:
  using Scalar = T;
  using type = T;
};
}  // namespace math

namespace internal {

/** \ingroup type_traits
 * @internal
 * This underlying implementation is used when the type is not an std vector.
 */
template <typename T>
struct is_matrix_cl_impl : std::false_type {};

/** \ingroup type_traits
 * @internal
 * This specialization implementation has a static member named value when the
 * template type is an std vector.
 */
template <typename... Args>
struct is_matrix_cl_impl<stan::math::matrix_cl<Args...>> : std::true_type {};

}  // namespace internal

template <typename T, typename = void>
struct is_matrix_cl : std::false_type {};

/** \ingroup type_traits
 * Checks if the decayed type of T is a matrix_cl.
 */
template <typename T>
struct is_matrix_cl<
    T, std::enable_if_t<internal::is_matrix_cl_impl<std::decay_t<T>>::value>>
    : std::true_type {};

STAN_ADD_REQUIRE_UNARY(matrix_cl, is_matrix_cl, matrix_cl_group);
STAN_ADD_REQUIRE_CONTAINER(matrix_cl, is_matrix_cl, matrix_cl_group);

}  // namespace stan
#endif
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_OPENCL_REV_MULTIPLY_HPP
#define STAN_MATH_OPENCL_REV_MULTIPLY_HPP
#ifdef STAN_OPENCL

#include <stan/math/prim/meta/is_kernel_expression.hpp>
#include <stan/math/opencl/prim/multiply.hpp>
#include <stan/math/opencl/matrix_cl.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/fun/value_of.hpp>
#include <stan/math/rev/core/reverse_pass_callback.hpp>
#include <stan/math/prim/fun/value_of.hpp>

namespace stan {
namespace math {

/**
 * Matrix multiplication of two reverse mode matrices and/or kernel generator
 * expressions.
 * @tparam T_a type of first expression
 * @tparam T_b type of second expression
 * @param a first expression
 * @param b second expression
 * @return Matrix product of given arguments
 */
template <
    typename T_a, typename T_b,
    require_all_nonscalar_prim_or_rev_kernel_expression_t<T_a, T_b>* = nullptr,
    require_any_var_t<T_a, T_b>* = nullptr>
inline auto multiply(const T_a& a, const T_b& b) {
  check_size_match("multiply ((OpenCL))", "A.cols()", a.cols(), "B.rows()",
                   b.rows());
  const arena_t<T_a>& a_arena = a;
  const arena_t<T_b>& b_arena = b;

  var_value<matrix_cl<double>> res = value_of(a_arena) * value_of(b_arena);

  reverse_pass_callback([a_arena, b_arena, res]() mutable {
    if (!is_constant<T_a>::value) {
      auto& a_adj = forward_as<var_value<matrix_cl<double>>>(a_arena).adj();
      a_adj = a_adj + res.adj() * transpose(value_of(b_arena));
    }
    if (!is_constant<T_b>::value) {
      auto& b_adj = forward_as<var_value<matrix_cl<double>>>(b_arena).adj();
      b_adj = b_adj + transpose(value_of(a_arena)) * res.adj();
    }
  });
  return res;
}

/**
 * Matrix multiplication of two reverse mode matrices and/or kernel generator
 * expressions.
 * @tparam T_a type of first expression
 * @tparam T_b type of second expression
 * @param a first expression
 * @param b second expression
 * @return Matrix product of given arguments
 */
template <
    typename T_a, typename T_b,
    require_all_nonscalar_prim_or_rev_kernel_expression_t<T_a, T_b>* = nullptr,
    require_any_var_t<T_a, T_b>* = nullptr>
inline auto operator*(const T_a& a, const T_b& b) {
  return multiply(a, b);
}

/**
 * Return matrix multiplied by a scalar.
 *
 * @tparam T1 type of the scalar
 * @tparam T2 type of the matrix or expression
 *
 * @param a scalar
 * @param b matrix
 * @return product of matrix and scalar
 */
template <typename T1, typename T2, require_stan_scalar_t<T1>* = nullptr,
          require_all_nonscalar_prim_or_rev_kernel_expression_t<T2>* = nullptr,
          require_any_var_t<T1, T2>* = nullptr>
inline auto multiply(const T1& a, const T2& b) {
  const arena_t<T1>& a_arena = a;
  const arena_t<T2>& b_arena = b;

  var_value<matrix_cl<double>> res = value_of(a_arena) * value_of(b_arena);

  reverse_pass_callback([a_arena, b_arena, res]() mutable {
    if (!is_constant<T1>::value) {
      auto& a_adj = forward_as<var_value<double>>(a_arena).adj();
      a_adj = a_adj + sum(elt_multiply(res.adj(), value_of(b_arena)));
    }
    if (!is_constant<T2>::value) {
      auto& b_adj = forward_as<var_value<matrix_cl<double>>>(b_arena).adj();
      b_adj = b_adj + value_of(a_arena) * res.adj();
    }
  });
  return res;
}

/**
 * Return matrix multiplied by a scalar.
 *
 * @tparam T1 type of the matrix or expression
 * @tparam T2 type of the scalar
 *
 * @param a matrix
 * @param b scalar
 * @return product of matrix and scalar
 */
template <typename T1, typename T2, require_stan_scalar_t<T2>* = nullptr,
          require_all_nonscalar_prim_or_rev_kernel_expression_t<T1>* = nullptr,
          require_any_var_t<T1, T2>* = nullptr>
inline auto multiply(const T1& A, const T2& B) {
  return multiply(B, A);
}

}  // namespace math
}  // namespace stan

#endif
#endif
<commit_msg>fix capitalization<commit_after>#ifndef STAN_MATH_OPENCL_REV_MULTIPLY_HPP
#define STAN_MATH_OPENCL_REV_MULTIPLY_HPP
#ifdef STAN_OPENCL

#include <stan/math/prim/meta/is_kernel_expression.hpp>
#include <stan/math/opencl/prim/multiply.hpp>
#include <stan/math/opencl/matrix_cl.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/fun/value_of.hpp>
#include <stan/math/rev/core/reverse_pass_callback.hpp>
#include <stan/math/prim/fun/value_of.hpp>

namespace stan {
namespace math {

/**
 * Matrix multiplication of two reverse mode matrices and/or kernel generator
 * expressions.
 * @tparam T_a type of first expression
 * @tparam T_b type of second expression
 * @param a first expression
 * @param b second expression
 * @return Matrix product of given arguments
 */
template <
    typename T_a, typename T_b,
    require_all_nonscalar_prim_or_rev_kernel_expression_t<T_a, T_b>* = nullptr,
    require_any_var_t<T_a, T_b>* = nullptr>
inline auto multiply(const T_a& a, const T_b& b) {
  check_size_match("multiply ((OpenCL))", "A.cols()", a.cols(), "B.rows()",
                   b.rows());
  const arena_t<T_a>& a_arena = a;
  const arena_t<T_b>& b_arena = b;

  var_value<matrix_cl<double>> res = value_of(a_arena) * value_of(b_arena);

  reverse_pass_callback([a_arena, b_arena, res]() mutable {
    if (!is_constant<T_a>::value) {
      auto& a_adj = forward_as<var_value<matrix_cl<double>>>(a_arena).adj();
      a_adj = a_adj + res.adj() * transpose(value_of(b_arena));
    }
    if (!is_constant<T_b>::value) {
      auto& b_adj = forward_as<var_value<matrix_cl<double>>>(b_arena).adj();
      b_adj = b_adj + transpose(value_of(a_arena)) * res.adj();
    }
  });
  return res;
}

/**
 * Matrix multiplication of two reverse mode matrices and/or kernel generator
 * expressions.
 * @tparam T_a type of first expression
 * @tparam T_b type of second expression
 * @param a first expression
 * @param b second expression
 * @return Matrix product of given arguments
 */
template <
    typename T_a, typename T_b,
    require_all_nonscalar_prim_or_rev_kernel_expression_t<T_a, T_b>* = nullptr,
    require_any_var_t<T_a, T_b>* = nullptr>
inline auto operator*(const T_a& a, const T_b& b) {
  return multiply(a, b);
}

/**
 * Return matrix multiplied by a scalar.
 *
 * @tparam T1 type of the scalar
 * @tparam T2 type of the matrix or expression
 *
 * @param a scalar
 * @param b matrix
 * @return product of matrix and scalar
 */
template <typename T1, typename T2, require_stan_scalar_t<T1>* = nullptr,
          require_all_nonscalar_prim_or_rev_kernel_expression_t<T2>* = nullptr,
          require_any_var_t<T1, T2>* = nullptr>
inline auto multiply(const T1& a, const T2& b) {
  const arena_t<T1>& a_arena = a;
  const arena_t<T2>& b_arena = b;

  var_value<matrix_cl<double>> res = value_of(a_arena) * value_of(b_arena);

  reverse_pass_callback([a_arena, b_arena, res]() mutable {
    if (!is_constant<T1>::value) {
      auto& a_adj = forward_as<var_value<double>>(a_arena).adj();
      a_adj = a_adj + sum(elt_multiply(res.adj(), value_of(b_arena)));
    }
    if (!is_constant<T2>::value) {
      auto& b_adj = forward_as<var_value<matrix_cl<double>>>(b_arena).adj();
      b_adj = b_adj + value_of(a_arena) * res.adj();
    }
  });
  return res;
}

/**
 * Return matrix multiplied by a scalar.
 *
 * @tparam T1 type of the matrix or expression
 * @tparam T2 type of the scalar
 *
 * @param a matrix
 * @param b scalar
 * @return product of matrix and scalar
 */
template <typename T1, typename T2, require_stan_scalar_t<T2>* = nullptr,
          require_all_nonscalar_prim_or_rev_kernel_expression_t<T1>* = nullptr,
          require_any_var_t<T1, T2>* = nullptr>
inline auto multiply(const T1& a, const T2& b) {
  return multiply(b, a);
}

}  // namespace math
}  // namespace stan

#endif
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_FUN_LOG_SUM_EXP_HPP
#define STAN_MATH_REV_FUN_LOG_SUM_EXP_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/fun/typedefs.hpp>
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/fun/constants.hpp>
#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/fun/inv_logit.hpp>
#include <stan/math/prim/fun/log_sum_exp.hpp>
#include <cmath>
#include <vector>

namespace stan {
namespace math {
namespace internal {

class log_sum_exp_vv_vari : public op_vv_vari {
 public:
  log_sum_exp_vv_vari(vari* avi, vari* bvi)
      : op_vv_vari(log_sum_exp(avi->val_, bvi->val_), avi, bvi) {}
  void chain() {
    avi_->adj_ += adj_ * inv_logit(avi_->val_ - bvi_->val_);
    bvi_->adj_ += adj_ * inv_logit(bvi_->val_ - avi_->val_);
  }
};
class log_sum_exp_vd_vari : public op_vd_vari {
 public:
  log_sum_exp_vd_vari(vari* avi, double b)
      : op_vd_vari(log_sum_exp(avi->val_, b), avi, b) {}
  void chain() {
    if (val_ == NEGATIVE_INFTY) {
      avi_->adj_ += adj_;
    } else {
      avi_->adj_ += adj_ * inv_logit(avi_->val_ - bd_);
    }
  }
};

}  // namespace internal

/**
 * Returns the log sum of exponentials.
 */
inline var log_sum_exp(const var& a, const var& b) {
  return var(new internal::log_sum_exp_vv_vari(a.vi_, b.vi_));
}
/**
 * Returns the log sum of exponentials.
 */
inline var log_sum_exp(const var& a, double b) {
  return var(new internal::log_sum_exp_vd_vari(a.vi_, b));
}
/**
 * Returns the log sum of exponentials.
 */
inline var log_sum_exp(double a, const var& b) {
  return var(new internal::log_sum_exp_vd_vari(b.vi_, a));
}

/**
 * Returns the log sum of exponentials.
 *
 * @tparam T Type of input vector or matrix.
 * @param x matrix
 */
template <typename T, require_container_st<is_var, T>* = nullptr>
inline auto log_sum_exp(const T& x) {
  return apply_vector_unary<T>::reduce(x, [](const auto& v) {
    arena_t<decltype(v)> arena_v = v;

    var res = log_sum_exp(arena_v.val());

    reverse_pass_callback([arena_v, res]() mutable {
      arena_v.adj()
          += res.adj() * (arena_v.array().val() - res.val()).exp().matrix();
    });

    return res;
  });
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>pull out values for log_sum_exp<commit_after>#ifndef STAN_MATH_REV_FUN_LOG_SUM_EXP_HPP
#define STAN_MATH_REV_FUN_LOG_SUM_EXP_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/fun/typedefs.hpp>
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/fun/constants.hpp>
#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/fun/inv_logit.hpp>
#include <stan/math/prim/fun/log_sum_exp.hpp>
#include <cmath>
#include <vector>

namespace stan {
namespace math {
namespace internal {

class log_sum_exp_vv_vari : public op_vv_vari {
 public:
  log_sum_exp_vv_vari(vari* avi, vari* bvi)
      : op_vv_vari(log_sum_exp(avi->val_, bvi->val_), avi, bvi) {}
  void chain() {
    avi_->adj_ += adj_ * inv_logit(avi_->val_ - bvi_->val_);
    bvi_->adj_ += adj_ * inv_logit(bvi_->val_ - avi_->val_);
  }
};
class log_sum_exp_vd_vari : public op_vd_vari {
 public:
  log_sum_exp_vd_vari(vari* avi, double b)
      : op_vd_vari(log_sum_exp(avi->val_, b), avi, b) {}
  void chain() {
    if (val_ == NEGATIVE_INFTY) {
      avi_->adj_ += adj_;
    } else {
      avi_->adj_ += adj_ * inv_logit(avi_->val_ - bd_);
    }
  }
};

}  // namespace internal

/**
 * Returns the log sum of exponentials.
 */
inline var log_sum_exp(const var& a, const var& b) {
  return var(new internal::log_sum_exp_vv_vari(a.vi_, b.vi_));
}
/**
 * Returns the log sum of exponentials.
 */
inline var log_sum_exp(const var& a, double b) {
  return var(new internal::log_sum_exp_vd_vari(a.vi_, b));
}
/**
 * Returns the log sum of exponentials.
 */
inline var log_sum_exp(double a, const var& b) {
  return var(new internal::log_sum_exp_vd_vari(b.vi_, a));
}

/**
 * Returns the log sum of exponentials.
 *
 * @tparam T Type of input vector or matrix.
 * @param x matrix
 */
template <typename T, require_container_st<is_var, T>* = nullptr>
inline auto log_sum_exp(const T& x) {
  return apply_vector_unary<T>::reduce(x, [](const auto& v) {
    arena_t<decltype(v)> arena_v = v;
    arena_t<decltype(v.val())> arena_v_val = v.val();
    var res = log_sum_exp(arena_v_val);

    reverse_pass_callback([arena_v, arena_v_val, res]() mutable {
      arena_v.adj()
          += res.adj() * (arena_v_val.array().val() - res.val()).exp().matrix();
    });

    return res;
  });
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
#include <sstream>
// StdAir
#include <stdair/stdair_types.hpp>
#include <stdair/basic/BasChronometer.hpp>
#include <stdair/bom/BomManager.hpp>
#include <stdair/bom/BomDisplay.hpp>
#include <stdair/bom/BomRoot.hpp>
#include <stdair/bom/EventQueue.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/bom/BookingRequestStruct.hpp>
#include <stdair/command/CmdBomManager.hpp>
#include <stdair/service/FacSupervisor.hpp>
#include <stdair/service/FacSTDAIRServiceContext.hpp>
#include <stdair/service/STDAIR_ServiceContext.hpp>
#include <stdair/service/Logger.hpp>
#include <stdair/service/DBSessionManager.hpp>
#include <stdair/STDAIR_Service.hpp>

namespace stdair {

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::STDAIR_Service() : _stdairServiceContext (NULL) {

    // Initialise the service context
    initServiceContext();

    // Initialise the (remaining of the) context
    init();
  }

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::STDAIR_Service (const STDAIR_Service& iService)
    : _stdairServiceContext (NULL) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::STDAIR_Service (const BasLogParams& iLogParams)
    : _stdairServiceContext (NULL) {

    // Initialise the service context
    initServiceContext();

    // Set the log file
    logInit (iLogParams);

    // Initialise the (remaining of the) context
    init();
  }

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::STDAIR_Service (const BasLogParams& iLogParams,
                                  const BasDBParams& iDBParams)
    : _stdairServiceContext (NULL) {

    // Initialise the service context
    initServiceContext();

    // Set the log file
    logInit (iLogParams);

    // Create a database session
    dbInit (iDBParams);

    // Initialise the (remaining of the) context
    init();
  }

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::~STDAIR_Service() {
    // Delete/Clean all the objects from memory
    finalise();
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::initServiceContext() {
    // Initialise the service context
    STDAIR_ServiceContext& lSTDAIR_ServiceContext =
      FacSTDAIRServiceContext::instance().create();

    // Store the stdair service context
    _stdairServiceContext = &lSTDAIR_ServiceContext;
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::logInit (const BasLogParams& iLogParams) {
    Logger::init (iLogParams);
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::dbInit (const BasDBParams& iDBParams) {
    DBSessionManager::init (iDBParams);

    // Store the database parameters into the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;
    lSTDAIR_ServiceContext.setDBParams (iDBParams);
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::init() {
  }

  // //////////////////////////////////////////////////////////////////////
  BomRoot& STDAIR_Service::getBomRoot() const {
    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;
    return lSTDAIR_ServiceContext.getBomRoot();
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue& STDAIR_Service::getEventQueue() const {
    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;
    return lSTDAIR_ServiceContext.getEventQueue();
  }

  // //////////////////////////////////////////////////////////////////////
  BasLogParams STDAIR_Service::getLogParams() const {
    return Logger::getLogParams();
  }

  // //////////////////////////////////////////////////////////////////////
  const BasDBParams& STDAIR_Service::getDBParams() const {
    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;
    return lSTDAIR_ServiceContext.getDBParams();
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::buildSampleBom (const bool isForRMOL,
                                       const CabinCapacity_T iCabinCapacity ) {
    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the BOM tree root
    BomRoot& lBomRoot = lSTDAIR_ServiceContext.getBomRoot();

    // Build a sample BOM tree
    if (isForRMOL == true) {
      CmdBomManager::buildSampleBomForRMOL (lBomRoot, iCabinCapacity);
    } else {
      CmdBomManager::buildSampleBom (lBomRoot);
    }
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::buildSampleBomForFareQuoter () {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the BOM tree root
    BomRoot& lBomRoot = lSTDAIR_ServiceContext.getBomRoot();

    // Build a sample BOM tree
    CmdBomManager::buildSampleBomForFareQuoter (lBomRoot);
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::
  buildSampleTravelSolutionForPricing (TravelSolutionList_T& ioTravelSolutionList) {
    // Build a sample list of travel solution structures
    CmdBomManager::buildSampleTravelSolutionForPricing (ioTravelSolutionList);
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::
  buildSampleTravelSolutions (TravelSolutionList_T& ioTravelSolutionList) {
    // Build a sample list of travel solution structures
    CmdBomManager::buildSampleTravelSolutions (ioTravelSolutionList);
  }

  // //////////////////////////////////////////////////////////////////////
  BookingRequestStruct STDAIR_Service::
  buildSampleBookingRequest (const bool isForCRS) {

    // Build a sample booking request structure
    if (isForCRS == true) {
      return CmdBomManager::buildSampleBookingRequestForCRS();
    }

    return CmdBomManager::buildSampleBookingRequest();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string STDAIR_Service::csvDisplay() const {
    std::ostringstream oStr;

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the BOM tree root
    BomRoot& lBomRoot = lSTDAIR_ServiceContext.getBomRoot();

    // Dump the content of the whole BOM tree into the string
    BomDisplay::csvDisplay (oStr, lBomRoot);

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string STDAIR_Service::
  csvDisplay (const TravelSolutionList_T& iTravelSolutionList) const {
    std::ostringstream oStr;

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Dump the content of the whole list of travel solutions into the string
    BomDisplay::csvDisplay (oStr, iTravelSolutionList);

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::finalise() {
    // Clean all the objects
    FacSupervisor::cleanAll();
  }

  // ////////////////////////////////////////////////////////////////////
  const Count_T& STDAIR_Service::
  getExpectedTotalNumberOfEventsToBeGenerated() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the dedicated command
    const Count_T& oExpectedTotalNumberOfEventsToBeGenerated =
      lQueue.getExpectedTotalNbOfEvents();

    //
    return oExpectedTotalNumberOfEventsToBeGenerated;
  }

  // ////////////////////////////////////////////////////////////////////
  const Count_T& STDAIR_Service::
  getExpectedTotalNumberOfEventsToBeGenerated (const EventType::EN_EventType& iType) const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the dedicated command
    const Count_T& oExpectedTotalNumberOfEventsToBeGenerated =
      lQueue.getExpectedTotalNbOfEvents (iType);

    //
    return oExpectedTotalNumberOfEventsToBeGenerated;
  }

  // ////////////////////////////////////////////////////////////////////
  const Count_T& STDAIR_Service::
  getActualTotalNumberOfEventsToBeGenerated() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the dedicated command
    const Count_T& oActualTotalNumberOfEventsToBeGenerated =
      lQueue.getActualTotalNbOfEvents();

    //
    return oActualTotalNumberOfEventsToBeGenerated;
  }

  // ////////////////////////////////////////////////////////////////////
  const Count_T& STDAIR_Service::
  getActualTotalNumberOfEventsToBeGenerated (const EventType::EN_EventType& iType) const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the dedicated command
    const Count_T& oActualTotalNumberOfEventsToBeGenerated =
      lQueue.getActualTotalNbOfEvents (iType);

    //
    return oActualTotalNumberOfEventsToBeGenerated;
  }

  // ////////////////////////////////////////////////////////////////////
  EventStruct STDAIR_Service::popEvent() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Extract the next event from the queue
    const EventStruct& oEventStruct = lQueue.popEvent();

    //
    return oEventStruct;
  }

  // ////////////////////////////////////////////////////////////////////
  bool STDAIR_Service::isQueueDone() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Calculates whether the event queue has been fully emptied
    const bool isQueueDone = lQueue.isQueueDone();

    //
    return isQueueDone;
  }

  // ////////////////////////////////////////////////////////////////////
  void STDAIR_Service::reset() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the event queue object
    lQueue.reset();
  }

}
<commit_msg>[Dev] Removed unused (STDAIR_Service) variable.<commit_after>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
#include <sstream>
// StdAir
#include <stdair/stdair_types.hpp>
#include <stdair/basic/BasChronometer.hpp>
#include <stdair/bom/BomManager.hpp>
#include <stdair/bom/BomDisplay.hpp>
#include <stdair/bom/BomRoot.hpp>
#include <stdair/bom/EventQueue.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/bom/BookingRequestStruct.hpp>
#include <stdair/command/CmdBomManager.hpp>
#include <stdair/service/FacSupervisor.hpp>
#include <stdair/service/FacSTDAIRServiceContext.hpp>
#include <stdair/service/STDAIR_ServiceContext.hpp>
#include <stdair/service/Logger.hpp>
#include <stdair/service/DBSessionManager.hpp>
#include <stdair/STDAIR_Service.hpp>

namespace stdair {

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::STDAIR_Service() : _stdairServiceContext (NULL) {

    // Initialise the service context
    initServiceContext();

    // Initialise the (remaining of the) context
    init();
  }

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::STDAIR_Service (const STDAIR_Service& iService)
    : _stdairServiceContext (NULL) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::STDAIR_Service (const BasLogParams& iLogParams)
    : _stdairServiceContext (NULL) {

    // Initialise the service context
    initServiceContext();

    // Set the log file
    logInit (iLogParams);

    // Initialise the (remaining of the) context
    init();
  }

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::STDAIR_Service (const BasLogParams& iLogParams,
                                  const BasDBParams& iDBParams)
    : _stdairServiceContext (NULL) {

    // Initialise the service context
    initServiceContext();

    // Set the log file
    logInit (iLogParams);

    // Create a database session
    dbInit (iDBParams);

    // Initialise the (remaining of the) context
    init();
  }

  // //////////////////////////////////////////////////////////////////////
  STDAIR_Service::~STDAIR_Service() {
    // Delete/Clean all the objects from memory
    finalise();
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::initServiceContext() {
    // Initialise the service context
    STDAIR_ServiceContext& lSTDAIR_ServiceContext =
      FacSTDAIRServiceContext::instance().create();

    // Store the stdair service context
    _stdairServiceContext = &lSTDAIR_ServiceContext;
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::logInit (const BasLogParams& iLogParams) {
    Logger::init (iLogParams);
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::dbInit (const BasDBParams& iDBParams) {
    DBSessionManager::init (iDBParams);

    // Store the database parameters into the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;
    lSTDAIR_ServiceContext.setDBParams (iDBParams);
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::init() {
  }

  // //////////////////////////////////////////////////////////////////////
  BomRoot& STDAIR_Service::getBomRoot() const {
    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;
    return lSTDAIR_ServiceContext.getBomRoot();
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue& STDAIR_Service::getEventQueue() const {
    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;
    return lSTDAIR_ServiceContext.getEventQueue();
  }

  // //////////////////////////////////////////////////////////////////////
  BasLogParams STDAIR_Service::getLogParams() const {
    return Logger::getLogParams();
  }

  // //////////////////////////////////////////////////////////////////////
  const BasDBParams& STDAIR_Service::getDBParams() const {
    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;
    return lSTDAIR_ServiceContext.getDBParams();
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::buildSampleBom (const bool isForRMOL,
                                       const CabinCapacity_T iCabinCapacity ) {
    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the BOM tree root
    BomRoot& lBomRoot = lSTDAIR_ServiceContext.getBomRoot();

    // Build a sample BOM tree
    if (isForRMOL == true) {
      CmdBomManager::buildSampleBomForRMOL (lBomRoot, iCabinCapacity);
    } else {
      CmdBomManager::buildSampleBom (lBomRoot);
    }
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::buildSampleBomForFareQuoter () {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the BOM tree root
    BomRoot& lBomRoot = lSTDAIR_ServiceContext.getBomRoot();

    // Build a sample BOM tree
    CmdBomManager::buildSampleBomForFareQuoter (lBomRoot);
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::
  buildSampleTravelSolutionForPricing (TravelSolutionList_T& ioTravelSolutionList) {
    // Build a sample list of travel solution structures
    CmdBomManager::buildSampleTravelSolutionForPricing (ioTravelSolutionList);
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::
  buildSampleTravelSolutions (TravelSolutionList_T& ioTravelSolutionList) {
    // Build a sample list of travel solution structures
    CmdBomManager::buildSampleTravelSolutions (ioTravelSolutionList);
  }

  // //////////////////////////////////////////////////////////////////////
  BookingRequestStruct STDAIR_Service::
  buildSampleBookingRequest (const bool isForCRS) {

    // Build a sample booking request structure
    if (isForCRS == true) {
      return CmdBomManager::buildSampleBookingRequestForCRS();
    }

    return CmdBomManager::buildSampleBookingRequest();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string STDAIR_Service::csvDisplay() const {
    std::ostringstream oStr;

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    const STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the BOM tree root
    BomRoot& lBomRoot = lSTDAIR_ServiceContext.getBomRoot();

    // Dump the content of the whole BOM tree into the string
    BomDisplay::csvDisplay (oStr, lBomRoot);

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string STDAIR_Service::
  csvDisplay (const TravelSolutionList_T& iTravelSolutionList) const {

    // Dump the content of the whole list of travel solutions into the string
    std::ostringstream oStr;
    BomDisplay::csvDisplay (oStr, iTravelSolutionList);

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  void STDAIR_Service::finalise() {
    // Clean all the objects
    FacSupervisor::cleanAll();
  }

  // ////////////////////////////////////////////////////////////////////
  const Count_T& STDAIR_Service::
  getExpectedTotalNumberOfEventsToBeGenerated() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the dedicated command
    const Count_T& oExpectedTotalNumberOfEventsToBeGenerated =
      lQueue.getExpectedTotalNbOfEvents();

    //
    return oExpectedTotalNumberOfEventsToBeGenerated;
  }

  // ////////////////////////////////////////////////////////////////////
  const Count_T& STDAIR_Service::
  getExpectedTotalNumberOfEventsToBeGenerated (const EventType::EN_EventType& iType) const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the dedicated command
    const Count_T& oExpectedTotalNumberOfEventsToBeGenerated =
      lQueue.getExpectedTotalNbOfEvents (iType);

    //
    return oExpectedTotalNumberOfEventsToBeGenerated;
  }

  // ////////////////////////////////////////////////////////////////////
  const Count_T& STDAIR_Service::
  getActualTotalNumberOfEventsToBeGenerated() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the dedicated command
    const Count_T& oActualTotalNumberOfEventsToBeGenerated =
      lQueue.getActualTotalNbOfEvents();

    //
    return oActualTotalNumberOfEventsToBeGenerated;
  }

  // ////////////////////////////////////////////////////////////////////
  const Count_T& STDAIR_Service::
  getActualTotalNumberOfEventsToBeGenerated (const EventType::EN_EventType& iType) const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the dedicated command
    const Count_T& oActualTotalNumberOfEventsToBeGenerated =
      lQueue.getActualTotalNbOfEvents (iType);

    //
    return oActualTotalNumberOfEventsToBeGenerated;
  }

  // ////////////////////////////////////////////////////////////////////
  EventStruct STDAIR_Service::popEvent() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Extract the next event from the queue
    const EventStruct& oEventStruct = lQueue.popEvent();

    //
    return oEventStruct;
  }

  // ////////////////////////////////////////////////////////////////////
  bool STDAIR_Service::isQueueDone() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    const EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Calculates whether the event queue has been fully emptied
    const bool isQueueDone = lQueue.isQueueDone();

    //
    return isQueueDone;
  }

  // ////////////////////////////////////////////////////////////////////
  void STDAIR_Service::reset() const {

    // Retrieve the StdAir service context
    assert (_stdairServiceContext != NULL);
    STDAIR_ServiceContext& lSTDAIR_ServiceContext = *_stdairServiceContext;

    // Retrieve the event queue object instance
    EventQueue& lQueue = lSTDAIR_ServiceContext.getEventQueue();

    // Delegate the call to the event queue object
    lQueue.reset();
  }

}
<|endoftext|>


<commit_before>#include <CppUTest/TestHarness.h>
#include <CppUTestExt/MockSupport.h>

#include "../can_datagram.h"
#include "../config.h"
#include "mocks/can_interface_mock.h"
#include "../can_interface.h"
#include "../command.h"
#include <cstdio>

void read_eval(can_datagram_t *input, can_datagram_t *output, bootloader_config_t *config, command_t *commands, int command_len)
{
    uint32_t message_id;
    uint8_t message[8];
    int len, i;

    len = can_interface_read_message(&message_id, message);

    for (i = 0; i < len; ++i) {
        can_datagram_input_byte(input, message[i]);
    }

    if (can_datagram_is_valid(input)) {
        for (i = 0; i < input->destination_nodes_len; ++i) {
            if (input->destination_nodes[i] == config->ID){
                len = protocol_execute_command((char *)input->data, input->data_len, commands, command_len, (char *)output->data, output->data_len, config);

                /* Checks if there was any error. */
                if (len < 0) {
                    return;
                }

                output->data_len = len;
            }
        }

        if (output->data_len > 0) {
            output->destination_nodes_len = 1;
            output->crc = can_datagram_compute_crc(output);
        }
    }
}

static void mock_command(int argc, cmp_ctx_t *arg_context, cmp_ctx_t *out_context, bootloader_config_t *config)
{
    mock().actualCall("command");
}

TEST_GROUP(IntegrationTesting)
{
    can_datagram_t input_datagram;
    uint8_t input_datagram_destinations[10];
    uint8_t input_datagram_data[1000];

    can_datagram_t output_datagram;
    uint8_t output_datagram_destinations[10];
    uint8_t output_datagram_data[1000];

    bootloader_config_t config;
    command_t commands[1];

    void setup(void)
    {
        can_datagram_init(&input_datagram);
        can_datagram_set_address_buffer(&input_datagram, input_datagram_destinations);
        can_datagram_set_data_buffer(&input_datagram, input_datagram_data, sizeof input_datagram_data);

        can_datagram_init(&output_datagram);
        can_datagram_set_address_buffer(&output_datagram, output_datagram_destinations);
        can_datagram_set_data_buffer(&output_datagram, output_datagram_data, sizeof output_datagram_data);

        // Loads default config for testing
        config.ID = 0x01;

        commands[0].index = 1;
        commands[0].callback = mock_command;
    }

    void teardown(void)
    {
        mock().clear();
    }
};

TEST(IntegrationTesting, CanReadWholeDatagram)
{
    uint8_t message[] = {
        0x01,
        0x9e, 0x5b, 0x06, 0xb8,// CRC
        0x01,
        0x01, // dest nodes
        0x0, 0x0, 0x0, 0x1,
        0x1 // data
    };

    can_mock_message(0x0, &message[0], 8);
    read_eval(&input_datagram, &output_datagram, &config, NULL, 0);
    mock().checkExpectations();

    can_mock_message(0x0, &message[8], 4);
    read_eval(&input_datagram, &output_datagram, &config, NULL, 0);
    mock().checkExpectations();

    CHECK_TRUE(can_datagram_is_valid(&input_datagram));
}

TEST(IntegrationTesting, ExecutesCommand)
{
    uint8_t message[] = {
        0x01, // protocol version
        0x62, 0x67, 0x01, 0xfa,
        0x01,
        0x01, // dest nodes
        0x0, 0x0, 0x0, 0x2,
        0x1, 0x1 // data
    };

    can_mock_message(0x0, &message[0], 8);
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);
    mock().checkExpectations();

    can_mock_message(0x0, &message[8], 5);
    mock().expectOneCall("command");
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);
    mock().checkExpectations();
}

TEST(IntegrationTesting, ExecutesIfWeAreInMultiCast)
{
    uint8_t message[] = {
        0x01, // protocol version
        0x99, 0x8c, 0x64, 0xe8,
        0x02,
        0x01, 0x12, // dest nodes
        0x0, 0x0, 0x0, 0x2,
        0x1, 0x1 // data
    };

    config.ID = 0x12;

    can_mock_message(0x0, &message[0], 8);
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);
    mock().checkExpectations();

    can_mock_message(0x0, &message[8], 6);
    mock().expectOneCall("command");
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);
    mock().checkExpectations();
}

static void command_output(int argc, cmp_ctx_t *arg_context, cmp_ctx_t *out_context, bootloader_config_t *config)
{
    cmp_write_str(out_context, "hello", 5);
}

TEST(IntegrationTesting, OutputDatagramIsValid)
{
    uint8_t message[] = {
        0x01,
        0x62, 0x67, 0x01, 0xfa,// CRC
        0x01,
        0x01, // dest nodes
        0x0, 0x0, 0x0, 0x2,
        0x1, 0x1 // data
    };

    commands[0].callback = command_output;

    can_mock_message(0x0, &message[0], 8);
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);

    can_mock_message(0x0, &message[8], 5);
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);

    // Check that the data lenght is correct
    CHECK_EQUAL(6, output_datagram.data_len);
    CHECK_TRUE(can_datagram_is_valid(&output_datagram));
}
<commit_msg>Bypass CRC check in integration testing<commit_after>#include <CppUTest/TestHarness.h>
#include <CppUTestExt/MockSupport.h>

#include "../can_datagram.h"
#include "../config.h"
#include "mocks/can_interface_mock.h"
#include "../can_interface.h"
#include "../command.h"
#include <cstdio>

void read_eval(can_datagram_t *input, can_datagram_t *output, bootloader_config_t *config, command_t *commands, int command_len)
{
    uint32_t message_id;
    uint8_t message[8];
    int len, i;

    len = can_interface_read_message(&message_id, message);

    for (i = 0; i < len; ++i) {
        can_datagram_input_byte(input, message[i]);
    }

    // Bypass CRC check
    input->crc = can_datagram_compute_crc(input);

    if (can_datagram_is_valid(input)) {
        for (i = 0; i < input->destination_nodes_len; ++i) {
            if (input->destination_nodes[i] == config->ID){
                len = protocol_execute_command((char *)input->data, input->data_len, commands, command_len, (char *)output->data, output->data_len, config);

                /* Checks if there was any error. */
                if (len < 0) {
                    return;
                }

                output->data_len = len;
            }
        }

        if (output->data_len > 0) {
            output->destination_nodes_len = 1;
            output->crc = can_datagram_compute_crc(output);
        }
    }
}

static void mock_command(int argc, cmp_ctx_t *arg_context, cmp_ctx_t *out_context, bootloader_config_t *config)
{
    mock().actualCall("command");
}

TEST_GROUP(IntegrationTesting)
{
    can_datagram_t input_datagram;
    uint8_t input_datagram_destinations[10];
    uint8_t input_datagram_data[1000];

    can_datagram_t output_datagram;
    uint8_t output_datagram_destinations[10];
    uint8_t output_datagram_data[1000];

    bootloader_config_t config;
    command_t commands[1];

    void setup(void)
    {
        can_datagram_init(&input_datagram);
        can_datagram_set_address_buffer(&input_datagram, input_datagram_destinations);
        can_datagram_set_data_buffer(&input_datagram, input_datagram_data, sizeof input_datagram_data);

        can_datagram_init(&output_datagram);
        can_datagram_set_address_buffer(&output_datagram, output_datagram_destinations);
        can_datagram_set_data_buffer(&output_datagram, output_datagram_data, sizeof output_datagram_data);

        // Loads default config for testing
        config.ID = 0x01;

        commands[0].index = 1;
        commands[0].callback = mock_command;
    }

    void teardown(void)
    {
        mock().clear();
    }
};

TEST(IntegrationTesting, CanReadWholeDatagram)
{
    uint8_t message[] = {
        0x01,
        0x00, 0x00, 0x00, 0x00, // CRC
        0x01,
        0x01, // dest nodes
        0x0, 0x0, 0x0, 0x1,
        0x1 // data
    };

    can_mock_message(0x0, &message[0], 8);
    read_eval(&input_datagram, &output_datagram, &config, NULL, 0);
    mock().checkExpectations();

    can_mock_message(0x0, &message[8], 4);
    read_eval(&input_datagram, &output_datagram, &config, NULL, 0);
    mock().checkExpectations();

    CHECK_TRUE(can_datagram_is_valid(&input_datagram));
}

TEST(IntegrationTesting, ExecutesCommand)
{
    uint8_t message[] = {
        0x01, // protocol version
        0x00, 0x00, 0x00, 0x00, // CRC
        0x01,
        0x01, // dest nodes
        0x0, 0x0, 0x0, 0x2,
        0x1, 0x1 // data
    };

    can_mock_message(0x0, &message[0], 8);
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);
    mock().checkExpectations();

    can_mock_message(0x0, &message[8], 5);
    mock().expectOneCall("command");
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);
    mock().checkExpectations();
}

TEST(IntegrationTesting, ExecutesIfWeAreInMultiCast)
{
    uint8_t message[] = {
        0x01, // protocol version
        0x00, 0x00, 0x00, 0x00, // CRC
        0x02,
        0x01, 0x12, // dest nodes
        0x0, 0x0, 0x0, 0x2,
        0x1, 0x1 // data
    };

    config.ID = 0x12;

    can_mock_message(0x0, &message[0], 8);
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);
    mock().checkExpectations();

    can_mock_message(0x0, &message[8], 6);
    mock().expectOneCall("command");
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);
    mock().checkExpectations();
}

static void command_output(int argc, cmp_ctx_t *arg_context, cmp_ctx_t *out_context, bootloader_config_t *config)
{
    cmp_write_str(out_context, "hello", 5);
}

TEST(IntegrationTesting, OutputDatagramIsValid)
{
    uint8_t message[] = {
        0x01,
        0x00, 0x00, 0x00, 0x00, // CRC
        0x01,
        0x01, // dest nodes
        0x0, 0x0, 0x0, 0x2,
        0x1, 0x1 // data
    };

    commands[0].callback = command_output;

    can_mock_message(0x0, &message[0], 8);
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);

    can_mock_message(0x0, &message[8], 5);
    read_eval(&input_datagram, &output_datagram, &config, commands, 1);

    // Check that the data lenght is correct
    CHECK_EQUAL(6, output_datagram.data_len);
    CHECK_TRUE(can_datagram_is_valid(&output_datagram));
}
<|endoftext|>