<commit_before>// Author: Don Sanders <sanders@kde.org>
// License GPL

#include <config.h>

#include "kmstartup.h"

#include "kmkernel.h" //control center

#include <klocale.h>
#include <ksimpleconfig.h>
#include <kstandarddirs.h>
#include <kmessagebox.h>
#include <dcopclient.h>
#include <kcrash.h>
#include <kglobal.h>

#include <errno.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#undef Status // stupid X headers

extern "C" {

// Crash recovery signal handler
void kmsignalHandler(int sigId)
{
  kmsetSignalHandler(SIG_DFL);
  fprintf(stderr, "*** KMail got signal %d (Exiting)\n", sigId);
  // try to cleanup all windows
  if (kmkernel) kmkernel->dumpDeadLetters();
  ::exit(-1); //
}

// Crash recovery signal handler
void kmcrashHandler(int sigId)
{
  kmsetSignalHandler(SIG_DFL);
  fprintf(stderr, "*** KMail got signal %d (Crashing)\n", sigId);
  // try to cleanup all windows
  kmkernel->dumpDeadLetters();
  // Return to DrKonqi.
}
//-----------------------------------------------------------------------------

void kmsetSignalHandler(void (*handler)(int))
{
  signal(SIGKILL, handler);
  signal(SIGTERM, handler);
  signal(SIGHUP,  handler);
  KCrash::setEmergencySaveFunction(kmcrashHandler);
}

}
//-----------------------------------------------------------------------------

namespace {
  QString getMyHostName() {
    char hostNameC[256];
    // null terminate this C string
    hostNameC[255] = 0;
    // set the string to 0 length if gethostname fails
    if(gethostname(hostNameC, 255))
      hostNameC[0] = 0;
    return QString::fromLocal8Bit(hostNameC);
  }
} // anon namespace

namespace KMail {

void checkConfigUpdates() {
  static const char * const updates[] = {
    "9",
    "3.1-update-identities",
    "3.1-use-identity-uoids",
    "3.1-new-mail-notification",
    "3.2-update-loop-on-goto-unread-settings",
    "3.1.4-dont-use-UOID-0-for-any-identity",
    "3.2-misc",
    "3.2-moves",
    "3.3-use-ID-for-accounts",
    "3.3-update-filter-rules"
  };
  static const int numUpdates = sizeof updates / sizeof *updates;

  KConfig * config = KMKernel::config();
  KConfigGroup startup( config, "Startup" );
  const int configUpdateLevel = startup.readNumEntry( "update-level", 0 );
  if ( configUpdateLevel == numUpdates ) // Optimize for the common case that everything is OK
    return;

  for ( int i = 0 ; i < numUpdates ; ++i )
    config->checkUpdate( updates[i], "kmail.upd" );
  startup.writeEntry( "update-level", numUpdates );
}

void lockOrDie() {
// Check and create a lock file to prevent concurrent access to kmail files
  QString lockLocation = locateLocal("data", "kmail/lock");
  KSimpleConfig config(lockLocation);
  int oldPid = config.readNumEntry("pid", -1);
  const QString oldHostName = config.readEntry("hostname");
  const QString hostName = getMyHostName();
  bool first_instance = false;
  if ( oldPid == -1 )
      first_instance = true;
  // check if the lock file is stale by trying to see if
  // the other pid is currently running.
  // Not 100% correct but better safe than sorry
  else if (hostName == oldHostName && oldPid != getpid()) {
      if ( kill(oldPid, 0) == -1 )
          first_instance = ( errno == ESRCH );
  }

  if ( !first_instance )
  {
    QString msg( i18n("<qt>"
       "To prevent major damage to your existing mails KMail has "
       "been locked by another instance of KMail which seems to run "
       "on host %1 with process id (PID) %2.

"
       "In case you are really sure that this instance is not running any "
       "longer, press Continue to delete the stale lock file and "
       "restart KMail afterwards again.

"
       "If unsure, press Cancel."
       "</qt>").arg(oldHostName).arg(oldPid) );

    if (KMessageBox::Continue == KMessageBox::warningContinueCancel(0,
         msg, i18n("Warning"), KStdGuiItem::cont(), QString::null,
         KMessageBox::Dangerous) ) {
       // remove stale lock file entry
       config.writeEntry("pid", -1);
       config.sync();
    }
    exit(1);
  }

  config.writeEntry("pid", getpid());
  config.writeEntry("hostname", hostName);
  config.sync();
}

void insertLibraryCatalogues() {
  static const char * const catalogues[] = {
    "libkdenetwork",
    "libkdepim",
    "libktnef",
    "libkcal",
    "libksieve",
  };

  KLocale * l = KGlobal::locale();
  for ( unsigned int i = 0 ; i < sizeof catalogues / sizeof *catalogues ; ++i )
    l->insertCatalogue( catalogues[i] );
}

void cleanup()
{
  const QString lockLocation = locateLocal("data", "kmail/lock");
  KSimpleConfig config(lockLocation);
  config.writeEntry("pid", -1);
  config.sync();
}
}
<commit_msg>Scott is right - "No" is now the default choice. CCMAIL: wheeler@kde.org<commit_after>// Author: Don Sanders <sanders@kde.org>
// License GPL

#include <config.h>

#include "kmstartup.h"

#include "kmkernel.h" //control center

#include <klocale.h>
#include <ksimpleconfig.h>
#include <kstandarddirs.h>
#include <kmessagebox.h>
#include <dcopclient.h>
#include <kcrash.h>
#include <kglobal.h>

#include <errno.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#undef Status // stupid X headers

extern "C" {

// Crash recovery signal handler
void kmsignalHandler(int sigId)
{
  kmsetSignalHandler(SIG_DFL);
  fprintf(stderr, "*** KMail got signal %d (Exiting)\n", sigId);
  // try to cleanup all windows
  if (kmkernel) kmkernel->dumpDeadLetters();
  ::exit(-1); //
}

// Crash recovery signal handler
void kmcrashHandler(int sigId)
{
  kmsetSignalHandler(SIG_DFL);
  fprintf(stderr, "*** KMail got signal %d (Crashing)\n", sigId);
  // try to cleanup all windows
  kmkernel->dumpDeadLetters();
  // Return to DrKonqi.
}
//-----------------------------------------------------------------------------

void kmsetSignalHandler(void (*handler)(int))
{
  signal(SIGKILL, handler);
  signal(SIGTERM, handler);
  signal(SIGHUP,  handler);
  KCrash::setEmergencySaveFunction(kmcrashHandler);
}

}
//-----------------------------------------------------------------------------

namespace {
  QString getMyHostName() {
    char hostNameC[256];
    // null terminate this C string
    hostNameC[255] = 0;
    // set the string to 0 length if gethostname fails
    if(gethostname(hostNameC, 255))
      hostNameC[0] = 0;
    return QString::fromLocal8Bit(hostNameC);
  }
} // anon namespace

namespace KMail {

void checkConfigUpdates() {
  static const char * const updates[] = {
    "9",
    "3.1-update-identities",
    "3.1-use-identity-uoids",
    "3.1-new-mail-notification",
    "3.2-update-loop-on-goto-unread-settings",
    "3.1.4-dont-use-UOID-0-for-any-identity",
    "3.2-misc",
    "3.2-moves",
    "3.3-use-ID-for-accounts",
    "3.3-update-filter-rules"
  };
  static const int numUpdates = sizeof updates / sizeof *updates;

  KConfig * config = KMKernel::config();
  KConfigGroup startup( config, "Startup" );
  const int configUpdateLevel = startup.readNumEntry( "update-level", 0 );
  if ( configUpdateLevel == numUpdates ) // Optimize for the common case that everything is OK
    return;

  for ( int i = 0 ; i < numUpdates ; ++i )
    config->checkUpdate( updates[i], "kmail.upd" );
  startup.writeEntry( "update-level", numUpdates );
}

void lockOrDie() {
// Check and create a lock file to prevent concurrent access to kmail files
  QString lockLocation = locateLocal("data", "kmail/lock");
  KSimpleConfig config(lockLocation);
  int oldPid = config.readNumEntry("pid", -1);
  const QString oldHostName = config.readEntry("hostname");
  const QString hostName = getMyHostName();
  bool first_instance = false;
  if ( oldPid == -1 )
      first_instance = true;
  // check if the lock file is stale by trying to see if
  // the other pid is currently running.
  // Not 100% correct but better safe than sorry
  else if (hostName == oldHostName && oldPid != getpid()) {
      if ( kill(oldPid, 0) == -1 )
          first_instance = ( errno == ESRCH );
  }

  if ( !first_instance )
  {
    QString msg( i18n("<qt>"
       "To prevent major damage to your existing mails KMail has "
       "been locked by another instance of KMail which seems to run "
       "on host %1 with process id (PID) %2.

"
       "In case you are really sure that this instance is not running any "
       "longer, press Yes to delete the stale lock file and "
       "restart KMail afterwards again.
"
       "If unsure, press No.

"
       "Are you sure the other KMail instance has exitted ?"
       "</qt>").arg(oldHostName).arg(oldPid) );

    if ( KMessageBox::Yes == KMessageBox::warningYesNo(0, msg) ) {
       // remove stale lock file entry
       config.writeEntry("pid", -1);
       config.sync();
    }
    exit(1);
  }

  config.writeEntry("pid", getpid());
  config.writeEntry("hostname", hostName);
  config.sync();
}

void insertLibraryCatalogues() {
  static const char * const catalogues[] = {
    "libkdenetwork",
    "libkdepim",
    "libktnef",
    "libkcal",
    "libksieve",
  };

  KLocale * l = KGlobal::locale();
  for ( unsigned int i = 0 ; i < sizeof catalogues / sizeof *catalogues ; ++i )
    l->insertCatalogue( catalogues[i] );
}

void cleanup()
{
  const QString lockLocation = locateLocal("data", "kmail/lock");
  KSimpleConfig config(lockLocation);
  config.writeEntry("pid", -1);
  config.sync();
}
}
<|endoftext|>


<commit_before>#include "regex.hxx"
#include "pexpand.hxx"
#include "pool.hxx"
#include "util/Error.hxx"

#include <inline/compiler.h>

#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>

#include <string.h>
#include <stdlib.h>

class RegexTest : public CppUnit::TestFixture {
    CPPUNIT_TEST_SUITE(RegexTest);
    CPPUNIT_TEST(TestMatch1);
    CPPUNIT_TEST(TestMatch2);
    CPPUNIT_TEST(TestNotAnchored);
    CPPUNIT_TEST(TestAnchored);
    CPPUNIT_TEST(TestExpand);
    CPPUNIT_TEST(TestExpandOptional);
    CPPUNIT_TEST_SUITE_END();

public:
    void TestMatch1() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile(".", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("a"));
        CPPUNIT_ASSERT(r.Match("abc"));
    }

    void TestMatch2() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("..", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(!r.Match("a"));
        CPPUNIT_ASSERT(r.Match("abc"));
    }

    void TestNotAnchored() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("/foo/", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("/foo/"));
        CPPUNIT_ASSERT(r.Match("/foo/bar"));
        CPPUNIT_ASSERT(r.Match("foo/foo/"));
    }

    void TestAnchored() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("/foo/", true, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("/foo/"));
        CPPUNIT_ASSERT(r.Match("/foo/bar"));
        CPPUNIT_ASSERT(!r.Match("foo/foo/"));
    }

    void TestExpand() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("^/foo/(\\w+)/([^/]+)/(.*)$", false, true,
                                 IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());

        CPPUNIT_ASSERT(!r.Match("a"));

        auto match_info = r.MatchCapture("/foo/bar/a/b/c.html");
        CPPUNIT_ASSERT(match_info.IsDefined());

        struct pool *pool = pool_new_libc(nullptr, "root");
        auto e = expand_string(pool, "\\1-\\2-\\3-\\\\", match_info,
                               IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a-b/c.html-\\") == 0);

        match_info = r.MatchCapture("/foo/bar/a/b/");
        CPPUNIT_ASSERT(match_info.IsDefined());

        e = expand_string(pool, "\\1-\\2-\\3-\\\\", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a-b/-\\") == 0);

        match_info = r.MatchCapture("/foo/bar/a%20b/c%2520.html");
        CPPUNIT_ASSERT(match_info.IsDefined());

        e = expand_string_unescaped(pool, "\\1-\\2-\\3", match_info,
                                    IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a b-c%20.html") == 0);

        e = expand_string_unescaped(pool, "\\4", match_info, IgnoreError());
        CPPUNIT_ASSERT(e == nullptr);

        pool_unref(pool);
    }

    void TestExpandOptional() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("^(a)(b)?(c)$", true, true, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());

        auto match_info = r.MatchCapture("abc");
        CPPUNIT_ASSERT(match_info.IsDefined());
        struct pool *pool = pool_new_libc(nullptr, "root");
        auto e = expand_string(pool, "\\1-\\2-\\3", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "a-b-c") == 0);

        match_info = r.MatchCapture("ac");
        CPPUNIT_ASSERT(match_info.IsDefined());
        e = expand_string(pool, "\\1-\\2-\\3", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "a--c") == 0);

        pool_unref(pool);
    }
};

CPPUNIT_TEST_SUITE_REGISTRATION(RegexTest);

int
main(gcc_unused int argc, gcc_unused char **argv)
{
    CppUnit::Test *suite =
        CppUnit::TestFactoryRegistry::getRegistry().makeTest();

    CppUnit::TextUi::TestRunner runner;
    runner.addTest(suite);

    runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(),
                                                       std::cerr));
    bool success = runner.run();

    pool_recycler_clear();
    return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
<commit_msg>test/t_regex: add test for mismatching optional last capture<commit_after>#include "regex.hxx"
#include "pexpand.hxx"
#include "pool.hxx"
#include "util/Error.hxx"

#include <inline/compiler.h>

#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>

#include <string.h>
#include <stdlib.h>

class RegexTest : public CppUnit::TestFixture {
    CPPUNIT_TEST_SUITE(RegexTest);
    CPPUNIT_TEST(TestMatch1);
    CPPUNIT_TEST(TestMatch2);
    CPPUNIT_TEST(TestNotAnchored);
    CPPUNIT_TEST(TestAnchored);
    CPPUNIT_TEST(TestExpand);
    CPPUNIT_TEST(TestExpandOptional);
    CPPUNIT_TEST(TestExpandOptionalLast);
    CPPUNIT_TEST_SUITE_END();

public:
    void TestMatch1() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile(".", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("a"));
        CPPUNIT_ASSERT(r.Match("abc"));
    }

    void TestMatch2() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("..", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(!r.Match("a"));
        CPPUNIT_ASSERT(r.Match("abc"));
    }

    void TestNotAnchored() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("/foo/", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("/foo/"));
        CPPUNIT_ASSERT(r.Match("/foo/bar"));
        CPPUNIT_ASSERT(r.Match("foo/foo/"));
    }

    void TestAnchored() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("/foo/", true, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("/foo/"));
        CPPUNIT_ASSERT(r.Match("/foo/bar"));
        CPPUNIT_ASSERT(!r.Match("foo/foo/"));
    }

    void TestExpand() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("^/foo/(\\w+)/([^/]+)/(.*)$", false, true,
                                 IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());

        CPPUNIT_ASSERT(!r.Match("a"));

        auto match_info = r.MatchCapture("/foo/bar/a/b/c.html");
        CPPUNIT_ASSERT(match_info.IsDefined());

        struct pool *pool = pool_new_libc(nullptr, "root");
        auto e = expand_string(pool, "\\1-\\2-\\3-\\\\", match_info,
                               IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a-b/c.html-\\") == 0);

        match_info = r.MatchCapture("/foo/bar/a/b/");
        CPPUNIT_ASSERT(match_info.IsDefined());

        e = expand_string(pool, "\\1-\\2-\\3-\\\\", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a-b/-\\") == 0);

        match_info = r.MatchCapture("/foo/bar/a%20b/c%2520.html");
        CPPUNIT_ASSERT(match_info.IsDefined());

        e = expand_string_unescaped(pool, "\\1-\\2-\\3", match_info,
                                    IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a b-c%20.html") == 0);

        e = expand_string_unescaped(pool, "\\4", match_info, IgnoreError());
        CPPUNIT_ASSERT(e == nullptr);

        pool_unref(pool);
    }

    void TestExpandOptional() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("^(a)(b)?(c)$", true, true, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());

        auto match_info = r.MatchCapture("abc");
        CPPUNIT_ASSERT(match_info.IsDefined());
        struct pool *pool = pool_new_libc(nullptr, "root");
        auto e = expand_string(pool, "\\1-\\2-\\3", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "a-b-c") == 0);

        match_info = r.MatchCapture("ac");
        CPPUNIT_ASSERT(match_info.IsDefined());
        e = expand_string(pool, "\\1-\\2-\\3", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "a--c") == 0);

        pool_unref(pool);
    }

    void TestExpandOptionalLast() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("^(a)(b)?(c)?$", true, true, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());

        auto match_info = r.MatchCapture("abc");
        CPPUNIT_ASSERT(match_info.IsDefined());
        struct pool *pool = pool_new_libc(nullptr, "root");
        auto e = expand_string(pool, "\\1-\\2-\\3", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "a-b-c") == 0);

        match_info = r.MatchCapture("ac");
        CPPUNIT_ASSERT(match_info.IsDefined());
        e = expand_string(pool, "\\1-\\2-\\3", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "a--c") == 0);

        match_info = r.MatchCapture("ab");
        CPPUNIT_ASSERT(match_info.IsDefined());
        e = expand_string(pool, "\\1-\\2-\\3", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "a-b-") == 0);

        pool_unref(pool);
    }
};

CPPUNIT_TEST_SUITE_REGISTRATION(RegexTest);

int
main(gcc_unused int argc, gcc_unused char **argv)
{
    CppUnit::Test *suite =
        CppUnit::TestFactoryRegistry::getRegistry().makeTest();

    CppUnit::TextUi::TestRunner runner;
    runner.addTest(suite);

    runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(),
                                                       std::cerr));
    bool success = runner.run();

    pool_recycler_clear();
    return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */
#include <pcl/console/print.h>
#if defined WIN32 && defined _MSC_VER
# include <windows.h>

DWORD convertAttributesColor(int attribute, int fg, int bg=-1)
{
    static DWORD wAttributes[7]  = { 0, //TT_RESET
                                     FOREGROUND_INTENSITY , // TT_BRIGHT
                                     0, // TT_DIM
                                     COMMON_LVB_UNDERSCORE, // TT_UNDERLINE
                                     0, // TT_BLINK     = 4,
                                     COMMON_LVB_REVERSE_VIDEO, // TT_REVERSE
                                     0 //TT_HIDDEN    = 8
                                    };
    static DWORD wFgColors[8]  = { 0, // TT_BLACK
                                   FOREGROUND_RED, // TT_RED
                                   FOREGROUND_GREEN , // TT_GREEN
                                   FOREGROUND_GREEN | FOREGROUND_RED , // TT_YELLOW
                                   FOREGROUND_BLUE , // TT_BLUE
                                   FOREGROUND_RED | FOREGROUND_BLUE , // TT_MAGENTA
                                   FOREGROUND_GREEN | FOREGROUND_BLUE, // TT_CYAN
                                   FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED // TT_WHITE
                                 };
    static DWORD wBgColors[8]  = { 0, // TT_BLACK
                                   BACKGROUND_RED, // TT_RED
                                   BACKGROUND_GREEN , // TT_GREEN
                                   BACKGROUND_GREEN | BACKGROUND_BLUE , // TT_YELLOW
                                   BACKGROUND_BLUE , // TT_BLUE
                                   BACKGROUND_RED | BACKGROUND_BLUE , // TT_MAGENTA
                                   BACKGROUND_GREEN | BACKGROUND_BLUE, // TT_CYAN
                                   BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED // TT_WHITE
                                 };

    if(bg < 0)
        return wAttributes[attribute] | wFgColors[fg];
    else
        return wAttributes[attribute] | wFgColors[fg] | wBgColors[bg];

}

#endif

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::change_text_color (FILE *stream, int attribute, int fg, int bg)
{
#ifdef WIN32
  HANDLE h = GetStdHandle((stream == stdout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
  SetConsoleTextAttribute(h, convertAttributesColor(attribute, fg, bg));
#else
  char command[13];
  // Command is the control command to the terminal
  sprintf (command, "%c[%d;%d;%dm", 0x1B, attribute, fg + 30, bg + 40);
  fprintf (stream, "%s", command);
#endif
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::change_text_color (FILE *stream, int attribute, int fg)
{
#ifdef WIN32
  HANDLE h = GetStdHandle((stream == stdout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
  SetConsoleTextAttribute(h, convertAttributesColor(attribute, fg));
#else
  char command[13];
  // Command is the control command to the terminal
  sprintf (command, "%c[%d;%dm", 0x1B, attribute, fg + 30);
  fprintf (stream, "%s", command);
#endif
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::reset_text_color (FILE *stream)
{
#ifdef WIN32
  HANDLE h = GetStdHandle((stream == stdout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
  SetConsoleTextAttribute(h, convertAttributesColor(0, TT_WHITE, TT_BLACK));
#else
  char command[13];
  // Command is the control command to the terminal
  sprintf (command, "%c[0;m", 0x1B);
  fprintf (stream, "%s", command);
#endif
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_color (FILE *stream, int attr, int fg, const char *format, ...)
{
  change_text_color (stream, attr, fg);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_info (const char *format, ...)
{
  reset_text_color (stdout);

  va_list ap;

  va_start (ap, format);
  vfprintf (stdout, format, ap);
  va_end (ap);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_info (FILE *stream, const char *format, ...)
{
  reset_text_color (stream);

  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_highlight (const char *format, ...)
{
  change_text_color (stdout, TT_BRIGHT, TT_GREEN);
  fprintf (stdout, "> ");
  reset_text_color (stdout);

  va_list ap;

  va_start (ap, format);
  vfprintf (stdout, format, ap);
  va_end (ap);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_highlight (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_BRIGHT, TT_GREEN);
  fprintf (stream, "> ");
  reset_text_color (stream);

  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_error (const char *format, ...)
{
  change_text_color (stderr, TT_BRIGHT, TT_RED);
  va_list ap;

  va_start (ap, format);
  vfprintf (stderr, format, ap);
  va_end (ap);

  reset_text_color (stderr);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_error (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_BRIGHT, TT_RED);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_warn (const char *format, ...)
{
  change_text_color (stderr, TT_BRIGHT, TT_YELLOW);
  va_list ap;

  va_start (ap, format);
  vfprintf (stderr, format, ap);
  va_end (ap);

  reset_text_color (stderr);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_warn (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_BRIGHT, TT_YELLOW);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_value (const char *format, ...)
{
  change_text_color (stdout, TT_RESET, TT_CYAN);
  va_list ap;

  va_start (ap, format);
  vfprintf (stdout, format, ap);
  va_end (ap);

  reset_text_color (stdout);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_value (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_RESET, TT_CYAN);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_debug (const char *format, ...)
{
  change_text_color (stdout, TT_RESET, TT_GREEN);
  va_list ap;

  va_start (ap, format);
  vfprintf (stdout, format, ap);
  va_end (ap);

  reset_text_color (stdout);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_debug (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_RESET, TT_GREEN);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

<commit_msg>Update: apply Alessio patch: COMMON_LVB_UNDERSCORE undefined in MinGW<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */
#include <pcl/console/print.h>
#if defined WIN32
# include <windows.h>

DWORD convertAttributesColor(int attribute, int fg, int bg=-1)
{
#if defined _MSC_VER
    static DWORD wAttributes[7]  = { 0, //TT_RESET
                                     FOREGROUND_INTENSITY , // TT_BRIGHT
                                     0, // TT_DIM
                                     COMMON_LVB_UNDERSCORE, // TT_UNDERLINE
                                     0, // TT_BLINK     = 4,
                                     COMMON_LVB_REVERSE_VIDEO, // TT_REVERSE
                                     0 //TT_HIDDEN    = 8
                                    };
#else
   static DWORD wAttributes[7]  = { 0, //TT_RESET
                                     FOREGROUND_INTENSITY , // TT_BRIGHT
                                     0, // TT_DIM
                                     0, // TT_UNDERLINE
                                     0, // TT_BLINK     = 4,
                                     0, // TT_REVERSE
                                     0 //TT_HIDDEN    = 8
                                    };
#endif

    static DWORD wFgColors[8]  = { 0, // TT_BLACK
                                   FOREGROUND_RED, // TT_RED
                                   FOREGROUND_GREEN , // TT_GREEN
                                   FOREGROUND_GREEN | FOREGROUND_RED , // TT_YELLOW
                                   FOREGROUND_BLUE , // TT_BLUE
                                   FOREGROUND_RED | FOREGROUND_BLUE , // TT_MAGENTA
                                   FOREGROUND_GREEN | FOREGROUND_BLUE, // TT_CYAN
                                   FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED // TT_WHITE
                                 };
    static DWORD wBgColors[8]  = { 0, // TT_BLACK
                                   BACKGROUND_RED, // TT_RED
                                   BACKGROUND_GREEN , // TT_GREEN
                                   BACKGROUND_GREEN | BACKGROUND_BLUE , // TT_YELLOW
                                   BACKGROUND_BLUE , // TT_BLUE
                                   BACKGROUND_RED | BACKGROUND_BLUE , // TT_MAGENTA
                                   BACKGROUND_GREEN | BACKGROUND_BLUE, // TT_CYAN
                                   BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED // TT_WHITE
                                 };

    if(bg < 0)
        return wAttributes[attribute] | wFgColors[fg];
    else
        return wAttributes[attribute] | wFgColors[fg] | wBgColors[bg];

}

#endif

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::change_text_color (FILE *stream, int attribute, int fg, int bg)
{
#ifdef WIN32
  HANDLE h = GetStdHandle((stream == stdout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
  SetConsoleTextAttribute(h, convertAttributesColor(attribute, fg, bg));
#else
  char command[13];
  // Command is the control command to the terminal
  sprintf (command, "%c[%d;%d;%dm", 0x1B, attribute, fg + 30, bg + 40);
  fprintf (stream, "%s", command);
#endif
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::change_text_color (FILE *stream, int attribute, int fg)
{
#ifdef WIN32
  HANDLE h = GetStdHandle((stream == stdout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
  SetConsoleTextAttribute(h, convertAttributesColor(attribute, fg));
#else
  char command[13];
  // Command is the control command to the terminal
  sprintf (command, "%c[%d;%dm", 0x1B, attribute, fg + 30);
  fprintf (stream, "%s", command);
#endif
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::reset_text_color (FILE *stream)
{
#ifdef WIN32
  HANDLE h = GetStdHandle((stream == stdout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
  SetConsoleTextAttribute(h, convertAttributesColor(0, TT_WHITE, TT_BLACK));
#else
  char command[13];
  // Command is the control command to the terminal
  sprintf (command, "%c[0;m", 0x1B);
  fprintf (stream, "%s", command);
#endif
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_color (FILE *stream, int attr, int fg, const char *format, ...)
{
  change_text_color (stream, attr, fg);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_info (const char *format, ...)
{
  reset_text_color (stdout);

  va_list ap;

  va_start (ap, format);
  vfprintf (stdout, format, ap);
  va_end (ap);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_info (FILE *stream, const char *format, ...)
{
  reset_text_color (stream);

  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_highlight (const char *format, ...)
{
  change_text_color (stdout, TT_BRIGHT, TT_GREEN);
  fprintf (stdout, "> ");
  reset_text_color (stdout);

  va_list ap;

  va_start (ap, format);
  vfprintf (stdout, format, ap);
  va_end (ap);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_highlight (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_BRIGHT, TT_GREEN);
  fprintf (stream, "> ");
  reset_text_color (stream);

  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_error (const char *format, ...)
{
  change_text_color (stderr, TT_BRIGHT, TT_RED);
  va_list ap;

  va_start (ap, format);
  vfprintf (stderr, format, ap);
  va_end (ap);

  reset_text_color (stderr);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_error (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_BRIGHT, TT_RED);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_warn (const char *format, ...)
{
  change_text_color (stderr, TT_BRIGHT, TT_YELLOW);
  va_list ap;

  va_start (ap, format);
  vfprintf (stderr, format, ap);
  va_end (ap);

  reset_text_color (stderr);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_warn (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_BRIGHT, TT_YELLOW);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_value (const char *format, ...)
{
  change_text_color (stdout, TT_RESET, TT_CYAN);
  va_list ap;

  va_start (ap, format);
  vfprintf (stdout, format, ap);
  va_end (ap);

  reset_text_color (stdout);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_value (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_RESET, TT_CYAN);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_debug (const char *format, ...)
{
  change_text_color (stdout, TT_RESET, TT_GREEN);
  va_list ap;

  va_start (ap, format);
  vfprintf (stdout, format, ap);
  va_end (ap);

  reset_text_color (stdout);
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::print_debug (FILE *stream, const char *format, ...)
{
  change_text_color (stream, TT_RESET, TT_GREEN);
  va_list ap;

  va_start (ap, format);
  vfprintf (stream, format, ap);
  va_end (ap);

  reset_text_color (stream);
}

<|endoftext|>


<commit_before>#include "regex.hxx"
#include "pexpand.hxx"
#include "pool.hxx"
#include "util/Error.hxx"

#include <inline/compiler.h>

#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>

#include <string.h>
#include <stdlib.h>

class RegexTest : public CppUnit::TestFixture {
    CPPUNIT_TEST_SUITE(RegexTest);
    CPPUNIT_TEST(TestMatch1);
    CPPUNIT_TEST(TestMatch2);
    CPPUNIT_TEST(TestNotAnchored);
    CPPUNIT_TEST(TestAnchored);
    CPPUNIT_TEST(TestExpand);
    CPPUNIT_TEST_SUITE_END();

public:
    void TestMatch1() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile(".", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("a"));
        CPPUNIT_ASSERT(r.Match("abc"));
    }

    void TestMatch2() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("..", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(!r.Match("a"));
        CPPUNIT_ASSERT(r.Match("abc"));
    }

    void TestNotAnchored() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("/foo/", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("/foo/"));
        CPPUNIT_ASSERT(r.Match("/foo/bar"));
        CPPUNIT_ASSERT(r.Match("foo/foo/"));
    }

    void TestAnchored() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("/foo/", true, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("/foo/"));
        CPPUNIT_ASSERT(r.Match("/foo/bar"));
        CPPUNIT_ASSERT(!r.Match("foo/foo/"));
    }

    void TestExpand() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("^/foo/(\\w+)/([^/]+)/(.*)$", false, true,
                                 IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());

        CPPUNIT_ASSERT(!r.Match("a"));

        auto match_info = r.MatchCapture("/foo/bar/a/b/c.html");
        CPPUNIT_ASSERT(match_info.IsDefined());

        struct pool *pool = pool_new_libc(nullptr, "root");
        auto e = expand_string(pool, "\\1-\\2-\\3-\\\\", match_info,
                               IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a-b/c.html-\\") == 0);

        match_info = r.MatchCapture("/foo/bar/a/b/");
        CPPUNIT_ASSERT(match_info.IsDefined());

        e = expand_string(pool, "\\1-\\2-\\3-\\\\", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a-b/-\\") == 0);

        match_info = r.MatchCapture("/foo/bar/a%20b/c%2520.html");
        CPPUNIT_ASSERT(match_info.IsDefined());

        e = expand_string_unescaped(pool, "\\1-\\2-\\3", match_info,
                                    IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a b-c%20.html") == 0);

        e = expand_string_unescaped(pool, "\\4", match_info, IgnoreError());
        CPPUNIT_ASSERT(e == nullptr);

        pool_unref(pool);
    }
};

CPPUNIT_TEST_SUITE_REGISTRATION(RegexTest);

int
main(gcc_unused int argc, gcc_unused char **argv)
{
    CppUnit::Test *suite =
        CppUnit::TestFactoryRegistry::getRegistry().makeTest();

    CppUnit::TextUi::TestRunner runner;
    runner.addTest(suite);

    runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(),
                                                       std::cerr));
    bool success = runner.run();

    pool_recycler_clear();
    return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
<commit_msg>test/t_regex: add test for mismatching optional capture<commit_after>#include "regex.hxx"
#include "pexpand.hxx"
#include "pool.hxx"
#include "util/Error.hxx"

#include <inline/compiler.h>

#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>

#include <string.h>
#include <stdlib.h>

class RegexTest : public CppUnit::TestFixture {
    CPPUNIT_TEST_SUITE(RegexTest);
    CPPUNIT_TEST(TestMatch1);
    CPPUNIT_TEST(TestMatch2);
    CPPUNIT_TEST(TestNotAnchored);
    CPPUNIT_TEST(TestAnchored);
    CPPUNIT_TEST(TestExpand);
    CPPUNIT_TEST(TestExpandOptional);
    CPPUNIT_TEST_SUITE_END();

public:
    void TestMatch1() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile(".", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("a"));
        CPPUNIT_ASSERT(r.Match("abc"));
    }

    void TestMatch2() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("..", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(!r.Match("a"));
        CPPUNIT_ASSERT(r.Match("abc"));
    }

    void TestNotAnchored() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("/foo/", false, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("/foo/"));
        CPPUNIT_ASSERT(r.Match("/foo/bar"));
        CPPUNIT_ASSERT(r.Match("foo/foo/"));
    }

    void TestAnchored() {
        UniqueRegex r = UniqueRegex();
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("/foo/", true, false, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());
        CPPUNIT_ASSERT(r.Match("/foo/"));
        CPPUNIT_ASSERT(r.Match("/foo/bar"));
        CPPUNIT_ASSERT(!r.Match("foo/foo/"));
    }

    void TestExpand() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("^/foo/(\\w+)/([^/]+)/(.*)$", false, true,
                                 IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());

        CPPUNIT_ASSERT(!r.Match("a"));

        auto match_info = r.MatchCapture("/foo/bar/a/b/c.html");
        CPPUNIT_ASSERT(match_info.IsDefined());

        struct pool *pool = pool_new_libc(nullptr, "root");
        auto e = expand_string(pool, "\\1-\\2-\\3-\\\\", match_info,
                               IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a-b/c.html-\\") == 0);

        match_info = r.MatchCapture("/foo/bar/a/b/");
        CPPUNIT_ASSERT(match_info.IsDefined());

        e = expand_string(pool, "\\1-\\2-\\3-\\\\", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a-b/-\\") == 0);

        match_info = r.MatchCapture("/foo/bar/a%20b/c%2520.html");
        CPPUNIT_ASSERT(match_info.IsDefined());

        e = expand_string_unescaped(pool, "\\1-\\2-\\3", match_info,
                                    IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "bar-a b-c%20.html") == 0);

        e = expand_string_unescaped(pool, "\\4", match_info, IgnoreError());
        CPPUNIT_ASSERT(e == nullptr);

        pool_unref(pool);
    }

    void TestExpandOptional() {
        UniqueRegex r;
        CPPUNIT_ASSERT(!r.IsDefined());
        CPPUNIT_ASSERT(r.Compile("^(a)(b)?(c)$", true, true, IgnoreError()));
        CPPUNIT_ASSERT(r.IsDefined());

        auto match_info = r.MatchCapture("abc");
        CPPUNIT_ASSERT(match_info.IsDefined());
        struct pool *pool = pool_new_libc(nullptr, "root");
        auto e = expand_string(pool, "\\1-\\2-\\3", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "a-b-c") == 0);

        match_info = r.MatchCapture("ac");
        CPPUNIT_ASSERT(match_info.IsDefined());
        e = expand_string(pool, "\\1-\\2-\\3", match_info, IgnoreError());
        CPPUNIT_ASSERT(e != nullptr);
        CPPUNIT_ASSERT(strcmp(e, "a--c") == 0);

        pool_unref(pool);
    }
};

CPPUNIT_TEST_SUITE_REGISTRATION(RegexTest);

int
main(gcc_unused int argc, gcc_unused char **argv)
{
    CppUnit::Test *suite =
        CppUnit::TestFactoryRegistry::getRegistry().makeTest();

    CppUnit::TextUi::TestRunner runner;
    runner.addTest(suite);

    runner.setOutputter(new CppUnit::CompilerOutputter(&runner.result(),
                                                       std::cerr));
    bool success = runner.run();

    pool_recycler_clear();
    return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
<|endoftext|>


<commit_before>// dune-multiscale
// Copyright Holders: Patrick Henning, Rene Milk
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef SUBGRIDLIST_HH
#define SUBGRIDLIST_HH

#include <boost/noncopyable.hpp>
#include <boost/multi_array.hpp>

#include <dune/common/fmatrix.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/exceptions.hh>
#include <dune/stuff/grid/entity.hh>

#include <dune/multiscale/tools/subgrid_io.hh>
#include <dune/subgrid/subgrid.hh>

#include <dune/fem/quadrature/cachingquadrature.hh>
#include <dune/fem/operator/common/operator.hh>
#include <dune/fem/gridpart/adaptiveleafgridpart.hh>
#include <dune/fem/space/lagrangespace.hh>
#include <dune/fem/function/adaptivefunction.hh>
#include <dune/fem/operator/2order/lagrangematrixsetup.hh>

#include <dune/multiscale/msfem/msfem_traits.hh>
#include <dune/multiscale/msfem/msfem_grid_specifier.hh>

namespace Dune {
namespace Multiscale {
namespace MsFEM {

//! container for cell problem subgrids
class SubGridList : public boost::noncopyable
{
  typedef typename CommonTraits::DiscreteFunctionType HostDiscreteFunctionImp;
  typedef MsFEMTraits::SubGridType SubGridImp;
  typedef MsFEMTraits::MacroMicroGridSpecifierType MacroMicroGridSpecifierImp;

public:
  //! ---------------- typedefs for the HostDiscreteFunctionSpace -----------------------

  typedef MacroMicroGridSpecifierImp MacroMicroGridSpecifierType;
  typedef HostDiscreteFunctionImp HostDiscreteFunctionType;
  //! type of discrete function space
  typedef typename HostDiscreteFunctionType::DiscreteFunctionSpaceType HostDiscreteFunctionSpaceType;
  //! type of grid partition
  typedef typename HostDiscreteFunctionSpaceType::GridPartType HostGridPartType;

  //! type of grid
private:
  typedef typename HostDiscreteFunctionSpaceType::GridType HostGridType;
  typedef typename HostGridType::Traits::LeafIndexSet HostGridLeafIndexSet;
  typedef typename HostDiscreteFunctionSpaceType::IteratorType HostGridEntityIteratorType;
  typedef typename HostGridEntityIteratorType::Entity HostEntityType;
  typedef typename HostEntityType::EntityPointer HostEntityPointerType;
  typedef typename HostEntityType::template Codim< 2 >::EntityPointer HostNodePointer;
  typedef typename HostGridPartType::IntersectionIteratorType HostIntersectionIterator;

  //! type of (non-discrete )function space
  typedef typename HostDiscreteFunctionSpaceType::FunctionSpaceType FunctionSpaceType;

  //! type of domain
  typedef typename FunctionSpaceType::DomainType DomainType;
  typedef std::vector< DomainType > CoarseNodeVectorType;
  typedef std::vector< CoarseNodeVectorType > CoarseGridNodeStorageType;
  typedef boost::multi_array<bool, 3> EnrichmentMatrixType;
  //! @todo this should eventually be changed to the type of the coarse space
  typedef typename HostGridPartType::template Codim<0>::EntityType::Geometry::LocalCoordinate LocalCoordinateType;
  typedef GenericReferenceElements< typename  LocalCoordinateType::value_type,  LocalCoordinateType::dimension >
          CoarseRefElementType;
  typedef std::vector<std::vector<HostEntityPointerType>> EntityPointerCollectionType;

public:
  //! ---------------- typedefs for the SubgridDiscreteFunctionSpace -----------------------
  // ( typedefs for the local grid and the corresponding local ('sub') )discrete space )

  //! type of grid
  typedef SubGridImp SubGridType;

  //! type of grid part
  typedef LeafGridPart< SubGridType > SubGridPartType;

    //! type of subgrid discrete function space
  typedef LagrangeDiscreteFunctionSpace< FunctionSpaceType, SubGridPartType, 1/*=POLORDER*/ > SubGridDiscreteFunctionSpace;

  //! type of subgrid discrete function
  typedef AdaptiveDiscreteFunction< SubGridDiscreteFunctionSpace > SubGridDiscreteFunction;

  SubGridList(MacroMicroGridSpecifierType& specifier, bool silent = true);
  SubGridType& getSubGrid(int i);
  const SubGridType& getSubGrid(int i) const;

  // only required for oversampling strategies with constraints (e.g strategy 2 or 3):
  const CoarseNodeVectorType& getCoarseNodeVector(int i) const;

private:
  /**
   * \note called in SubGridList constructor only
   */
  void enrichment(const HostEntityPointerType& hit,
          const HostEntityPointerType& level_father_it,
          const int& father_index, // father_index = index/number of current subgrid
          const HostGridPartType& hostGridPart,
          shared_ptr<SubGridType> subGrid,
          EntityPointerCollectionType& entities_sharing_same_node,
          int& layer,
          EnrichmentMatrixType& enriched);

  bool entity_patch_in_subgrid(const HostEntityPointerType& hit,
          const HostGridPartType& hostGridPart,
          shared_ptr<const SubGridType> subGrid,
          const EntityPointerCollectionType& entities_sharing_same_node) const;

  const HostDiscreteFunctionSpaceType& hostSpace_;
  MacroMicroGridSpecifierType& specifier_;

  bool silent_;

  typedef std::vector< std::shared_ptr<SubGridType> > SubGridStorageType;
  SubGridStorageType subGridList_;

  CoarseGridNodeStorageType coarse_node_store_;

public:
  ~SubGridList()
  {}
};

} //namespace MsFEM {
} //namespace Multiscale {
} //namespace Dune {

#endif // #ifndef SUBGRIDLIST_HH

<commit_msg>_refix_ subgrid-list for gcc 4.7<commit_after>// dune-multiscale
// Copyright Holders: Patrick Henning, Rene Milk
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef SUBGRIDLIST_HH
#define SUBGRIDLIST_HH

#include <boost/noncopyable.hpp>
#include <boost/multi_array.hpp>

#include <dune/common/fmatrix.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/exceptions.hh>
#include <dune/stuff/grid/entity.hh>

#include <dune/multiscale/tools/subgrid_io.hh>
#include <dune/subgrid/subgrid.hh>

#include <dune/fem/quadrature/cachingquadrature.hh>
#include <dune/fem/operator/common/operator.hh>
#include <dune/fem/gridpart/adaptiveleafgridpart.hh>
#include <dune/fem/space/lagrangespace.hh>
#include <dune/fem/function/adaptivefunction.hh>
#include <dune/fem/operator/2order/lagrangematrixsetup.hh>

#include <dune/multiscale/msfem/msfem_traits.hh>
#include <dune/multiscale/msfem/msfem_grid_specifier.hh>

namespace Dune {
namespace Multiscale {
namespace MsFEM {

//! container for cell problem subgrids
class SubGridList : public boost::noncopyable
{
  typedef typename CommonTraits::DiscreteFunctionType HostDiscreteFunctionImp;
  typedef MsFEMTraits::SubGridType SubGridImp;
  typedef MsFEMTraits::MacroMicroGridSpecifierType MacroMicroGridSpecifierImp;

public:
  //! ---------------- typedefs for the HostDiscreteFunctionSpace -----------------------

  typedef MacroMicroGridSpecifierImp MacroMicroGridSpecifierType;
  typedef HostDiscreteFunctionImp HostDiscreteFunctionType;
  //! type of discrete function space
  typedef typename HostDiscreteFunctionType::DiscreteFunctionSpaceType HostDiscreteFunctionSpaceType;
  //! type of grid partition
  typedef typename HostDiscreteFunctionSpaceType::GridPartType HostGridPartType;

  //! type of grid
private:
  typedef typename HostDiscreteFunctionSpaceType::GridType HostGridType;
  typedef typename HostGridType::Traits::LeafIndexSet HostGridLeafIndexSet;
  typedef typename HostDiscreteFunctionSpaceType::IteratorType HostGridEntityIteratorType;
  typedef typename HostGridEntityIteratorType::Entity HostEntityType;
  typedef typename HostEntityType::EntityPointer HostEntityPointerType;
  typedef typename HostEntityType::Codim< 2 >::EntityPointer HostNodePointer;
  typedef typename HostGridPartType::IntersectionIteratorType HostIntersectionIterator;

  //! type of (non-discrete )function space
  typedef typename HostDiscreteFunctionSpaceType::FunctionSpaceType FunctionSpaceType;

  //! type of domain
  typedef typename FunctionSpaceType::DomainType DomainType;
  typedef std::vector< DomainType > CoarseNodeVectorType;
  typedef std::vector< CoarseNodeVectorType > CoarseGridNodeStorageType;
  typedef boost::multi_array<bool, 3> EnrichmentMatrixType;
  //! @todo this should eventually be changed to the type of the coarse space
  typedef typename HostGridPartType::Codim<0>::EntityType::Geometry::LocalCoordinate LocalCoordinateType;
  typedef GenericReferenceElements< typename  LocalCoordinateType::value_type,  LocalCoordinateType::dimension >
          CoarseRefElementType;
  typedef std::vector<std::vector<HostEntityPointerType>> EntityPointerCollectionType;

public:
  //! ---------------- typedefs for the SubgridDiscreteFunctionSpace -----------------------
  // ( typedefs for the local grid and the corresponding local ('sub') )discrete space )

  //! type of grid
  typedef SubGridImp SubGridType;

  //! type of grid part
  typedef LeafGridPart< SubGridType > SubGridPartType;

    //! type of subgrid discrete function space
  typedef LagrangeDiscreteFunctionSpace< FunctionSpaceType, SubGridPartType, 1/*=POLORDER*/ > SubGridDiscreteFunctionSpace;

  //! type of subgrid discrete function
  typedef AdaptiveDiscreteFunction< SubGridDiscreteFunctionSpace > SubGridDiscreteFunction;

  SubGridList(MacroMicroGridSpecifierType& specifier, bool silent = true);
  SubGridType& getSubGrid(int i);
  const SubGridType& getSubGrid(int i) const;

  // only required for oversampling strategies with constraints (e.g strategy 2 or 3):
  const CoarseNodeVectorType& getCoarseNodeVector(int i) const;

private:
  /**
   * \note called in SubGridList constructor only
   */
  void enrichment(const HostEntityPointerType& hit,
          const HostEntityPointerType& level_father_it,
          const int& father_index, // father_index = index/number of current subgrid
          const HostGridPartType& hostGridPart,
          shared_ptr<SubGridType> subGrid,
          EntityPointerCollectionType& entities_sharing_same_node,
          int& layer,
          EnrichmentMatrixType& enriched);

  bool entity_patch_in_subgrid(const HostEntityPointerType& hit,
          const HostGridPartType& hostGridPart,
          shared_ptr<const SubGridType> subGrid,
          const EntityPointerCollectionType& entities_sharing_same_node) const;

  const HostDiscreteFunctionSpaceType& hostSpace_;
  MacroMicroGridSpecifierType& specifier_;

  bool silent_;

  typedef std::vector< std::shared_ptr<SubGridType> > SubGridStorageType;
  SubGridStorageType subGridList_;

  CoarseGridNodeStorageType coarse_node_store_;

public:
  ~SubGridList()
  {}
};

} //namespace MsFEM {
} //namespace Multiscale {
} //namespace Dune {

#endif // #ifndef SUBGRIDLIST_HH

<|endoftext|>


<commit_before>/*
 * IsoffMainManager.cpp
 *****************************************************************************
 * Copyright (C) 2010 - 2012 Klagenfurt University
 *
 * Created on: Jan 27, 2010
 * Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
 *          Christian Timmerer  <christian.timmerer@itec.uni-klu.ac.at>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "IsoffMainManager.h"

using namespace dash::mpd;

IsoffMainManager::IsoffMainManager  (MPD *mpd)
{
    this->mpd = mpd;
}
IsoffMainManager::~IsoffMainManager ()
{
    delete this->mpd;
}

std::vector<Segment*>       IsoffMainManager::getSegments           (const Representation *rep)
{
    std::vector<Segment *>  retSegments;
    SegmentList*            list= rep->getSegmentList();

    if(rep->getSegmentBase())
    {
        Segment* initSegment = rep->getSegmentBase()->getInitSegment();

        if(initSegment)
            retSegments.push_back(initSegment);
    }

    retSegments.insert(retSegments.end(), list->getSegments().begin(), list->getSegments().end());
    return retSegments;
}
const std::vector<Period*>& IsoffMainManager::getPeriods            () const
{
    return this->mpd->getPeriods();
}
Representation*             IsoffMainManager::getBestRepresentation (Period *period)
{
    std::vector<AdaptationSet *> adaptationSets = period->getAdaptationSets();

    int             bitrate  = 0;
    Representation  *best    = NULL;

    for(size_t i = 0; i < adaptationSets.size(); i++)
    {
        std::vector<Representation *> reps = adaptationSets.at(i)->getRepresentations();
        for(size_t j = 0; j < reps.size(); j++)
        {
            int currentBitrate = reps.at(j)->getBandwidth();

            if(currentBitrate > bitrate)
            {
                bitrate = currentBitrate;
                best    = reps.at(j);
            }
        }
    }
    return best;
}
Period*                     IsoffMainManager::getFirstPeriod        ()
{
    std::vector<Period *> periods = this->mpd->getPeriods();

    if(periods.size() == 0)
        return NULL;

    return periods.at(0);
}
Representation*             IsoffMainManager::getRepresentation     (Period *period, uint64_t bitrate) const
{
    if(period == NULL)
        return NULL;

    std::vector<AdaptationSet *> adaptationSets = period->getAdaptationSets();

    Representation  *best = NULL;

    for(size_t i = 0; i < adaptationSets.size(); i++)
    {
        std::vector<Representation *> reps = adaptationSets.at(i)->getRepresentations();
        for( size_t j = 0; j < reps.size(); j++ )
        {
            uint64_t currentBitrate = reps.at(j)->getBandwidth();

            if(best == NULL || (currentBitrate > best->getBandwidth() && currentBitrate < bitrate))
            {
                best = reps.at( j );
            }
        }
    }
    return best;
}
Period*                     IsoffMainManager::getNextPeriod         (Period *period)
{
    std::vector<Period *> periods = this->mpd->getPeriods();

    for(size_t i = 0; i < periods.size(); i++)
    {
        if(periods.at(i) == period && (i + 1) < periods.size())
            return periods.at(i + 1);
    }

    return NULL;
}
const MPD*                  IsoffMainManager::getMPD                () const
{
    return this->mpd;
}
Representation*             IsoffMainManager::getRepresentation     (Period *period, uint64_t bitrate, int width, int height) const
{
    if(period == NULL)
        return NULL;

    std::vector<AdaptationSet *> adaptationSets = period->getAdaptationSets();
    std::vector<Representation *> resMatchReps;

    for(size_t i = 0; i < adaptationSets.size(); i++)
    {
        std::vector<Representation *> reps = adaptationSets.at(i)->getRepresentations();
        for( size_t j = 0; j < reps.size(); j++ )
        {
            if(reps.at(j)->getWidth() == width && reps.at(j)->getHeight() == height)
                resMatchReps.push_back(reps.at(j));
        }
    }

    if(resMatchReps.size() == 0)
        return this->getRepresentation(period, bitrate);

    Representation  *best = NULL;
    for( size_t j = 0; j < resMatchReps.size(); j++ )
    {
        uint64_t currentBitrate = resMatchReps.at(j)->getBandwidth();

        if(best == NULL || (currentBitrate > best->getBandwidth() && currentBitrate < bitrate))
        {
            best = resMatchReps.at(j);
        }
    }

    return best;
}
<commit_msg>stream_filter: dash: fix null dereference on empty segments list<commit_after>/*
 * IsoffMainManager.cpp
 *****************************************************************************
 * Copyright (C) 2010 - 2012 Klagenfurt University
 *
 * Created on: Jan 27, 2010
 * Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
 *          Christian Timmerer  <christian.timmerer@itec.uni-klu.ac.at>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "IsoffMainManager.h"

using namespace dash::mpd;

IsoffMainManager::IsoffMainManager  (MPD *mpd)
{
    this->mpd = mpd;
}
IsoffMainManager::~IsoffMainManager ()
{
    delete this->mpd;
}

std::vector<Segment*>       IsoffMainManager::getSegments           (const Representation *rep)
{
    std::vector<Segment *>  retSegments;
    SegmentList*            list= rep->getSegmentList();

    if(rep->getSegmentBase())
    {
        Segment* initSegment = rep->getSegmentBase()->getInitSegment();

        if(initSegment)
            retSegments.push_back(initSegment);
    }

    if ( list )
        retSegments.insert(retSegments.end(), list->getSegments().begin(), list->getSegments().end());
    return retSegments;
}
const std::vector<Period*>& IsoffMainManager::getPeriods            () const
{
    return this->mpd->getPeriods();
}
Representation*             IsoffMainManager::getBestRepresentation (Period *period)
{
    std::vector<AdaptationSet *> adaptationSets = period->getAdaptationSets();

    int             bitrate  = 0;
    Representation  *best    = NULL;

    for(size_t i = 0; i < adaptationSets.size(); i++)
    {
        std::vector<Representation *> reps = adaptationSets.at(i)->getRepresentations();
        for(size_t j = 0; j < reps.size(); j++)
        {
            int currentBitrate = reps.at(j)->getBandwidth();

            if(currentBitrate > bitrate)
            {
                bitrate = currentBitrate;
                best    = reps.at(j);
            }
        }
    }
    return best;
}
Period*                     IsoffMainManager::getFirstPeriod        ()
{
    std::vector<Period *> periods = this->mpd->getPeriods();

    if(periods.size() == 0)
        return NULL;

    return periods.at(0);
}
Representation*             IsoffMainManager::getRepresentation     (Period *period, uint64_t bitrate) const
{
    if(period == NULL)
        return NULL;

    std::vector<AdaptationSet *> adaptationSets = period->getAdaptationSets();

    Representation  *best = NULL;

    for(size_t i = 0; i < adaptationSets.size(); i++)
    {
        std::vector<Representation *> reps = adaptationSets.at(i)->getRepresentations();
        for( size_t j = 0; j < reps.size(); j++ )
        {
            uint64_t currentBitrate = reps.at(j)->getBandwidth();

            if(best == NULL || (currentBitrate > best->getBandwidth() && currentBitrate < bitrate))
            {
                best = reps.at( j );
            }
        }
    }
    return best;
}
Period*                     IsoffMainManager::getNextPeriod         (Period *period)
{
    std::vector<Period *> periods = this->mpd->getPeriods();

    for(size_t i = 0; i < periods.size(); i++)
    {
        if(periods.at(i) == period && (i + 1) < periods.size())
            return periods.at(i + 1);
    }

    return NULL;
}
const MPD*                  IsoffMainManager::getMPD                () const
{
    return this->mpd;
}
Representation*             IsoffMainManager::getRepresentation     (Period *period, uint64_t bitrate, int width, int height) const
{
    if(period == NULL)
        return NULL;

    std::vector<AdaptationSet *> adaptationSets = period->getAdaptationSets();
    std::vector<Representation *> resMatchReps;

    for(size_t i = 0; i < adaptationSets.size(); i++)
    {
        std::vector<Representation *> reps = adaptationSets.at(i)->getRepresentations();
        for( size_t j = 0; j < reps.size(); j++ )
        {
            if(reps.at(j)->getWidth() == width && reps.at(j)->getHeight() == height)
                resMatchReps.push_back(reps.at(j));
        }
    }

    if(resMatchReps.size() == 0)
        return this->getRepresentation(period, bitrate);

    Representation  *best = NULL;
    for( size_t j = 0; j < resMatchReps.size(); j++ )
    {
        uint64_t currentBitrate = resMatchReps.at(j)->getBandwidth();

        if(best == NULL || (currentBitrate > best->getBandwidth() && currentBitrate < bitrate))
        {
            best = resMatchReps.at(j);
        }
    }

    return best;
}
<|endoftext|>


<commit_before>#include "ParticleSystem.h"
#include "AnimRecorder.h"
#include "InvertRecord.h"
#include "ps_config.h"
#include "PS.h"

#include <ps_3d.h>

namespace eparticle3d
{

ParticleSystem::ParticleSystem(p3d_emitter_cfg* cfg, bool record)
	: m_anim_recorder(NULL)
	, m_inv_record(NULL)
{
	PS::Instance();

	if (record) {
		m_anim_recorder = new AnimRecorder(4096);
		m_inv_record = new InvertRecord;
	}

	m_et = p3d_emitter_create(cfg);
	m_et->ud = this;
}

ParticleSystem::ParticleSystem(const ParticleSystem& ps)
	: m_anim_recorder(NULL)
	, m_inv_record(NULL)
{
	PS::Instance();

	m_et = p3d_emitter_create(ps.m_et->cfg);
	m_et->ud = this;
}

ParticleSystem::~ParticleSystem()
{
	delete m_anim_recorder;
	delete m_inv_record;

	free(m_et);
}

void ParticleSystem::SetValue(int key, const d2d::UICallback::Data& data)
{
	switch (key)
	{
	case PS_COUNT:
		m_et->cfg->count = data.val0;
		break;
	case PS_EMISSION_TIME:
		m_et->cfg->emission_time = data.val0 * 0.001f;
		break;
	case PS_LIFE_TIME:
		m_et->cfg->life = data.val0 * 0.001f;
		m_et->cfg->life_var = data.val1 * 0.001f;
		break;
	case PS_SPEED:
		m_et->cfg->spd = data.val0 * 0.25f;
		m_et->cfg->spd_var = data.val1 * 0.25f;
		break;
	case PS_ANGULAR_SPEED:
		m_et->cfg->angular_spd = data.val0 * d2d::TRANS_DEG_TO_RAD;
		m_et->cfg->angular_spd_var = data.val1 * d2d::TRANS_DEG_TO_RAD;
		break;
	case PS_DISTURBANCE_RADIUS:
		m_et->cfg->dis_region = data.val0;
		m_et->cfg->dis_region_var = data.val1;
		break;
	case PS_DISTURBANCE_SPD:
		m_et->cfg->dis_spd = data.val0;
		m_et->cfg->dis_spd_var = data.val1;
		break;
	case PS_GRAVITY:
		m_et->cfg->gravity = data.val0 * 0.3f;
		if (m_inv_record) {
			m_inv_record->SetGravity(m_et->cfg->gravity);
		}
		break;
	case PS_LINEAR_ACC:
		m_et->cfg->linear_acc = data.val0;
		m_et->cfg->linear_acc_var = data.val1;
		break;
	case PS_FADEOUT_TIME:
		m_et->cfg->fadeout_time = data.val0 * 0.001f;
		break;
	case PS_START_POS:
		m_et->cfg->start_radius = data.val0;
		m_et->cfg->start_height = data.val1;
		break;
	}
}

void ParticleSystem::GetValue(int key, d2d::UICallback::Data& data)
{
	switch (key)
	{
	case PS_COUNT:
		data.val0 = m_et->cfg->count;
		break;
	case PS_EMISSION_TIME:
		data.val0 = m_et->cfg->emission_time * 1000;
		break;
	case PS_LIFE_TIME:
		data.val0 = m_et->cfg->life * 1000;
		data.val1 = m_et->cfg->life_var * 1000;
		break;
	case PS_SPEED:
		data.val0 = m_et->cfg->spd * 4;
		data.val1 = m_et->cfg->spd_var * 4;
		break;
	case PS_ANGULAR_SPEED:
		data.val0 = m_et->cfg->angular_spd * d2d::TRANS_RAD_TO_DEG;
		data.val1 = m_et->cfg->angular_spd_var * d2d::TRANS_RAD_TO_DEG;
		break;
	case PS_DISTURBANCE_RADIUS:
		data.val0 = m_et->cfg->dis_region;
		data.val1 = m_et->cfg->dis_region_var;
		break;
	case PS_DISTURBANCE_SPD:
		data.val0 = m_et->cfg->dis_spd;
		data.val1 = m_et->cfg->dis_spd_var;
		break;
	case PS_GRAVITY:
		data.val0 = m_et->cfg->gravity / 0.3f;
		break;
	case PS_LINEAR_ACC:
		data.val0 = m_et->cfg->linear_acc;
		data.val1 = m_et->cfg->linear_acc_var;
		break;
	case PS_FADEOUT_TIME:
		data.val0 = m_et->cfg->fadeout_time * 1000;
		break;
	case PS_START_POS:
		data.val0 = m_et->cfg->start_radius;
		data.val1 = m_et->cfg->start_height;
		break;
	}
}

void ParticleSystem::Draw(const d2d::Matrix& mt, AnimRecorder* recorder) const
{
//  // todo record
// 	if (m_anim_recorder) {
// 		m_anim_recorder->FinishFrame();
// 	}

	if (m_et->local_mode_draw) {
		p3d_emitter_draw(m_et, &mt);
	} else {
		p3d_emitter_draw(m_et, NULL);
	}
}

bool ParticleSystem::Update(const d2d::Matrix& mat)
{
	float time = PS::Instance()->GetTime();
	assert(m_et->time <= time);
	if (m_et->time == time) {
		return false;
	}

	const float* src = mat.getElements();
	float mt[6];
	mt[0] = src[0];
	mt[1] = src[1];
	mt[2] = src[4];
	mt[3] = src[5];
	mt[4] = src[12];
	mt[5] = src[13];

	float dt = time - m_et->time;
	p3d_emitter_update(m_et, dt, mt);
	m_et->time = time;

	return true;
}

void ParticleSystem::SetDirection(float x, float y, float z)
{
	vec3 start(0, 0, 1), end(x, y, z);
	end.Normalize();
	SetDirection(Quaternion::CreateFromVectors(start, end));
}

void ParticleSystem::SetDirection(const Quaternion& dir)
{
	// todo
//	direction = dir.ToMatrix();
}

void ParticleSystem::Start()
{
	m_et->active = true;
	m_et->particle_count = 0;
}

void ParticleSystem::Stop()
{
	m_et->active = false;
	m_et->emit_counter = 0;
}

void ParticleSystem::Reset()
{
//  	// todo clear child's ps
//  	Particle* p = pStart;
//  	while (p != pLast)
//  	{
//  		if (p->pc->m_bind_ps) {
//  			p->pc->m_bind_ps->reset();
// 			p->pc->m_bind_ps->stop();
//  		}
//  		++p;
//  	}

	Clear();
}

void ParticleSystem::Pause()
{
	m_et->active = false;
}

void ParticleSystem::SetLoop(bool loop)
{
	if (loop == m_et->loop) {
		return;
	}

	m_et->loop = loop;

	if (m_et->loop) {
		Start();
	} else {
		Pause();
	}
}

void ParticleSystem::SetLocalModeDraw(bool local)
{
	m_et->local_mode_draw = local;
}

void ParticleSystem::Clear()
{
	p3d_emitter_clear(m_et);
	if (m_anim_recorder) {
		m_anim_recorder->Clear();
	}
	if (m_inv_record) {
		m_inv_record->Clear();
	}
}

bool ParticleSystem::IsEmpty() const
{
	return !m_et->head;
}

void ParticleSystem::ReloadTexture() const
{
	for (int i = 0; i < m_et->cfg->symbol_count; ++i) {
		d2d::ISymbol* symbol = static_cast<d2d::ISymbol*>(m_et->cfg->symbols[i].ud);
		symbol->ReloadTexture();
	}
}

void ParticleSystem::StoreAnimRecord(const std::string& filepath) const
{
	if (m_anim_recorder) {
		m_anim_recorder->StoreToFile(filepath);
	}
}

void ParticleSystem::StoreInvertRecord(const std::string& filepath) const
{
	if (m_inv_record) {
		m_inv_record->StoreToFile(filepath);
	}
}

void ParticleSystem::RemoveFromInvertRecord(p3d_particle* p)
{
	if (m_inv_record) {
		m_inv_record->AddItem(p);
	}
}

void ParticleSystem::SetHori(int min, int max)
{
	m_et->cfg->hori = (min + max) * 0.5f * d2d::TRANS_DEG_TO_RAD;
	m_et->cfg->hori_var = (max - min) * 0.5f * d2d::TRANS_DEG_TO_RAD;
}

void ParticleSystem::SetVert(int min, int max)
{
	m_et->cfg->vert = (min + max) * 0.5f * d2d::TRANS_DEG_TO_RAD;
	m_et->cfg->vert_var = (max - min) * 0.5f * d2d::TRANS_DEG_TO_RAD;
}

void ParticleSystem::SetGround(int ground)
{
	m_et->cfg->ground = ground;
}

void ParticleSystem::SetOrientToMovement(bool open)
{
	m_et->cfg->orient_to_movement = open;
}

p3d_symbol* ParticleSystem::AddSymbol(d2d::ISymbol* symbol)
{
	assert(m_et->cfg->symbol_count < MAX_COMPONENTS);

	p3d_symbol& comp = m_et->cfg->symbols[m_et->cfg->symbol_count++];
	memset(&comp, 0, SIZEOF_P3D_SYMBOL);

	comp.scale_start = comp.scale_end = 1;

	comp.col_mul.r = comp.col_mul.g = comp.col_mul.b = comp.col_mul.a = 1;
	comp.col_add.r = comp.col_add.g = comp.col_add.b = 0;

	comp.alpha_start = comp.alpha_end = 1;

	comp.ud = symbol;

	return ∁
}

void ParticleSystem::DelSymbol(int idx)
{
	if (idx < 0 || idx >= m_et->cfg->symbol_count) {
		return;
	}

	if (m_et->cfg->symbol_count == 1) {
		m_et->cfg->symbol_count = 0;
	} else {
		for (int i = idx; i < m_et->cfg->symbol_count - 1; ++i) {
			const p3d_symbol* src = &m_et->cfg->symbols[i+1];
			p3d_symbol* dst = &m_et->cfg->symbols[i];
			memcpy(dst, src, sizeof(p3d_symbol));
		}
		--m_et->cfg->symbol_count;
	}
}

void ParticleSystem::DelAllSymbol()
{
	m_et->cfg->symbol_count = 0;
}

p3d_symbol* ParticleSystem::GetSymbol(int idx)
{
	if (idx < 0 || idx >= m_et->cfg->symbol_count) {
		return NULL;
	} else {
		return &m_et->cfg->symbols[idx];
	}
}

const p3d_emitter_cfg* ParticleSystem::GetConfig() const
{
	return m_et->cfg;
}

}
<commit_msg>[FIXED] ps release<commit_after>#include "ParticleSystem.h"
#include "AnimRecorder.h"
#include "InvertRecord.h"
#include "ps_config.h"
#include "PS.h"

#include <ps_3d.h>

namespace eparticle3d
{

ParticleSystem::ParticleSystem(p3d_emitter_cfg* cfg, bool record)
	: m_anim_recorder(NULL)
	, m_inv_record(NULL)
{
	PS::Instance();

	if (record) {
		m_anim_recorder = new AnimRecorder(4096);
		m_inv_record = new InvertRecord;
	}

	m_et = p3d_emitter_create(cfg);
	m_et->ud = this;
}

ParticleSystem::ParticleSystem(const ParticleSystem& ps)
	: m_anim_recorder(NULL)
	, m_inv_record(NULL)
{
	PS::Instance();

	m_et = p3d_emitter_create(ps.m_et->cfg);
	m_et->ud = this;
}

ParticleSystem::~ParticleSystem()
{
	delete m_anim_recorder;
	delete m_inv_record;

	p3d_emitter_release(m_et);
}

void ParticleSystem::SetValue(int key, const d2d::UICallback::Data& data)
{
	switch (key)
	{
	case PS_COUNT:
		m_et->cfg->count = data.val0;
		break;
	case PS_EMISSION_TIME:
		m_et->cfg->emission_time = data.val0 * 0.001f;
		break;
	case PS_LIFE_TIME:
		m_et->cfg->life = data.val0 * 0.001f;
		m_et->cfg->life_var = data.val1 * 0.001f;
		break;
	case PS_SPEED:
		m_et->cfg->spd = data.val0 * 0.25f;
		m_et->cfg->spd_var = data.val1 * 0.25f;
		break;
	case PS_ANGULAR_SPEED:
		m_et->cfg->angular_spd = data.val0 * d2d::TRANS_DEG_TO_RAD;
		m_et->cfg->angular_spd_var = data.val1 * d2d::TRANS_DEG_TO_RAD;
		break;
	case PS_DISTURBANCE_RADIUS:
		m_et->cfg->dis_region = data.val0;
		m_et->cfg->dis_region_var = data.val1;
		break;
	case PS_DISTURBANCE_SPD:
		m_et->cfg->dis_spd = data.val0;
		m_et->cfg->dis_spd_var = data.val1;
		break;
	case PS_GRAVITY:
		m_et->cfg->gravity = data.val0 * 0.3f;
		if (m_inv_record) {
			m_inv_record->SetGravity(m_et->cfg->gravity);
		}
		break;
	case PS_LINEAR_ACC:
		m_et->cfg->linear_acc = data.val0;
		m_et->cfg->linear_acc_var = data.val1;
		break;
	case PS_FADEOUT_TIME:
		m_et->cfg->fadeout_time = data.val0 * 0.001f;
		break;
	case PS_START_POS:
		m_et->cfg->start_radius = data.val0;
		m_et->cfg->start_height = data.val1;
		break;
	}
}

void ParticleSystem::GetValue(int key, d2d::UICallback::Data& data)
{
	switch (key)
	{
	case PS_COUNT:
		data.val0 = m_et->cfg->count;
		break;
	case PS_EMISSION_TIME:
		data.val0 = m_et->cfg->emission_time * 1000;
		break;
	case PS_LIFE_TIME:
		data.val0 = m_et->cfg->life * 1000;
		data.val1 = m_et->cfg->life_var * 1000;
		break;
	case PS_SPEED:
		data.val0 = m_et->cfg->spd * 4;
		data.val1 = m_et->cfg->spd_var * 4;
		break;
	case PS_ANGULAR_SPEED:
		data.val0 = m_et->cfg->angular_spd * d2d::TRANS_RAD_TO_DEG;
		data.val1 = m_et->cfg->angular_spd_var * d2d::TRANS_RAD_TO_DEG;
		break;
	case PS_DISTURBANCE_RADIUS:
		data.val0 = m_et->cfg->dis_region;
		data.val1 = m_et->cfg->dis_region_var;
		break;
	case PS_DISTURBANCE_SPD:
		data.val0 = m_et->cfg->dis_spd;
		data.val1 = m_et->cfg->dis_spd_var;
		break;
	case PS_GRAVITY:
		data.val0 = m_et->cfg->gravity / 0.3f;
		break;
	case PS_LINEAR_ACC:
		data.val0 = m_et->cfg->linear_acc;
		data.val1 = m_et->cfg->linear_acc_var;
		break;
	case PS_FADEOUT_TIME:
		data.val0 = m_et->cfg->fadeout_time * 1000;
		break;
	case PS_START_POS:
		data.val0 = m_et->cfg->start_radius;
		data.val1 = m_et->cfg->start_height;
		break;
	}
}

void ParticleSystem::Draw(const d2d::Matrix& mt, AnimRecorder* recorder) const
{
//  // todo record
// 	if (m_anim_recorder) {
// 		m_anim_recorder->FinishFrame();
// 	}

	if (m_et->local_mode_draw) {
		p3d_emitter_draw(m_et, &mt);
	} else {
		p3d_emitter_draw(m_et, NULL);
	}
}

bool ParticleSystem::Update(const d2d::Matrix& mat)
{
	float time = PS::Instance()->GetTime();
	assert(m_et->time <= time);
	if (m_et->time == time) {
		return false;
	}

	const float* src = mat.getElements();
	float mt[6];
	mt[0] = src[0];
	mt[1] = src[1];
	mt[2] = src[4];
	mt[3] = src[5];
	mt[4] = src[12];
	mt[5] = src[13];

	float dt = time - m_et->time;
	p3d_emitter_update(m_et, dt, mt);
	m_et->time = time;

	return true;
}

void ParticleSystem::SetDirection(float x, float y, float z)
{
	vec3 start(0, 0, 1), end(x, y, z);
	end.Normalize();
	SetDirection(Quaternion::CreateFromVectors(start, end));
}

void ParticleSystem::SetDirection(const Quaternion& dir)
{
	// todo
//	direction = dir.ToMatrix();
}

void ParticleSystem::Start()
{
	m_et->active = true;
	m_et->particle_count = 0;
}

void ParticleSystem::Stop()
{
	m_et->active = false;
	m_et->emit_counter = 0;
}

void ParticleSystem::Reset()
{
//  	// todo clear child's ps
//  	Particle* p = pStart;
//  	while (p != pLast)
//  	{
//  		if (p->pc->m_bind_ps) {
//  			p->pc->m_bind_ps->reset();
// 			p->pc->m_bind_ps->stop();
//  		}
//  		++p;
//  	}

	Clear();
}

void ParticleSystem::Pause()
{
	m_et->active = false;
}

void ParticleSystem::SetLoop(bool loop)
{
	if (loop == m_et->loop) {
		return;
	}

	m_et->loop = loop;

	if (m_et->loop) {
		Start();
	} else {
		Pause();
	}
}

void ParticleSystem::SetLocalModeDraw(bool local)
{
	m_et->local_mode_draw = local;
}

void ParticleSystem::Clear()
{
	p3d_emitter_clear(m_et);
	if (m_anim_recorder) {
		m_anim_recorder->Clear();
	}
	if (m_inv_record) {
		m_inv_record->Clear();
	}
}

bool ParticleSystem::IsEmpty() const
{
	return !m_et->head;
}

void ParticleSystem::ReloadTexture() const
{
	for (int i = 0; i < m_et->cfg->symbol_count; ++i) {
		d2d::ISymbol* symbol = static_cast<d2d::ISymbol*>(m_et->cfg->symbols[i].ud);
		symbol->ReloadTexture();
	}
}

void ParticleSystem::StoreAnimRecord(const std::string& filepath) const
{
	if (m_anim_recorder) {
		m_anim_recorder->StoreToFile(filepath);
	}
}

void ParticleSystem::StoreInvertRecord(const std::string& filepath) const
{
	if (m_inv_record) {
		m_inv_record->StoreToFile(filepath);
	}
}

void ParticleSystem::RemoveFromInvertRecord(p3d_particle* p)
{
	if (m_inv_record) {
		m_inv_record->AddItem(p);
	}
}

void ParticleSystem::SetHori(int min, int max)
{
	m_et->cfg->hori = (min + max) * 0.5f * d2d::TRANS_DEG_TO_RAD;
	m_et->cfg->hori_var = (max - min) * 0.5f * d2d::TRANS_DEG_TO_RAD;
}

void ParticleSystem::SetVert(int min, int max)
{
	m_et->cfg->vert = (min + max) * 0.5f * d2d::TRANS_DEG_TO_RAD;
	m_et->cfg->vert_var = (max - min) * 0.5f * d2d::TRANS_DEG_TO_RAD;
}

void ParticleSystem::SetGround(int ground)
{
	m_et->cfg->ground = ground;
}

void ParticleSystem::SetOrientToMovement(bool open)
{
	m_et->cfg->orient_to_movement = open;
}

p3d_symbol* ParticleSystem::AddSymbol(d2d::ISymbol* symbol)
{
	assert(m_et->cfg->symbol_count < MAX_COMPONENTS);

	p3d_symbol& comp = m_et->cfg->symbols[m_et->cfg->symbol_count++];
	memset(&comp, 0, SIZEOF_P3D_SYMBOL);

	comp.scale_start = comp.scale_end = 1;

	comp.col_mul.r = comp.col_mul.g = comp.col_mul.b = comp.col_mul.a = 1;
	comp.col_add.r = comp.col_add.g = comp.col_add.b = 0;

	comp.alpha_start = comp.alpha_end = 1;

	comp.ud = symbol;

	return ∁
}

void ParticleSystem::DelSymbol(int idx)
{
	if (idx < 0 || idx >= m_et->cfg->symbol_count) {
		return;
	}

	if (m_et->cfg->symbol_count == 1) {
		m_et->cfg->symbol_count = 0;
	} else {
		for (int i = idx; i < m_et->cfg->symbol_count - 1; ++i) {
			const p3d_symbol* src = &m_et->cfg->symbols[i+1];
			p3d_symbol* dst = &m_et->cfg->symbols[i];
			memcpy(dst, src, sizeof(p3d_symbol));
		}
		--m_et->cfg->symbol_count;
	}
}

void ParticleSystem::DelAllSymbol()
{
	m_et->cfg->symbol_count = 0;
}

p3d_symbol* ParticleSystem::GetSymbol(int idx)
{
	if (idx < 0 || idx >= m_et->cfg->symbol_count) {
		return NULL;
	} else {
		return &m_et->cfg->symbols[idx];
	}
}

const p3d_emitter_cfg* ParticleSystem::GetConfig() const
{
	return m_et->cfg;
}

}
<|endoftext|>