<commit_before>/*
 * Mickey Scheme
 *
 * Copyright (C) 2011-2012 Christian Stigen Larsen <csl@sublevel3.org>
 * http://csl.sublevel3.org                              _
 *                                                        \
 * Distributed under the LGPL 2.1; see LICENSE            /\
 * Please post bugfixes and suggestions to the author.   /  \_
 *
 */

#include <dlfcn.h>
#include <libgen.h>
#include "cons.h"
#include "library/unix-dlopen.h"

extern "C" {

/*
 * Define an arbitrary type tag to use to discern
 * between different pointers.
 */
#define TYPE_TAG "dynamic-shared-library-handle"

/*
 * Symbols we will use for the RTLD_* mode flags.
 */
#define SYMBOL_RTLD_LAZY   "lazy"
#define SYMBOL_RTLD_NOW    "now"
#define SYMBOL_RTLD_GLOBAL "global"
#define SYMBOL_RTLD_LOCAL  "local"

named_function_t exports_dlopen[] = {
  {"dlclose", proc_dlclose, false},
  {"dlerror", proc_dlerror, false},
  {"dlopen", proc_dlopen, false},
  {"dlopen-internal", proc_dlopen_internal, false},
  {"dlopen-self", proc_dlopen_self, false},
  {"dlsym", proc_dlsym, false},
  {"dlsym-syntax", proc_dlsym_syntax, false},
  {NULL, NULL, false}};

/*
 * ... and the function to parse it
 */
static int parse_dlopen_mode(const cons_t* p)
{
  int mode = 0;

  for ( cons_t *m = cdr(p); !nullp(m); m = cdr(m) ) {
    std::string n = symbol_name(car(m));

         if ( n == SYMBOL_RTLD_LAZY )   mode |= RTLD_LAZY;
    else if ( n == SYMBOL_RTLD_NOW )    mode |= RTLD_NOW;
    else if ( n == SYMBOL_RTLD_GLOBAL ) mode |= RTLD_GLOBAL;
    else if ( n == SYMBOL_RTLD_LOCAL )  mode |= RTLD_LOCAL;
    else {
      raise(runtime_exception(format(
        "Unknown dlopen mode parameter %s --- "
        "available modes are %s %s %s %s", n.c_str(),
          SYMBOL_RTLD_LAZY, SYMBOL_RTLD_NOW,
          SYMBOL_RTLD_GLOBAL, SYMBOL_RTLD_LOCAL)));
    }
  }

  return mode;
}

cons_t* proc_dlclose(cons_t* p, environment_t*)
{
  assert_length(p, 1);
  assert_pointer(TYPE_TAG, car(p));
  void *handle = car(p)->pointer->value;
  return boolean(dlclose(handle) == 0);
}

cons_t* proc_dlerror(cons_t*, environment_t*)
{
  const char* s = dlerror();
  return string(s!=NULL? s : "");
}

/*
 * Signature: (dlopen <filename> <mode options> ...)
 *
 * Options must be symbols with names lazy now global local.  These
 * correspond to the RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL and RTLD_LOCAL mode
 * options.  If you specify several options, they will be bitwise OR'ed
 * together.
 *
 */
cons_t* proc_dlopen(cons_t* p, environment_t*)
{
  assert_length_min(p, 1);
  assert_type(STRING, car(p));

  void *h = dlopen(car(p)->string, parse_dlopen_mode(cdr(p)));

  return h!=NULL?
    pointer(new pointer_t(TYPE_TAG, h)) :
    boolean(false);
}

/*
 * Signature: (dlopen <mode options> ...)
 *
 * Opens the currently running code.
 */
cons_t* proc_dlopen_self(cons_t* p, environment_t*)
{
  void *h = dlopen(NULL, length(p)==0? NULL : parse_dlopen_mode(cdr(p)));

  return h!=NULL?
    pointer(new pointer_t(TYPE_TAG, h)) :
    boolean(false);
}

/*
 * Same as proc_dlopen, but will load from Mickey Scheme's library
 * directory.  It's a utility function to load default libraries without
 * having to guess the path.
 */
cons_t* proc_dlopen_internal(cons_t* p, environment_t*)
{
  assert_length_min(p, 1);
  assert_type(STRING, car(p));

  /*
   * file will point to Mickey Scheme's location
   * and then in the /lib/ subdirectory
   */
  std::string file =
    format("%s/lib/%s",
      global_opts.mickey_absolute_path,
      sbasename(car(p)->string).c_str());

  void *h = dlopen(file.c_str(), parse_dlopen_mode(cdr(p)));

  return h!=NULL?
    pointer(new pointer_t(TYPE_TAG, h)) :
    boolean(false);
}

static lambda_t dlsym_helper(cons_t* p)
{
  assert_length(p, 2, 3);
  assert_pointer(TYPE_TAG, car(p));
  assert_type(STRING, cadr(p));

  pointer_t *handle = car(p)->pointer;
  const char* name = cadr(p)->string;

  return reinterpret_cast<lambda_t>(dlsym(handle->value, name));
}

/*
 * Takes a handle, a function name and an optional environment
 * (default is current environment) and returns a closure
 * of the given function and environment, or #f if operation
 * failed.
 *
 * (dlsym <handle> <name> <environment>?)
 *
 */
cons_t* proc_dlsym(cons_t* p, environment_t* current)
{
  environment_t *e = current;

  if ( length(p) == 3 ) {
    assert_type(ENVIRONMENT, caddr(p));
    e = caddr(p)->environment;
  }

  lambda_t f = dlsym_helper(p);
  return f != NULL ? closure(f, e) : boolean(false);
}

/*
 * Same as dlsym, but returns a syntactic closure, meaning that function
 * arguments are not evaluated before invocation.
 */
cons_t* proc_dlsym_syntax(cons_t* p, environment_t* current)
{
  environment_t *e = current;

  if ( length(p) == 3 ) {
    assert_type(ENVIRONMENT, caddr(p));
    e = caddr(p)->environment;
  }

  lambda_t f = dlsym_helper(p);
  return f != NULL ? closure(f, e, true) : boolean(false);
}

}
<commit_msg>Explicit conversion<commit_after>/*
 * Mickey Scheme
 *
 * Copyright (C) 2011-2012 Christian Stigen Larsen <csl@sublevel3.org>
 * http://csl.sublevel3.org                              _
 *                                                        \
 * Distributed under the LGPL 2.1; see LICENSE            /\
 * Please post bugfixes and suggestions to the author.   /  \_
 *
 */

#include <dlfcn.h>
#include <libgen.h>
#include "cons.h"
#include "library/unix-dlopen.h"

extern "C" {

/*
 * Define an arbitrary type tag to use to discern
 * between different pointers.
 */
#define TYPE_TAG "dynamic-shared-library-handle"

/*
 * Symbols we will use for the RTLD_* mode flags.
 */
#define SYMBOL_RTLD_LAZY   "lazy"
#define SYMBOL_RTLD_NOW    "now"
#define SYMBOL_RTLD_GLOBAL "global"
#define SYMBOL_RTLD_LOCAL  "local"

named_function_t exports_dlopen[] = {
  {"dlclose", proc_dlclose, false},
  {"dlerror", proc_dlerror, false},
  {"dlopen", proc_dlopen, false},
  {"dlopen-internal", proc_dlopen_internal, false},
  {"dlopen-self", proc_dlopen_self, false},
  {"dlsym", proc_dlsym, false},
  {"dlsym-syntax", proc_dlsym_syntax, false},
  {NULL, NULL, false}};

/*
 * ... and the function to parse it
 */
static int parse_dlopen_mode(const cons_t* p)
{
  int mode = 0;

  for ( cons_t *m = cdr(p); !nullp(m); m = cdr(m) ) {
    std::string n = symbol_name(car(m));

         if ( n == SYMBOL_RTLD_LAZY )   mode |= RTLD_LAZY;
    else if ( n == SYMBOL_RTLD_NOW )    mode |= RTLD_NOW;
    else if ( n == SYMBOL_RTLD_GLOBAL ) mode |= RTLD_GLOBAL;
    else if ( n == SYMBOL_RTLD_LOCAL )  mode |= RTLD_LOCAL;
    else {
      raise(runtime_exception(format(
        "Unknown dlopen mode parameter %s --- "
        "available modes are %s %s %s %s", n.c_str(),
          SYMBOL_RTLD_LAZY, SYMBOL_RTLD_NOW,
          SYMBOL_RTLD_GLOBAL, SYMBOL_RTLD_LOCAL)));
    }
  }

  return mode;
}

cons_t* proc_dlclose(cons_t* p, environment_t*)
{
  assert_length(p, 1);
  assert_pointer(TYPE_TAG, car(p));
  void *handle = car(p)->pointer->value;
  return boolean(dlclose(handle) == 0);
}

cons_t* proc_dlerror(cons_t*, environment_t*)
{
  const char* s = dlerror();
  return string(s!=NULL? s : "");
}

/*
 * Signature: (dlopen <filename> <mode options> ...)
 *
 * Options must be symbols with names lazy now global local.  These
 * correspond to the RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL and RTLD_LOCAL mode
 * options.  If you specify several options, they will be bitwise OR'ed
 * together.
 *
 */
cons_t* proc_dlopen(cons_t* p, environment_t*)
{
  assert_length_min(p, 1);
  assert_type(STRING, car(p));

  void *h = dlopen(car(p)->string, parse_dlopen_mode(cdr(p)));

  return h!=NULL?
    pointer(new pointer_t(TYPE_TAG, h)) :
    boolean(false);
}

/*
 * Signature: (dlopen <mode options> ...)
 *
 * Opens the currently running code.
 */
cons_t* proc_dlopen_self(cons_t* p, environment_t*)
{
  void *h = static_cast<void*>(
              dlopen(NULL, length(p)==0 ?
                NULL : parse_dlopen_mode(cdr(p))));

  return h!=NULL?
    pointer(new pointer_t(TYPE_TAG, h)) :
    boolean(false);
}

/*
 * Same as proc_dlopen, but will load from Mickey Scheme's library
 * directory.  It's a utility function to load default libraries without
 * having to guess the path.
 */
cons_t* proc_dlopen_internal(cons_t* p, environment_t*)
{
  assert_length_min(p, 1);
  assert_type(STRING, car(p));

  /*
   * file will point to Mickey Scheme's location
   * and then in the /lib/ subdirectory
   */
  std::string file =
    format("%s/lib/%s",
      global_opts.mickey_absolute_path,
      sbasename(car(p)->string).c_str());

  void *h = dlopen(file.c_str(), parse_dlopen_mode(cdr(p)));

  return h!=NULL?
    pointer(new pointer_t(TYPE_TAG, h)) :
    boolean(false);
}

static lambda_t dlsym_helper(cons_t* p)
{
  assert_length(p, 2, 3);
  assert_pointer(TYPE_TAG, car(p));
  assert_type(STRING, cadr(p));

  pointer_t *handle = car(p)->pointer;
  const char* name = cadr(p)->string;

  return reinterpret_cast<lambda_t>(dlsym(handle->value, name));
}

/*
 * Takes a handle, a function name and an optional environment
 * (default is current environment) and returns a closure
 * of the given function and environment, or #f if operation
 * failed.
 *
 * (dlsym <handle> <name> <environment>?)
 *
 */
cons_t* proc_dlsym(cons_t* p, environment_t* current)
{
  environment_t *e = current;

  if ( length(p) == 3 ) {
    assert_type(ENVIRONMENT, caddr(p));
    e = caddr(p)->environment;
  }

  lambda_t f = dlsym_helper(p);
  return f != NULL ? closure(f, e) : boolean(false);
}

/*
 * Same as dlsym, but returns a syntactic closure, meaning that function
 * arguments are not evaluated before invocation.
 */
cons_t* proc_dlsym_syntax(cons_t* p, environment_t* current)
{
  environment_t *e = current;

  if ( length(p) == 3 ) {
    assert_type(ENVIRONMENT, caddr(p));
    e = caddr(p)->environment;
  }

  lambda_t f = dlsym_helper(p);
  return f != NULL ? closure(f, e, true) : boolean(false);
}

}
<|endoftext|>


<commit_before>/******************************************************************************
 *
 * package:     Log4Qt
 * file:        loggingevent.cpp
 * created:     September 2007
 * author:      Martin Heinrich
 *
 *
 * Copyright 2007 Martin Heinrich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *****************************************************************************/

/******************************************************************************
 * Dependencies
 ******************************************************************************/

#include "log4qt/loggingevent.h"

#include <QtCore/QBuffer>
#include <QtCore/QByteArray>
#include <QtCore/QDataStream>
#include <QtCore/QDebug>
#include <QtCore/QMutex>
#include <QtCore/QThread>
#include "log4qt/helpers/datetime.h"
#include "log4qt/helpers/initialisationhelper.h"
#include "log4qt/logger.h"
#include "log4qt/mdc.h"
#include "log4qt/ndc.h"

namespace Log4Qt
{

	/**************************************************************************
	 * Declarations
	 **************************************************************************/

	LOG4QT_GLOBAL_STATIC(QMutex, sequence_guard)

	/**************************************************************************
	 * C helper functions
	 **************************************************************************/

	/**************************************************************************
	 * Class implementation: LoggingEvent
	 **************************************************************************/

	LoggingEvent::LoggingEvent() :
		mLevel(Level::NULL_INT),
	    mpLogger(0),
	    mMessage(),
	    mNdc(NDC::peek()),
	    mProperties(MDC::context()),
	    mSequenceNumber(nextSequenceNumber()),
	    mThreadName(),
	    mTimeStamp(DateTime::currentDateTime().toMilliSeconds())
	{
		setThreadNameToCurrent();
	}

	LoggingEvent::LoggingEvent(const Logger *pLogger,
	                           Level level,
	                           const QString &rMessage) :
	    mLevel(level),
	    mpLogger(pLogger),
	    mMessage(rMessage),
	    mNdc(NDC::peek()),
	    mProperties(MDC::context()),
	    mSequenceNumber(nextSequenceNumber()),
	    mThreadName(),
	    mTimeStamp(DateTime::currentDateTime().toMilliSeconds())
	{
		setThreadNameToCurrent();
	}

	LoggingEvent::LoggingEvent(const Logger *pLogger,
	                           Level level,
	                           const QString &rMessage,
	                           qint64 timeStamp) :
	    mLevel(level),
	    mpLogger(pLogger),
	    mMessage(rMessage),
	    mNdc(NDC::peek()),
	    mProperties(MDC::context()),
	    mSequenceNumber(nextSequenceNumber()),
	    mThreadName(),
	    mTimeStamp(timeStamp)
	{
		setThreadNameToCurrent();
	}

	LoggingEvent::LoggingEvent(const Logger *pLogger,
	                           Level level,
	                           const QString &rMessage,
	                           const QString &rNdc,
	                           const QHash<QString, QString> &rProperties,
	                           const QString &rThreadName,
	                           qint64 timeStamp) :
	    mLevel(level),
	    mpLogger(pLogger),
	    mMessage(rMessage),
	    mNdc(rNdc),
	    mProperties(rProperties),
	    mSequenceNumber(nextSequenceNumber()),
	    mThreadName(rThreadName),
	    mTimeStamp(timeStamp)
	{
	}

	QString LoggingEvent::loggerName() const
	{
		if (mpLogger)
			return mpLogger->name();
		else
			return QString();
	}

	QString LoggingEvent::toString() const
	{
	    return level().toString() + QLatin1Char(':') + message();
	}

	qint64 LoggingEvent::sequenceCount()
	{
	    QMutexLocker locker(sequence_guard());

	    return msSequenceCount;
	}

	qint64 LoggingEvent::startTime()
	{
		return InitialisationHelper::startTime();
	}

	void LoggingEvent::setThreadNameToCurrent()
	{
		if (QThread::currentThread())
			mThreadName = QThread::currentThread()->objectName();
	}

	qint64 LoggingEvent::nextSequenceNumber()
	{
	    QMutexLocker locker(sequence_guard());

	    return ++msSequenceCount;
	}

	qint64 LoggingEvent::msSequenceCount = 0;

	/**************************************************************************
	 * Implementation: Operators, Helper
	 **************************************************************************/

#ifndef QT_NO_DATASTREAM
    QDataStream &operator<<(QDataStream &rStream, const LoggingEvent &rLoggingEvent)
    {
        QBuffer buffer;
        buffer.open(QIODevice::WriteOnly);
        QDataStream stream(&buffer);

        // version
        quint16 version = 0;
        stream << version;
        // version 0 data
        stream << rLoggingEvent.mLevel
               << rLoggingEvent.loggerName()
               << rLoggingEvent.mMessage
               << rLoggingEvent.mNdc
               << rLoggingEvent.mProperties
               << rLoggingEvent.mSequenceNumber
               << rLoggingEvent.mThreadName
               << rLoggingEvent.mTimeStamp;

        buffer.close();
        rStream << buffer.buffer();
        return rStream;
    }

    QDataStream &operator>>(QDataStream &rStream, LoggingEvent &rLoggingEvent)
    {
        QByteArray array;
        rStream >> array;
        QBuffer buffer(&array);
        buffer.open(QIODevice::ReadOnly);
        QDataStream stream(&buffer);

        // version
        quint16 version;
        stream >> version;
        // Version 0 data
        QString logger;
        stream >> rLoggingEvent.mLevel
               >> logger
               >> rLoggingEvent.mMessage
               >> rLoggingEvent.mNdc
               >> rLoggingEvent.mProperties
               >> rLoggingEvent.mSequenceNumber
               >> rLoggingEvent.mThreadName
               >> rLoggingEvent.mTimeStamp;
        if (logger.isEmpty())
            rLoggingEvent.mpLogger = 0;
        else
            rLoggingEvent.mpLogger = Logger::logger(logger);

        buffer.close();
        return rStream;
    }
#endif // QT_NO_DATASTREAM

#ifndef QT_NO_DEBUG_STREAM
	QDebug operator<<(QDebug debug,
	                  const LoggingEvent &rLoggingEvent)
	{
	    QString logger;
	    if (rLoggingEvent.logger() != 0)
	        logger = rLoggingEvent.logger()->name();

	    debug.nospace() << "LoggingEvent("
	        << "level:" << rLoggingEvent.level().toString() << " "
	        << "logger:" << logger << " "
	        << "message:" << rLoggingEvent.message() << " "
	        << "sequencenumber:" << rLoggingEvent.sequenceNumber() << " "
	        << "threadname:" << rLoggingEvent.threadName() << " "
	        << "timestamp:" << rLoggingEvent.timeStamp()
	        	<< "(" << DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()) << ")"
	        << "sequenceCount:" << rLoggingEvent.sequenceCount()
	        << ")";
	    return debug.space();
	}
#endif // QT_NO_DEBUG_STREAM

} // namespace Log4Qt
<commit_msg>Use threadId if threads objectName is empty.<commit_after>/******************************************************************************
 *
 * package:     Log4Qt
 * file:        loggingevent.cpp
 * created:     September 2007
 * author:      Martin Heinrich
 *
 *
 * Copyright 2007 Martin Heinrich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *****************************************************************************/

/******************************************************************************
 * Dependencies
 ******************************************************************************/

#include "log4qt/loggingevent.h"

#include <QtCore/QBuffer>
#include <QtCore/QByteArray>
#include <QtCore/QDataStream>
#include <QtCore/QDebug>
#include <QtCore/QMutex>
#include <QtCore/QThread>
#include "log4qt/helpers/datetime.h"
#include "log4qt/helpers/initialisationhelper.h"
#include "log4qt/logger.h"
#include "log4qt/mdc.h"
#include "log4qt/ndc.h"

namespace Log4Qt
{

	/**************************************************************************
	 * Declarations
	 **************************************************************************/

	LOG4QT_GLOBAL_STATIC(QMutex, sequence_guard)

	/**************************************************************************
	 * C helper functions
	 **************************************************************************/

	/**************************************************************************
	 * Class implementation: LoggingEvent
	 **************************************************************************/

	LoggingEvent::LoggingEvent() :
		mLevel(Level::NULL_INT),
	    mpLogger(0),
	    mMessage(),
	    mNdc(NDC::peek()),
	    mProperties(MDC::context()),
	    mSequenceNumber(nextSequenceNumber()),
	    mThreadName(),
	    mTimeStamp(DateTime::currentDateTime().toMilliSeconds())
	{
		setThreadNameToCurrent();
	}

	LoggingEvent::LoggingEvent(const Logger *pLogger,
	                           Level level,
	                           const QString &rMessage) :
	    mLevel(level),
	    mpLogger(pLogger),
	    mMessage(rMessage),
	    mNdc(NDC::peek()),
	    mProperties(MDC::context()),
	    mSequenceNumber(nextSequenceNumber()),
	    mThreadName(),
	    mTimeStamp(DateTime::currentDateTime().toMilliSeconds())
	{
		setThreadNameToCurrent();
	}

	LoggingEvent::LoggingEvent(const Logger *pLogger,
	                           Level level,
	                           const QString &rMessage,
	                           qint64 timeStamp) :
	    mLevel(level),
	    mpLogger(pLogger),
	    mMessage(rMessage),
	    mNdc(NDC::peek()),
	    mProperties(MDC::context()),
	    mSequenceNumber(nextSequenceNumber()),
	    mThreadName(),
	    mTimeStamp(timeStamp)
	{
		setThreadNameToCurrent();
	}

	LoggingEvent::LoggingEvent(const Logger *pLogger,
	                           Level level,
	                           const QString &rMessage,
	                           const QString &rNdc,
	                           const QHash<QString, QString> &rProperties,
	                           const QString &rThreadName,
	                           qint64 timeStamp) :
	    mLevel(level),
	    mpLogger(pLogger),
	    mMessage(rMessage),
	    mNdc(rNdc),
	    mProperties(rProperties),
	    mSequenceNumber(nextSequenceNumber()),
	    mThreadName(rThreadName),
	    mTimeStamp(timeStamp)
	{
	}

	QString LoggingEvent::loggerName() const
	{
		if (mpLogger)
			return mpLogger->name();
		else
			return QString();
	}

	QString LoggingEvent::toString() const
	{
	    return level().toString() + QLatin1Char(':') + message();
	}

	qint64 LoggingEvent::sequenceCount()
	{
	    QMutexLocker locker(sequence_guard());

	    return msSequenceCount;
	}

	qint64 LoggingEvent::startTime()
	{
		return InitialisationHelper::startTime();
	}

	void LoggingEvent::setThreadNameToCurrent()
	{
		if (QThread::currentThread()) {
			mThreadName = QThread::currentThread()->objectName();
    }
    if (mThreadName.isEmpty()) {
      mThreadName = QString::number((int)QThread::currentThreadId());
    }
	}

	qint64 LoggingEvent::nextSequenceNumber()
	{
	    QMutexLocker locker(sequence_guard());

	    return ++msSequenceCount;
	}

	qint64 LoggingEvent::msSequenceCount = 0;

	/**************************************************************************
	 * Implementation: Operators, Helper
	 **************************************************************************/

#ifndef QT_NO_DATASTREAM
    QDataStream &operator<<(QDataStream &rStream, const LoggingEvent &rLoggingEvent)
    {
        QBuffer buffer;
        buffer.open(QIODevice::WriteOnly);
        QDataStream stream(&buffer);

        // version
        quint16 version = 0;
        stream << version;
        // version 0 data
        stream << rLoggingEvent.mLevel
               << rLoggingEvent.loggerName()
               << rLoggingEvent.mMessage
               << rLoggingEvent.mNdc
               << rLoggingEvent.mProperties
               << rLoggingEvent.mSequenceNumber
               << rLoggingEvent.mThreadName
               << rLoggingEvent.mTimeStamp;

        buffer.close();
        rStream << buffer.buffer();
        return rStream;
    }

    QDataStream &operator>>(QDataStream &rStream, LoggingEvent &rLoggingEvent)
    {
        QByteArray array;
        rStream >> array;
        QBuffer buffer(&array);
        buffer.open(QIODevice::ReadOnly);
        QDataStream stream(&buffer);

        // version
        quint16 version;
        stream >> version;
        // Version 0 data
        QString logger;
        stream >> rLoggingEvent.mLevel
               >> logger
               >> rLoggingEvent.mMessage
               >> rLoggingEvent.mNdc
               >> rLoggingEvent.mProperties
               >> rLoggingEvent.mSequenceNumber
               >> rLoggingEvent.mThreadName
               >> rLoggingEvent.mTimeStamp;
        if (logger.isEmpty())
            rLoggingEvent.mpLogger = 0;
        else
            rLoggingEvent.mpLogger = Logger::logger(logger);

        buffer.close();
        return rStream;
    }
#endif // QT_NO_DATASTREAM

#ifndef QT_NO_DEBUG_STREAM
	QDebug operator<<(QDebug debug,
	                  const LoggingEvent &rLoggingEvent)
	{
	    QString logger;
	    if (rLoggingEvent.logger() != 0)
	        logger = rLoggingEvent.logger()->name();

	    debug.nospace() << "LoggingEvent("
	        << "level:" << rLoggingEvent.level().toString() << " "
	        << "logger:" << logger << " "
	        << "message:" << rLoggingEvent.message() << " "
	        << "sequencenumber:" << rLoggingEvent.sequenceNumber() << " "
	        << "threadname:" << rLoggingEvent.threadName() << " "
	        << "timestamp:" << rLoggingEvent.timeStamp()
	        	<< "(" << DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()) << ")"
	        << "sequenceCount:" << rLoggingEvent.sequenceCount()
	        << ")";
	    return debug.space();
	}
#endif // QT_NO_DEBUG_STREAM

} // namespace Log4Qt
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "NewRemoteParameterUpdater.h"
#include "Trainer.h"
#include "paddle/utils/Stat.h"

DECLARE_int32(trainer_id);
DECLARE_string(save_dir);

namespace paddle {
NewRemoteParameterUpdater::NewRemoteParameterUpdater(
    const OptimizationConfig &config, const std::string pserverSpec)
    : trainerConfig_(config),
      parameterClient_(-1),
      newParameters_(nullptr),
      newGradients_(nullptr),
      pserverSpec_(pserverSpec) {}

NewRemoteParameterUpdater::NewRemoteParameterUpdater(
    const OptimizationConfig &config,
    const std::string pserverSpec,
    const bool useEtcd)
    : trainerConfig_(config),
      parameterClient_(-1),
      newParameters_(nullptr),
      newGradients_(nullptr),
      pserverSpec_(pserverSpec),
      useEtcd_(useEtcd) {}

void NewRemoteParameterUpdater::init(
    const std::vector<ParameterPtr> &parameters) {
  ParameterUpdater::init(parameters);

  // create parameter server client.
  if (useEtcd_) {
    parameterClient_ =
        paddle_new_etcd_pserver_client((char *)pserverSpec_.c_str());
  } else {
    parameterClient_ = paddle_new_pserver_client((char *)pserverSpec_.c_str(),
                                                 FLAGS_trainer_id == 0);
  }

  // init new parameter and gradient.
  newParameters_ = initNewParameter(PARAMETER_VALUE);
  newGradients_ = initNewParameter(PARAMETER_GRADIENT);

  // init parameter, one trainer will get the opportunity to int parameter and
  // send them to parameter server. Others will get the initialized parameter
  // from parameter server
  if (paddle_begin_init_params(parameterClient_)) {
    LOG(INFO) << "paddle_begin_init_params start";
    // NOTE: convert V1 OptimizatioinConfig proto to V2 OptimizerConfig.
    // This makes golang pserver compatible with handy V1 demos.
    // TODO(wuyi): Refine or remove these ugly converting lines
    OptimizerConfig optimizerConfigV2;
    if (trainerConfig_.learning_method() == "momentum") {
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::SGD);
    } else if (trainerConfig_.learning_method() == "adagrad") {
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::Adagrad);
      optimizerConfigV2.mutable_adagrad()->set_epsilon(
          trainerConfig_.ada_epsilon());
    } else if (trainerConfig_.learning_method() == "adadelta") {
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::Adagrad);
      optimizerConfigV2.mutable_adadelta()->set_epsilon(
          trainerConfig_.ada_epsilon());
      optimizerConfigV2.mutable_adadelta()->set_rho(trainerConfig_.ada_rou());
    } else if (trainerConfig_.learning_method() == "adam") {
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::Adam);
      optimizerConfigV2.mutable_adam()->set_beta_1(trainerConfig_.adam_beta1());
      optimizerConfigV2.mutable_adam()->set_beta_2(trainerConfig_.adam_beta2());
      optimizerConfigV2.mutable_adam()->set_epsilon(
          trainerConfig_.adam_epsilon());
    } else {
      LOG(ERROR) << "got unsupported v1 optimizer config: "
                 << trainerConfig_.learning_method();
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::SGD);
    }

    if (trainerConfig_.learning_rate_schedule() == "constant") {
      optimizerConfigV2.set_lr_policy(paddle::OptimizerConfig::Const);
      optimizerConfigV2.mutable_const_lr()->set_learning_rate(
          trainerConfig_.learning_rate());
    } else if (trainerConfig_.learning_rate_schedule() == "linear") {
      optimizerConfigV2.set_lr_policy(paddle::OptimizerConfig::Linear);
      optimizerConfigV2.mutable_linear_lr()->set_learning_rate(
          trainerConfig_.learning_rate());
      optimizerConfigV2.mutable_linear_lr()->set_lr_decay_a(
          trainerConfig_.learning_rate_decay_a());
      optimizerConfigV2.mutable_linear_lr()->set_lr_decay_b(
          trainerConfig_.learning_rate_decay_b());
    } else {
      LOG(ERROR) << "got unsupported v1 learning_rate_schedule config: "
                 << trainerConfig_.learning_rate_schedule() << ", set to const";
      optimizerConfigV2.set_lr_policy(paddle::OptimizerConfig::Const);
      optimizerConfigV2.mutable_const_lr()->set_learning_rate(
          trainerConfig_.learning_rate());
    }

    // overwrite optimizerConfigV2 for per-parameter(layer) configs
    for (int i = 0; i < parameterSize(); ++i) {
      // FIXME(typhoonzero): paramConfig always have default values,
      // how to check if it's default?
      // TODO: log output: optimizerConfigV2.DebugString();
      LOG(INFO) << "trainerConfig_: " << trainerConfig_.DebugString();
      // send param and config to pserver
      std::string bytes = optimizerConfigV2.SerializeAsString();
      const char *array = bytes.data();
      int size = (int)bytes.size();
      paddle_init_param(
          parameterClient_, *newParameters_[i], (void *)array, size);
    }
    paddle_finish_init_params(parameterClient_);
    LOG(INFO) << "paddle_begin_init_params done";
  } else {
    paddle_get_params(parameterClient_, newParameters_, parameterSize());
  }

  LOG(INFO) << "NewRemoteParameterUpdater initialized";
}

void NewRemoteParameterUpdater::updateImpl(Parameter *para) {}

void NewRemoteParameterUpdater::finishBatch(real cost) {
  // send gradient to parameter server.
  paddle_send_grads(parameterClient_, newGradients_, parameterSize());
  // get the updated parameter from parameterClient.
  paddle_get_params(parameterClient_, newParameters_, parameterSize());

  // clear gradient after update parameter.
  for (auto &para : parameters_) {
    para->getBuf(PARAMETER_GRADIENT)->zeroMem();
  }
}

void NewRemoteParameterUpdater::startPass() {}

bool NewRemoteParameterUpdater::finishPass() { return true; }
}  // namespace paddle
<commit_msg>Fix CI style check.<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include "NewRemoteParameterUpdater.h"
#include "Trainer.h"
#include "paddle/utils/Stat.h"

DECLARE_int32(trainer_id);
DECLARE_string(save_dir);

namespace paddle {
NewRemoteParameterUpdater::NewRemoteParameterUpdater(
    const OptimizationConfig &config, const std::string pserverSpec)
    : trainerConfig_(config),
      parameterClient_(-1),
      newParameters_(nullptr),
      newGradients_(nullptr),
      pserverSpec_(pserverSpec) {}

NewRemoteParameterUpdater::NewRemoteParameterUpdater(
    const OptimizationConfig &config,
    const std::string pserverSpec,
    const bool useEtcd)
    : trainerConfig_(config),
      parameterClient_(-1),
      newParameters_(nullptr),
      newGradients_(nullptr),
      pserverSpec_(pserverSpec),
      useEtcd_(useEtcd) {}

void NewRemoteParameterUpdater::init(
    const std::vector<ParameterPtr> &parameters) {
  ParameterUpdater::init(parameters);

  // create parameter server client.
  if (useEtcd_) {
    parameterClient_ =
        paddle_new_etcd_pserver_client((char *)pserverSpec_.c_str());
  } else {
    parameterClient_ = paddle_new_pserver_client((char *)pserverSpec_.c_str(),
                                                 FLAGS_trainer_id == 0);
  }

  // init new parameter and gradient.
  newParameters_ = initNewParameter(PARAMETER_VALUE);
  newGradients_ = initNewParameter(PARAMETER_GRADIENT);

  // init parameter, one trainer will get the opportunity to int parameter and
  // send them to parameter server. Others will get the initialized parameter
  // from parameter server
  if (paddle_begin_init_params(parameterClient_)) {
    LOG(INFO) << "paddle_begin_init_params start";
    // NOTE: convert V1 OptimizatioinConfig proto to V2 OptimizerConfig.
    // This makes golang pserver compatible with handy V1 demos.
    // TODO(wuyi): Refine or remove these ugly converting lines
    OptimizerConfig optimizerConfigV2;
    if (trainerConfig_.learning_method() == "momentum") {
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::SGD);
    } else if (trainerConfig_.learning_method() == "adagrad") {
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::Adagrad);
      optimizerConfigV2.mutable_adagrad()->set_epsilon(
          trainerConfig_.ada_epsilon());
    } else if (trainerConfig_.learning_method() == "adadelta") {
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::Adagrad);
      optimizerConfigV2.mutable_adadelta()->set_epsilon(
          trainerConfig_.ada_epsilon());
      optimizerConfigV2.mutable_adadelta()->set_rho(trainerConfig_.ada_rou());
    } else if (trainerConfig_.learning_method() == "adam") {
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::Adam);
      optimizerConfigV2.mutable_adam()->set_beta_1(trainerConfig_.adam_beta1());
      optimizerConfigV2.mutable_adam()->set_beta_2(trainerConfig_.adam_beta2());
      optimizerConfigV2.mutable_adam()->set_epsilon(
          trainerConfig_.adam_epsilon());
    } else {
      LOG(ERROR) << "got unsupported v1 optimizer config: "
                 << trainerConfig_.learning_method();
      optimizerConfigV2.set_optimizer(paddle::OptimizerConfig::SGD);
    }

    if (trainerConfig_.learning_rate_schedule() == "constant") {
      optimizerConfigV2.set_lr_policy(paddle::OptimizerConfig::Const);
      optimizerConfigV2.mutable_const_lr()->set_learning_rate(
          trainerConfig_.learning_rate());
    } else if (trainerConfig_.learning_rate_schedule() == "linear") {
      optimizerConfigV2.set_lr_policy(paddle::OptimizerConfig::Linear);
      optimizerConfigV2.mutable_linear_lr()->set_learning_rate(
          trainerConfig_.learning_rate());
      optimizerConfigV2.mutable_linear_lr()->set_lr_decay_a(
          trainerConfig_.learning_rate_decay_a());
      optimizerConfigV2.mutable_linear_lr()->set_lr_decay_b(
          trainerConfig_.learning_rate_decay_b());
    } else {
      LOG(ERROR) << "got unsupported v1 learning_rate_schedule config: "
                 << trainerConfig_.learning_rate_schedule() << ", set to const";
      optimizerConfigV2.set_lr_policy(paddle::OptimizerConfig::Const);
      optimizerConfigV2.mutable_const_lr()->set_learning_rate(
          trainerConfig_.learning_rate());
    }

    // overwrite optimizerConfigV2 for per-parameter(layer) configs
    for (int i = 0; i < parameterSize(); ++i) {
      // FIXME(typhoonzero): paramConfig always have default values,
      // how to check if it's default?
      // TODO(typhoonzero): log output: optimizerConfigV2.DebugString();
      LOG(INFO) << "trainerConfig_: " << trainerConfig_.DebugString();
      // send param and config to pserver
      std::string bytes = optimizerConfigV2.SerializeAsString();
      const char *array = bytes.data();
      int size = (int)bytes.size();
      paddle_init_param(
          parameterClient_, *newParameters_[i], (void *)array, size);
    }
    paddle_finish_init_params(parameterClient_);
    LOG(INFO) << "paddle_begin_init_params done";
  } else {
    paddle_get_params(parameterClient_, newParameters_, parameterSize());
  }

  LOG(INFO) << "NewRemoteParameterUpdater initialized";
}

void NewRemoteParameterUpdater::updateImpl(Parameter *para) {}

void NewRemoteParameterUpdater::finishBatch(real cost) {
  // send gradient to parameter server.
  paddle_send_grads(parameterClient_, newGradients_, parameterSize());
  // get the updated parameter from parameterClient.
  paddle_get_params(parameterClient_, newParameters_, parameterSize());

  // clear gradient after update parameter.
  for (auto &para : parameters_) {
    para->getBuf(PARAMETER_GRADIENT)->zeroMem();
  }
}

void NewRemoteParameterUpdater::startPass() {}

bool NewRemoteParameterUpdater::finishPass() { return true; }
}  // namespace paddle
<|endoftext|>


<commit_before>#include <vector>
#include <boost/test/unit_test.hpp>
#include <boost/foreach.hpp>

#include "../util.h"

using namespace std;

BOOST_AUTO_TEST_SUITE(util_tests)

BOOST_AUTO_TEST_CASE(util_MedianFilter)
{
    CMedianFilter<int> filter(5, 15);

    BOOST_CHECK_EQUAL(filter.median(), 15);

    filter.input(20); // [15 20]
    BOOST_CHECK_EQUAL(filter.median(), 17);

    filter.input(30); // [15 20 30]
    BOOST_CHECK_EQUAL(filter.median(), 20);

    filter.input(3); // [3 15 20 30]
    BOOST_CHECK_EQUAL(filter.median(), 17);

    filter.input(7); // [3 7 15 20 30]
    BOOST_CHECK_EQUAL(filter.median(), 15);

    filter.input(18); // [3 7 18 20 30]
    BOOST_CHECK_EQUAL(filter.median(), 18);

    filter.input(0); // [0 3 7 18 30]
    BOOST_CHECK_EQUAL(filter.median(), 7);
}

static const unsigned char ParseHex_expected[65] = {
    0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
    0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
    0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12,
    0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
    0x5f
};
BOOST_AUTO_TEST_CASE(util_ParseHex)
{
    std::vector<unsigned char> result;
    std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
    // Basic test vector
    result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
    BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());

    // Spaces between bytes must be supported
    result = ParseHex("12 34 56 78");
    BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);

    // Stop parsing at invalid value
    result = ParseHex("1234 invalid 1234");
    BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34);
}

BOOST_AUTO_TEST_CASE(util_HexStr)
{
    BOOST_CHECK_EQUAL(
        HexStr(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)),
        "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");

    BOOST_CHECK_EQUAL(
        HexStr(ParseHex_expected, ParseHex_expected + 5, true),
        "04 67 8a fd b0");
}

BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
{
    BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0), "01/01/70 00:00:00");
    BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0x7FFFFFFF), "01/19/38 03:14:07");
    // Formats used within bitcoin
    BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 1317425777), "09/30/11 23:36:17");
    BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M", 1317425777), "09/30/11 23:36");
}

BOOST_AUTO_TEST_CASE(util_ParseParameters)
{
    const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"};

    ParseParameters(0, (char**)argv_test);
    BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());

    ParseParameters(1, (char**)argv_test);
    BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());

    ParseParameters(5, (char**)argv_test);
    // expectation: -ignored is ignored (program name argument),
    // -a, -b and -ccc end up in map, -d ignored because it is after
    // a non-option argument (non-GNU option parsing)
    BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3);
    BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc")
                && !mapArgs.count("f") && !mapArgs.count("-d"));
    BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc")
                && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d"));

    BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple");
    BOOST_CHECK(mapMultiArgs["-ccc"].size() == 2);
}

BOOST_AUTO_TEST_CASE(util_GetArg)
{
    mapArgs.clear();
    mapArgs["strtest1"] = "string...";
    // strtest2 undefined on purpose
    mapArgs["inttest1"] = "12345";
    mapArgs["inttest2"] = "81985529216486895";
    // inttest3 undefined on purpose
    mapArgs["booltest1"] = "";
    // booltest2 undefined on purpose
    mapArgs["booltest3"] = "0";
    mapArgs["booltest4"] = "1";

    BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string...");
    BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default");
    BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345);
    BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895);
    BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1);
    BOOST_CHECK_EQUAL(GetBoolArg("booltest1"), true);
    BOOST_CHECK_EQUAL(GetBoolArg("booltest2"), false);
    BOOST_CHECK_EQUAL(GetBoolArg("booltest3"), false);
    BOOST_CHECK_EQUAL(GetBoolArg("booltest4"), true);
}

BOOST_AUTO_TEST_CASE(util_WildcardMatch)
{
    BOOST_CHECK(WildcardMatch("127.0.0.1", "*"));
    BOOST_CHECK(WildcardMatch("127.0.0.1", "127.*"));
    BOOST_CHECK(WildcardMatch("abcdef", "a?cde?"));
    BOOST_CHECK(!WildcardMatch("abcdef", "a?cde??"));
    BOOST_CHECK(WildcardMatch("abcdef", "a*f"));
    BOOST_CHECK(!WildcardMatch("abcdef", "a*x"));
    BOOST_CHECK(WildcardMatch("", "*"));
}

BOOST_AUTO_TEST_CASE(util_FormatMoney)
{
    BOOST_CHECK_EQUAL(FormatMoney(0, false), "0.00");
    BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789, false), "12345.6789");
    BOOST_CHECK_EQUAL(FormatMoney(COIN, true), "+1.00");
    BOOST_CHECK_EQUAL(FormatMoney(-COIN, false), "-1.00");
    BOOST_CHECK_EQUAL(FormatMoney(-COIN, true), "-1.00");

    BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000, false), "100000000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000, false), "10000000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000, false), "1000000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*100000, false), "100000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*10000, false), "10000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*1000, false), "1000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*100, false), "100.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*10, false), "10.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN, false), "1.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/10, false), "0.10");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/100, false), "0.01");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/1000, false), "0.001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/10000, false), "0.0001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/100000, false), "0.00001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000, false), "0.000001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000, false), "0.0000001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000, false), "0.00000001");
}

BOOST_AUTO_TEST_CASE(util_ParseMoney)
{
    int64 ret = 0;
    BOOST_CHECK(ParseMoney("0.0", ret));
    BOOST_CHECK_EQUAL(ret, 0);

    BOOST_CHECK(ParseMoney("12345.6789", ret));
    BOOST_CHECK_EQUAL(ret, (COIN/10000)*123456789);

    BOOST_CHECK(ParseMoney("100000000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*100000000);
    BOOST_CHECK(ParseMoney("10000000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*10000000);
    BOOST_CHECK(ParseMoney("1000000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*1000000);
    BOOST_CHECK(ParseMoney("100000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*100000);
    BOOST_CHECK(ParseMoney("10000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*10000);
    BOOST_CHECK(ParseMoney("1000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*1000);
    BOOST_CHECK(ParseMoney("100.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*100);
    BOOST_CHECK(ParseMoney("10.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*10);
    BOOST_CHECK(ParseMoney("1.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN);
    BOOST_CHECK(ParseMoney("0.1", ret));
    BOOST_CHECK_EQUAL(ret, COIN/10);
    BOOST_CHECK(ParseMoney("0.01", ret));
    BOOST_CHECK_EQUAL(ret, COIN/100);
    BOOST_CHECK(ParseMoney("0.001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/1000);
    BOOST_CHECK(ParseMoney("0.0001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/10000);
    BOOST_CHECK(ParseMoney("0.00001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/100000);
    BOOST_CHECK(ParseMoney("0.000001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/1000000);
    BOOST_CHECK(ParseMoney("0.0000001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/10000000);
    BOOST_CHECK(ParseMoney("0.00000001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/100000000);

    // Attempted 63 bit overflow should fail
    BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Declare integer constant LL<commit_after>#include <vector>
#include <boost/test/unit_test.hpp>
#include <boost/foreach.hpp>

#include "../util.h"

using namespace std;

BOOST_AUTO_TEST_SUITE(util_tests)

BOOST_AUTO_TEST_CASE(util_MedianFilter)
{
    CMedianFilter<int> filter(5, 15);

    BOOST_CHECK_EQUAL(filter.median(), 15);

    filter.input(20); // [15 20]
    BOOST_CHECK_EQUAL(filter.median(), 17);

    filter.input(30); // [15 20 30]
    BOOST_CHECK_EQUAL(filter.median(), 20);

    filter.input(3); // [3 15 20 30]
    BOOST_CHECK_EQUAL(filter.median(), 17);

    filter.input(7); // [3 7 15 20 30]
    BOOST_CHECK_EQUAL(filter.median(), 15);

    filter.input(18); // [3 7 18 20 30]
    BOOST_CHECK_EQUAL(filter.median(), 18);

    filter.input(0); // [0 3 7 18 30]
    BOOST_CHECK_EQUAL(filter.median(), 7);
}

static const unsigned char ParseHex_expected[65] = {
    0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
    0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
    0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12,
    0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
    0x5f
};
BOOST_AUTO_TEST_CASE(util_ParseHex)
{
    std::vector<unsigned char> result;
    std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
    // Basic test vector
    result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
    BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());

    // Spaces between bytes must be supported
    result = ParseHex("12 34 56 78");
    BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);

    // Stop parsing at invalid value
    result = ParseHex("1234 invalid 1234");
    BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34);
}

BOOST_AUTO_TEST_CASE(util_HexStr)
{
    BOOST_CHECK_EQUAL(
        HexStr(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)),
        "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");

    BOOST_CHECK_EQUAL(
        HexStr(ParseHex_expected, ParseHex_expected + 5, true),
        "04 67 8a fd b0");
}

BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
{
    BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0), "01/01/70 00:00:00");
    BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0x7FFFFFFF), "01/19/38 03:14:07");
    // Formats used within bitcoin
    BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 1317425777), "09/30/11 23:36:17");
    BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M", 1317425777), "09/30/11 23:36");
}

BOOST_AUTO_TEST_CASE(util_ParseParameters)
{
    const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"};

    ParseParameters(0, (char**)argv_test);
    BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());

    ParseParameters(1, (char**)argv_test);
    BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty());

    ParseParameters(5, (char**)argv_test);
    // expectation: -ignored is ignored (program name argument),
    // -a, -b and -ccc end up in map, -d ignored because it is after
    // a non-option argument (non-GNU option parsing)
    BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3);
    BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc")
                && !mapArgs.count("f") && !mapArgs.count("-d"));
    BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc")
                && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d"));

    BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple");
    BOOST_CHECK(mapMultiArgs["-ccc"].size() == 2);
}

BOOST_AUTO_TEST_CASE(util_GetArg)
{
    mapArgs.clear();
    mapArgs["strtest1"] = "string...";
    // strtest2 undefined on purpose
    mapArgs["inttest1"] = "12345";
    mapArgs["inttest2"] = "81985529216486895";
    // inttest3 undefined on purpose
    mapArgs["booltest1"] = "";
    // booltest2 undefined on purpose
    mapArgs["booltest3"] = "0";
    mapArgs["booltest4"] = "1";

    BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string...");
    BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default");
    BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345);
    BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL);
    BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1);
    BOOST_CHECK_EQUAL(GetBoolArg("booltest1"), true);
    BOOST_CHECK_EQUAL(GetBoolArg("booltest2"), false);
    BOOST_CHECK_EQUAL(GetBoolArg("booltest3"), false);
    BOOST_CHECK_EQUAL(GetBoolArg("booltest4"), true);
}

BOOST_AUTO_TEST_CASE(util_WildcardMatch)
{
    BOOST_CHECK(WildcardMatch("127.0.0.1", "*"));
    BOOST_CHECK(WildcardMatch("127.0.0.1", "127.*"));
    BOOST_CHECK(WildcardMatch("abcdef", "a?cde?"));
    BOOST_CHECK(!WildcardMatch("abcdef", "a?cde??"));
    BOOST_CHECK(WildcardMatch("abcdef", "a*f"));
    BOOST_CHECK(!WildcardMatch("abcdef", "a*x"));
    BOOST_CHECK(WildcardMatch("", "*"));
}

BOOST_AUTO_TEST_CASE(util_FormatMoney)
{
    BOOST_CHECK_EQUAL(FormatMoney(0, false), "0.00");
    BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789, false), "12345.6789");
    BOOST_CHECK_EQUAL(FormatMoney(COIN, true), "+1.00");
    BOOST_CHECK_EQUAL(FormatMoney(-COIN, false), "-1.00");
    BOOST_CHECK_EQUAL(FormatMoney(-COIN, true), "-1.00");

    BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000, false), "100000000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000, false), "10000000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000, false), "1000000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*100000, false), "100000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*10000, false), "10000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*1000, false), "1000.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*100, false), "100.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN*10, false), "10.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN, false), "1.00");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/10, false), "0.10");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/100, false), "0.01");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/1000, false), "0.001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/10000, false), "0.0001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/100000, false), "0.00001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000, false), "0.000001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000, false), "0.0000001");
    BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000, false), "0.00000001");
}

BOOST_AUTO_TEST_CASE(util_ParseMoney)
{
    int64 ret = 0;
    BOOST_CHECK(ParseMoney("0.0", ret));
    BOOST_CHECK_EQUAL(ret, 0);

    BOOST_CHECK(ParseMoney("12345.6789", ret));
    BOOST_CHECK_EQUAL(ret, (COIN/10000)*123456789);

    BOOST_CHECK(ParseMoney("100000000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*100000000);
    BOOST_CHECK(ParseMoney("10000000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*10000000);
    BOOST_CHECK(ParseMoney("1000000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*1000000);
    BOOST_CHECK(ParseMoney("100000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*100000);
    BOOST_CHECK(ParseMoney("10000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*10000);
    BOOST_CHECK(ParseMoney("1000.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*1000);
    BOOST_CHECK(ParseMoney("100.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*100);
    BOOST_CHECK(ParseMoney("10.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN*10);
    BOOST_CHECK(ParseMoney("1.00", ret));
    BOOST_CHECK_EQUAL(ret, COIN);
    BOOST_CHECK(ParseMoney("0.1", ret));
    BOOST_CHECK_EQUAL(ret, COIN/10);
    BOOST_CHECK(ParseMoney("0.01", ret));
    BOOST_CHECK_EQUAL(ret, COIN/100);
    BOOST_CHECK(ParseMoney("0.001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/1000);
    BOOST_CHECK(ParseMoney("0.0001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/10000);
    BOOST_CHECK(ParseMoney("0.00001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/100000);
    BOOST_CHECK(ParseMoney("0.000001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/1000000);
    BOOST_CHECK(ParseMoney("0.0000001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/10000000);
    BOOST_CHECK(ParseMoney("0.00000001", ret));
    BOOST_CHECK_EQUAL(ret, COIN/100000000);

    // Attempted 63 bit overflow should fail
    BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include <vector>
#include <utility>
#include <algorithm>

#include "baseproc-sys.h"

static std::vector<bool> usedfds = {true, true, true};

// Allocate a file descriptor
static int allocfd()
{
    auto f = std::find(usedfds.begin(), usedfds.end(), false);
    if (f == usedfds.end()) {
        int r = usedfds.size();
        usedfds.push_back(true);
        return r;
    }

    *f = true;
    return f - usedfds.begin();
}

namespace bp_sys {

int last_sig_sent = -1; // last signal number sent, accessible for tests.
pid_t last_forked_pid = 1;  // last forked process id (incremented each 'fork')

int pipe2(int fds[2], int flags)
{
    fds[0] = allocfd();
    fds[1] = allocfd();
    return 0;
}

int close(int fd)
{
    if (fd >= usedfds.size()) abort();

    usedfds[fd] = false;
    return 0;
}

int kill(pid_t pid, int sig)
{
    last_sig_sent = sig;
    return 0;
}

}
<commit_msg>tests: build fix for OpenBSD.<commit_after>#include <vector>
#include <utility>
#include <algorithm>

#include <cstdlib>

#include "baseproc-sys.h"

static std::vector<bool> usedfds = {true, true, true};

// Allocate a file descriptor
static int allocfd()
{
    auto f = std::find(usedfds.begin(), usedfds.end(), false);
    if (f == usedfds.end()) {
        int r = usedfds.size();
        usedfds.push_back(true);
        return r;
    }

    *f = true;
    return f - usedfds.begin();
}

namespace bp_sys {

int last_sig_sent = -1; // last signal number sent, accessible for tests.
pid_t last_forked_pid = 1;  // last forked process id (incremented each 'fork')

int pipe2(int fds[2], int flags)
{
    fds[0] = allocfd();
    fds[1] = allocfd();
    return 0;
}

int close(int fd)
{
    if (size_t(fd) >= usedfds.size()) abort();

    usedfds[fd] = false;
    return 0;
}

int kill(pid_t pid, int sig)
{
    last_sig_sent = sig;
    return 0;
}

}
<|endoftext|>


<commit_before>/*
* (C) 2014,2015,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "tests.h"

#if defined(BOTAN_HAS_HASH)
   #include <botan/hash.h>
#endif

namespace Botan_Tests {

#if defined(BOTAN_HAS_HASH)

namespace {

class Invalid_Hash_Name_Tests final : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         Test::Result result("Invalid HashFunction names");
         test_invalid_name(result, "NonExistentHash");
         test_invalid_name(result, "Blake2b(9)", "Bad output bits size for Blake2b");
         test_invalid_name(result, "Comb4P(MD5,MD5)", "Comb4P: Must use two distinct hashes");
         test_invalid_name(result, "Comb4P(MD5,SHA-1)", "Comb4P: Incompatible hashes MD5 and SHA-160");
         test_invalid_name(result, "Tiger(168)", "Tiger: Illegal hash output size: 168");
         test_invalid_name(result, "Tiger(20,2)", "Tiger: Invalid number of passes: 2");
         test_invalid_name(result, "Keccak-1600(160)", "Keccak_1600: Invalid output length 160");
         test_invalid_name(result, "SHA-3(160)", "SHA_3: Invalid output length 160");

         return {result};
         }

   private:
      void test_invalid_name(Result& result,
                             const std::string& name,
                             const std::string& expected_msg = "") const
         {
         try
            {
            auto hash = Botan::HashFunction::create_or_throw(name);
            result.test_failure("Was successfully able to create " + name);
            }
         catch(Botan::Invalid_Argument& e)
            {
            const std::string msg = e.what();
            const std::string full_msg = "Invalid argument " + expected_msg;
            result.test_eq("expected error message", msg, full_msg);
            }
         catch(Botan::Lookup_Error& e)
            {
            const std::string algo_not_found_msg = "Unavailable Hash " + name;
            const std::string msg = e.what();
            result.test_eq("expected error message", msg, algo_not_found_msg);
            }
         catch(std::exception& e)
            {
            result.test_failure("some unknown exception", e.what());
            }
         catch(...)
            {
            result.test_failure("some unknown exception");
            }
         }
   };

BOTAN_REGISTER_TEST("invalid_name_hash", Invalid_Hash_Name_Tests);

class Hash_Function_Tests final : public Text_Based_Test
   {
   public:
      Hash_Function_Tests() : Text_Based_Test("hash", "In,Out") {}

      std::vector<std::string> possible_providers(const std::string& algo) override
         {
         return provider_filter(Botan::HashFunction::providers(algo));
         }

      Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
         {
         const std::vector<uint8_t> input    = get_req_bin(vars, "In");
         const std::vector<uint8_t> expected = get_req_bin(vars, "Out");

         Test::Result result(algo);

         const std::vector<std::string> providers = possible_providers(algo);

         if(providers.empty())
            {
            result.note_missing("hash " + algo);
            return result;
            }

         for(auto const& provider_ask : providers)
            {
            std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(algo, provider_ask));

            if(!hash)
               {
               result.test_failure("Hash " + algo + " supported by " + provider_ask + " but not found");
               continue;
               }

            std::unique_ptr<Botan::HashFunction> clone(hash->clone());

            const std::string provider(hash->provider());
            result.test_is_nonempty("provider", provider);
            result.test_eq(provider, hash->name(), algo);
            result.test_eq(provider, hash->name(), clone->name());

            hash->update(input);
            result.test_eq(provider, "hashing", hash->final(), expected);

            clone->update(input);
            result.test_eq(provider, "hashing (clone)", clone->final(), expected);

            // Test to make sure clear() resets what we need it to
            hash->update("some discarded input");
            hash->clear();
            hash->update(nullptr, 0); // this should be effectively ignored
            hash->update(input);

            result.test_eq(provider, "hashing after clear", hash->final(), expected);

            if(input.size() > 5)
               {
               hash->update(input[0]);

               std::unique_ptr<Botan::HashFunction> fork = hash->copy_state();
               // verify fork copy doesn't affect original computation
               fork->update(&input[1], input.size() - 2);

               size_t so_far = 1;
               while(so_far < input.size())
                  {
                  size_t take = Test::rng().next_byte() % (input.size() - so_far);

                  if(input.size() - so_far == 1)
                     take = 1;

                  hash->update(&input[so_far], take);
                  so_far += take;
                  }
               result.test_eq(provider, "hashing split", hash->final(), expected);

               fork->update(&input[input.size() - 1], 1);
               result.test_eq(provider, "hashing split", fork->final(), expected);
               }

            if(hash->hash_block_size() > 0)
               {
               // GOST-34.11 uses 32 byte block
               result.test_gte("If hash_block_size is set, it is large", hash->hash_block_size(), 32);
               }
            }

         return result;
         }

   };

BOTAN_REGISTER_TEST("hash", Hash_Function_Tests);

}

#endif

}
<commit_msg>Fix test if OpenSSL provider enabled.<commit_after>/*
* (C) 2014,2015,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "tests.h"

#if defined(BOTAN_HAS_HASH)
   #include <botan/hash.h>
#endif

namespace Botan_Tests {

#if defined(BOTAN_HAS_HASH)

namespace {

class Invalid_Hash_Name_Tests final : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         Test::Result result("Invalid HashFunction names");
         test_invalid_name(result, "NonExistentHash");
         test_invalid_name(result, "Blake2b(9)", "Bad output bits size for Blake2b");
         test_invalid_name(result, "Comb4P(MD5,MD5)", "Comb4P: Must use two distinct hashes");
         test_invalid_name(result, "Comb4P(MD5,SHA-256)", "Comb4P: Incompatible hashes MD5 and SHA-256");
         test_invalid_name(result, "Tiger(168)", "Tiger: Illegal hash output size: 168");
         test_invalid_name(result, "Tiger(20,2)", "Tiger: Invalid number of passes: 2");
         test_invalid_name(result, "Keccak-1600(160)", "Keccak_1600: Invalid output length 160");
         test_invalid_name(result, "SHA-3(160)", "SHA_3: Invalid output length 160");

         return {result};
         }

   private:
      void test_invalid_name(Result& result,
                             const std::string& name,
                             const std::string& expected_msg = "") const
         {
         try
            {
            auto hash = Botan::HashFunction::create_or_throw(name);
            result.test_failure("Was successfully able to create " + name);
            }
         catch(Botan::Invalid_Argument& e)
            {
            const std::string msg = e.what();
            const std::string full_msg = "Invalid argument " + expected_msg;
            result.test_eq("expected error message", msg, full_msg);
            }
         catch(Botan::Lookup_Error& e)
            {
            const std::string algo_not_found_msg = "Unavailable Hash " + name;
            const std::string msg = e.what();
            result.test_eq("expected error message", msg, algo_not_found_msg);
            }
         catch(std::exception& e)
            {
            result.test_failure("some unknown exception", e.what());
            }
         catch(...)
            {
            result.test_failure("some unknown exception");
            }
         }
   };

BOTAN_REGISTER_TEST("invalid_name_hash", Invalid_Hash_Name_Tests);

class Hash_Function_Tests final : public Text_Based_Test
   {
   public:
      Hash_Function_Tests() : Text_Based_Test("hash", "In,Out") {}

      std::vector<std::string> possible_providers(const std::string& algo) override
         {
         return provider_filter(Botan::HashFunction::providers(algo));
         }

      Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
         {
         const std::vector<uint8_t> input    = get_req_bin(vars, "In");
         const std::vector<uint8_t> expected = get_req_bin(vars, "Out");

         Test::Result result(algo);

         const std::vector<std::string> providers = possible_providers(algo);

         if(providers.empty())
            {
            result.note_missing("hash " + algo);
            return result;
            }

         for(auto const& provider_ask : providers)
            {
            std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(algo, provider_ask));

            if(!hash)
               {
               result.test_failure("Hash " + algo + " supported by " + provider_ask + " but not found");
               continue;
               }

            std::unique_ptr<Botan::HashFunction> clone(hash->clone());

            const std::string provider(hash->provider());
            result.test_is_nonempty("provider", provider);
            result.test_eq(provider, hash->name(), algo);
            result.test_eq(provider, hash->name(), clone->name());

            hash->update(input);
            result.test_eq(provider, "hashing", hash->final(), expected);

            clone->update(input);
            result.test_eq(provider, "hashing (clone)", clone->final(), expected);

            // Test to make sure clear() resets what we need it to
            hash->update("some discarded input");
            hash->clear();
            hash->update(nullptr, 0); // this should be effectively ignored
            hash->update(input);

            result.test_eq(provider, "hashing after clear", hash->final(), expected);

            if(input.size() > 5)
               {
               hash->update(input[0]);

               std::unique_ptr<Botan::HashFunction> fork = hash->copy_state();
               // verify fork copy doesn't affect original computation
               fork->update(&input[1], input.size() - 2);

               size_t so_far = 1;
               while(so_far < input.size())
                  {
                  size_t take = Test::rng().next_byte() % (input.size() - so_far);

                  if(input.size() - so_far == 1)
                     take = 1;

                  hash->update(&input[so_far], take);
                  so_far += take;
                  }
               result.test_eq(provider, "hashing split", hash->final(), expected);

               fork->update(&input[input.size() - 1], 1);
               result.test_eq(provider, "hashing split", fork->final(), expected);
               }

            if(hash->hash_block_size() > 0)
               {
               // GOST-34.11 uses 32 byte block
               result.test_gte("If hash_block_size is set, it is large", hash->hash_block_size(), 32);
               }
            }

         return result;
         }

   };

BOTAN_REGISTER_TEST("hash", Hash_Function_Tests);

}

#endif

}
<|endoftext|>


<commit_before>#include "thread_renderer.h"
#include "app_globals.h"
#include "audio_nodes.h"
#include "recorder_node.h"

#include <cinder/app/App.h>

namespace cieq {

ThreadRenderer::ThreadRenderer(AppGlobals& globals)
	: mGlobals(globals)
	, mFramesPerSurface(mGlobals.getAudioNodes().getFormat().getSamplesCacheSize())
	, mFftSize(mGlobals.getAudioNodes().getFormat().getFftBins() / 2)
	, mLastPopPos(0)
	, mLastSurfaceLength(0)
	, mTotalSurfacesLength(0)
{}

void ThreadRenderer::setup()
{
	if (!mGlobals.getAudioNodes().ready()) return;

	mNumSurfaces = mGlobals.getAudioNodes().getBufferRecorderNode()->getMaxPossiblePops() / mFramesPerSurface;
	if (mGlobals.getAudioNodes().getBufferRecorderNode()->getMaxPossiblePops() % mFramesPerSurface != 0)
		mNumSurfaces += 1;

	mSurfaceTexturePool.resize(mNumSurfaces);

	mLastSurfaceLength = calculateLastSurfaceLength();
	mTotalSurfacesLength = calculateTotalSurfacesLength();

	// I hate APIs with booleans in them :(
	mCompleteAudioFbo = ci::gl::Fbo(
		mTotalSurfacesLength, //width
		mFftSize, //height
		false, // alpha
		true, // color
		false); //depth
}

void ThreadRenderer::update()
{
	if (!mGlobals.getAudioNodes().ready()) return;

	for (container_pair& pair : mSurfaceTexturePool)
	{
		if (pair.first && pair.first->allRowsTouched())
		{
			if (pair.second)
			{
				pair.second->update(*pair.first);
			}
			else
			{
				pair.second = ci::gl::Texture::create(*pair.first);
				pair.second->setMinFilter(GL_NEAREST); //disable GPU blur
				pair.second->setMagFilter(GL_NEAREST); //disable GPU blur
			}

			pair.first.reset();
		}
	}
}

void ThreadRenderer::draw()
{
	if (!mGlobals.getAudioNodes().ready()) return;

	{ //enter FBO scope
		ci::gl::SaveFramebufferBinding _save_fb;
		mCompleteAudioFbo.bindFramebuffer();

		ci::gl::pushMatrices();
		ci::gl::clear();
		ci::gl::rotate(90.0f); //rotate scene 90 degrees

		// just a convenience
		auto _recorder_node = mGlobals.getAudioNodes().getBufferRecorderNode();

		// get current record position
		const int _current_write_pos = mLastPopPos;
		// percentage of the entire audio done recording
		const float _percentage_done = static_cast<float>(_current_write_pos) / _recorder_node->getNumFrames();
		// get the index of last active surface for drawing
		int _current_last_surface = static_cast<int>(_percentage_done * mNumSurfaces);
		// number of samples that will be empty drawn (last surface)
		// get last thread-reported pop position and divide it over max pops possible
		const float _current_index_in_surface = static_cast<float>(getIndexInSurfaceByQueryPos(mLastPopPos));
		// shift to left for OpenGL (we're moving textures upside-down, therefore we shift one entire surface to right + estimate index in surface + static offset)
		const float _shift_right = static_cast<float>(_current_index_in_surface - mFramesPerSurface) - ci::app::getWindowWidth();

		ci::gl::translate(0.0f, _shift_right); //after rotation, moving x is like moving y

		for (int index = _current_last_surface, count = 0; index >= 0; --index, ++count)
		{
			const auto t = ci::app::getWindowHeight() / mCompleteAudioFbo.getHeight();
			const auto x1 = static_cast<float>(mFftSize) * ci::app::getWindowHeight() / mCompleteAudioFbo.getHeight();
			const auto y1 = static_cast<float>(count + 1) * mFramesPerSurface;
			const auto x2 = 0.0f;
			const auto y2 = static_cast<float>(count)* mFramesPerSurface;

			ci::Rectf draw_rect(x1, y1, x2, y2);

			if (mSurfaceTexturePool[index].first)
			{
				// draw surface
				ci::gl::draw(*mSurfaceTexturePool[index].first, draw_rect);
			}
			else if (mSurfaceTexturePool[index].second)
			{
				// draw texture
				ci::gl::draw(mSurfaceTexturePool[index].second, draw_rect);
			}
		}

		ci::gl::popMatrices();

		mCompleteAudioFbo.unbindFramebuffer();
	}

	{// enter screen drawing scope
		ci::gl::pushMatrices();

		ci::Rectf _target_rect(mCompleteAudioFbo.getBounds());
		std::swap(_target_rect.y1, _target_rect.y2); //swap UVs
		ci::gl::draw(mCompleteAudioFbo.getTexture(), _target_rect);

		ci::gl::popMatrices();
	}
}

SpectralSurface& ThreadRenderer::getSurface(int index, int pop_pos)
{
	// if surface does not exist
	if (!mSurfaceTexturePool[index].first)
	{
		// lock and construct the surface
		std::lock_guard<std::mutex> _lock(mPoolLock);
		if (!mSurfaceTexturePool[index].first) //double check
		{
			if (index != mNumSurfaces - 1)
			{
				mSurfaceTexturePool[index].first = std::make_unique<SpectralSurface>(mFftSize, mLastSurfaceLength);
			}
			else
			{
				mSurfaceTexturePool[index].first = std::make_unique<SpectralSurface>(mFftSize, getFramesPerSurface());
			}
		}
	}

	mLastPopPos = pop_pos; //no lock needed, atomic
	return *(mSurfaceTexturePool[index].first);
}

std::size_t ThreadRenderer::getFramesPerSurface() const
{
	return mFramesPerSurface;
}

std::size_t ThreadRenderer::getSurfaceIndexByQueryPos(std::size_t pos) const
{
	const auto pop_index = mGlobals.getAudioNodes().getBufferRecorderNode()->getQueryIndexByQueryPos(pos);
	return pop_index / getFramesPerSurface();
}

std::size_t ThreadRenderer::getIndexInSurfaceByQueryPos(std::size_t pos) const
{
	const auto pop_index = mGlobals.getAudioNodes().getBufferRecorderNode()->getQueryIndexByQueryPos(pos);
	return pop_index % getFramesPerSurface();
}

std::size_t ThreadRenderer::calculateLastSurfaceLength() const
{
	const auto _max_pops = mGlobals.getAudioNodes().getBufferRecorderNode()->getMaxPossiblePops();
	const auto _max_num_pops_in_surfaces = mNumSurfaces * mFramesPerSurface;
	const auto _actual_minus_real_diff = _max_num_pops_in_surfaces - _max_pops;
	return getFramesPerSurface() - _actual_minus_real_diff;
}

std::size_t ThreadRenderer::calculateTotalSurfacesLength() const
{
	const auto _max_pops = mGlobals.getAudioNodes().getBufferRecorderNode()->getMaxPossiblePops();
	const auto _max_num_pops_in_surfaces = mNumSurfaces * mFramesPerSurface;
	const auto _actual_minus_real_diff = _max_num_pops_in_surfaces - _max_pops;
	return (mNumSurfaces * mFramesPerSurface) - _actual_minus_real_diff;
}

} //!cieq<commit_msg>I am not sure what to do with rendering part anymore! nice.<commit_after>#include "thread_renderer.h"
#include "app_globals.h"
#include "audio_nodes.h"
#include "recorder_node.h"

#include <cinder/app/App.h>

namespace cieq {

ThreadRenderer::ThreadRenderer(AppGlobals& globals)
	: mGlobals(globals)
	, mFramesPerSurface(mGlobals.getAudioNodes().getFormat().getSamplesCacheSize())
	, mFftSize(mGlobals.getAudioNodes().getFormat().getFftBins() / 2)
	, mLastPopPos(0)
	, mLastSurfaceLength(0)
	, mTotalSurfacesLength(0)
{}

void ThreadRenderer::setup()
{
	if (!mGlobals.getAudioNodes().ready()) return;

	mNumSurfaces = mGlobals.getAudioNodes().getBufferRecorderNode()->getMaxPossiblePops() / mFramesPerSurface;
	if (mGlobals.getAudioNodes().getBufferRecorderNode()->getMaxPossiblePops() % mFramesPerSurface != 0)
		mNumSurfaces += 1;

	mSurfaceTexturePool.resize(mNumSurfaces);

	mLastSurfaceLength = calculateLastSurfaceLength();
	mTotalSurfacesLength = calculateTotalSurfacesLength();

	// I hate APIs with booleans in them :(
	mCompleteAudioFbo = ci::gl::Fbo(
		mTotalSurfacesLength, //width
		mFftSize, //height
		false, // alpha
		true, // color
		false); //depth
}

void ThreadRenderer::update()
{
	if (!mGlobals.getAudioNodes().ready()) return;

	for (container_pair& pair : mSurfaceTexturePool)
	{
		if (pair.first && pair.first->allRowsTouched())
		{
			if (pair.second)
			{
				pair.second->update(*pair.first);
			}
			else
			{
				pair.second = ci::gl::Texture::create(*pair.first);
				pair.second->setMinFilter(GL_NEAREST); //disable GPU blur
				pair.second->setMagFilter(GL_NEAREST); //disable GPU blur
			}

			pair.first.reset();
		}
	}
}

void ThreadRenderer::draw()
{
	if (!mGlobals.getAudioNodes().ready()) return;

	{ //enter FBO scope
		ci::gl::SaveFramebufferBinding _save_fb;
		mCompleteAudioFbo.bindFramebuffer();

		ci::gl::pushMatrices();
		ci::gl::clear();
		ci::gl::rotate(90.0f); //rotate scene 90 degrees

		// just a convenience
		auto _recorder_node = mGlobals.getAudioNodes().getBufferRecorderNode();

		// get current record position
		const int _current_write_pos = mLastPopPos;
		// percentage of the entire audio done recording
		const float _percentage_done = static_cast<float>(_current_write_pos) / _recorder_node->getNumFrames();
		// get the index of last active surface for drawing
		int _current_last_surface = static_cast<int>(_percentage_done * mNumSurfaces);
		// number of samples that will be empty drawn (last surface)
		// get last thread-reported pop position and divide it over max pops possible
		const float _current_index_in_surface = static_cast<float>(getIndexInSurfaceByQueryPos(mLastPopPos));
		// shift to left for OpenGL (we're moving textures upside-down, therefore we shift one entire surface to right + estimate index in surface + static offset)
		const float _shift_right = static_cast<float>(_current_index_in_surface - mFramesPerSurface) - ci::app::getWindowWidth();

		ci::gl::translate(0.0f, _shift_right); //after rotation, moving x is like moving y

		for (int index = _current_last_surface, count = 0; index >= 0; --index, ++count)
		{
			const auto t = ci::app::getWindowHeight() / mCompleteAudioFbo.getHeight();
			const auto x1 = static_cast<float>(mFftSize) * ci::app::getWindowHeight() / mCompleteAudioFbo.getHeight();
			const auto y1 = static_cast<float>(count + 1) * mFramesPerSurface;
			const auto x2 = 0.0f;
			const auto y2 = static_cast<float>(count)* mFramesPerSurface;

			ci::Rectf draw_rect(x1, y1, x2, y2);

			if (mSurfaceTexturePool[index].first)
			{
				// draw surface
				ci::gl::draw(*mSurfaceTexturePool[index].first, draw_rect);
			}
			else if (mSurfaceTexturePool[index].second)
			{
				// draw texture
				ci::gl::draw(mSurfaceTexturePool[index].second, draw_rect);
			}
		}

		ci::gl::popMatrices();

		mCompleteAudioFbo.unbindFramebuffer();
	}

	{// enter screen drawing scope
		ci::gl::pushMatrices();

		mCompleteAudioFbo.blitToScreen(mCompleteAudioFbo.getBounds(), mCompleteAudioFbo.getBounds());

		ci::gl::popMatrices();
	}
}

SpectralSurface& ThreadRenderer::getSurface(int index, int pop_pos)
{
	// if surface does not exist
	if (!mSurfaceTexturePool[index].first)
	{
		// lock and construct the surface
		std::lock_guard<std::mutex> _lock(mPoolLock);
		if (!mSurfaceTexturePool[index].first) //double check
		{
			if (index != mNumSurfaces - 1)
			{
				mSurfaceTexturePool[index].first = std::make_unique<SpectralSurface>(mFftSize, mLastSurfaceLength);
			}
			else
			{
				mSurfaceTexturePool[index].first = std::make_unique<SpectralSurface>(mFftSize, getFramesPerSurface());
			}
		}
	}

	mLastPopPos = pop_pos; //no lock needed, atomic
	return *(mSurfaceTexturePool[index].first);
}

std::size_t ThreadRenderer::getFramesPerSurface() const
{
	return mFramesPerSurface;
}

std::size_t ThreadRenderer::getSurfaceIndexByQueryPos(std::size_t pos) const
{
	const auto pop_index = mGlobals.getAudioNodes().getBufferRecorderNode()->getQueryIndexByQueryPos(pos);
	return pop_index / getFramesPerSurface();
}

std::size_t ThreadRenderer::getIndexInSurfaceByQueryPos(std::size_t pos) const
{
	const auto pop_index = mGlobals.getAudioNodes().getBufferRecorderNode()->getQueryIndexByQueryPos(pos);
	return pop_index % getFramesPerSurface();
}

std::size_t ThreadRenderer::calculateLastSurfaceLength() const
{
	const auto _max_pops = mGlobals.getAudioNodes().getBufferRecorderNode()->getMaxPossiblePops();
	const auto _max_num_pops_in_surfaces = mNumSurfaces * mFramesPerSurface;
	const auto _actual_minus_real_diff = _max_num_pops_in_surfaces - _max_pops;
	return getFramesPerSurface() - _actual_minus_real_diff;
}

std::size_t ThreadRenderer::calculateTotalSurfacesLength() const
{
	const auto _max_pops = mGlobals.getAudioNodes().getBufferRecorderNode()->getMaxPossiblePops();
	const auto _max_num_pops_in_surfaces = mNumSurfaces * mFramesPerSurface;
	const auto _actual_minus_real_diff = _max_num_pops_in_surfaces - _max_pops;
	return (mNumSurfaces * mFramesPerSurface) - _actual_minus_real_diff;
}

} //!cieq<|endoftext|>


<commit_before>#ifndef _TILES_NODE_HPP_
#define _TILES_NODE_HPP_

#include "search/Node.hpp"
#include "tiles/TilesTypes.hpp"
#include "tiles/TilesState.hpp"

template class Node<TilesState15, TileCost>;
typedef Node<TilesState15, TileCost> TilesNode15;

#endif /* !_TILES_NODE_HPP_ */
<commit_msg>Eliminated class declaration in .hpp file.<commit_after>#ifndef _TILES_NODE_HPP_
#define _TILES_NODE_HPP_

#include "search/Node.hpp"
#include "tiles/TilesTypes.hpp"
#include "tiles/TilesState.hpp"

typedef Node<TilesState15, TileCost> TilesNode15;

#endif /* !_TILES_NODE_HPP_ */
<|endoftext|>


<commit_before>#include <sstream>
#include <string>
#include <tuple>
#include <optional>
#include <functional>

#include "iterate_tuple.h"
#include "dataconsts.h"
#include "entity_system.h"
#include "chat/whisper_chat.h"

namespace {
template <typename... Args>
class Parser {
    public:
        Parser(std::stringstream&& ss) {
            size_t index = 0;
            Core::for_each(args, [&ss, &index, this](auto& data) {
                is_arg_ok[index++] = parse(ss, data);
            });
        }

        bool is_good() const {
            return std::all_of(is_arg_ok.cbegin(), is_arg_ok.cend(), [](bool i) {
                return i;
            });
        }

        std::array<bool, sizeof...(Args)> is_arg_ok;
        std::tuple<Args...> args;

    private:
        template <typename T>
        static bool parse(std::stringstream& ss, T& h) {
            return static_cast<bool>(ss >> h);
        }

        template <typename T>
        static bool parse(std::stringstream& ss, std::optional<T>& h) {
            T tmp;
            const bool has_data = ss >> tmp;
            if (has_data) {
                h = tmp;
            }
            return true;
        }
};

template <>
class Parser<> {
    public:
        Parser(std::stringstream&&) {}

        bool is_good() const {
            return true;
        }
};

void item(EntitySystem&, RoseCommon::Entity, Parser<int, int>) {
}

void teleport(EntitySystem&, RoseCommon::Entity, Parser<int, int, int, std::optional<uint16_t>>) {
}

void zuly(EntitySystem&, RoseCommon::Entity, Parser<int>) {
}
}

#define REGISTER_FUNCTION(f) [](EntitySystem& en, Entity e, std::stringstream&& ss) { f(en, e, {std::move(ss)}); }

void help(EntitySystem&, RoseCommon::Entity, Parser<std::optional<std::string>>);

static constexpr const std::unordered_map<std::string, std::tuple<uint16_t, void(*)(EntitySystem&, Entity, std::stringstream&&), std::string>> commands = {
    //{"/item", {100, REGISTER_FUNCTION(item), "Creates an item. Usage: /item <type> <id>"}},
    {"/help", {100, REGISTER_FUNCTION(help), "Prints this help. Usage: /help [command]"}},
    //{"/zuly", {100, REGISTER_FUNCTION(zuly), "Adds zulies to your inventory (you can add a negative amount). Usage: /zuly <amount>"}},
    //{"/tp", {200, REGISTER_FUNCTION(teleport), "Teleports a player or self. usage: /tp <map_id> <x> <y> [client_id]"}}
};

void help(EntitySystem& entitySystem, RoseCommon::Entity entity, Parser<std::optional<std::string>> parser) {
    if (!parser.is_good()) {
        Chat::send_whisper(entitySystem, entity, "Error while parsing the command. Usage: /help [command]");
    }
    Chat::send_whisper(entitySystem, entity, "help (<required args> [optional args]):");
    if (!std::get<0>(parser.args)) {
        for (const auto& command : commands) {
            Chat::send_whisper(entitySystem, entity, std::get<2>(command.second));
        }
    } else {
        if (const auto it = commands.find(std::get<0>(parser.args).value()); it != commands.end()) {
            Chat::send_whisper(entitySystem, entity, std::get<2>(it->second));
        } else {
            Chat::send_whisper(entitySystem, entity, fmt::format("Error, no command {} found.", std::get<0>(parser.args)));
        }
    }
}

void execute_gm(EntitySystem& entitySystem, RoseCommon::Entity entity, const std::string& message) {
    const uint16_t access_level = entitySystem.component<Component::SocketConnector>(entity).access_level;
    std::stringstream ss(message);
    std::string command;
    ss >> command;
    if (const auto it = commands.find(command); it != commands.end() && access_level >= std::get<0>(it->second)) {
        std::get<1>(it->second)(entitySystem, entity, std::move(ss));
    }
}
<commit_msg>Update gm_commands.cpp<commit_after>#include <sstream>
#include <string>
#include <tuple>
#include <optional>
#include <functional>

#include "iterate_tuple.h"
#include "dataconsts.h"
#include "entity_system.h"
#include "chat/whisper_chat.h"

namespace {
template <typename... Args>
class Parser {
    public:
        Parser(std::stringstream&& ss) {
            size_t index = 0;
            Core::for_each(args, [&ss, &index, this](auto& data) {
                is_arg_ok[index++] = parse(ss, data);
            });
        }

        bool is_good() const {
            return std::all_of(is_arg_ok.cbegin(), is_arg_ok.cend(), [](bool i) {
                return i;
            });
        }

        template <size_t N>
        decltype(auto) get_arg() {
            return std::get<N>(args);
        }

    private:
        std::array<bool, sizeof...(Args)> is_arg_ok;
        std::tuple<Args...> args;

        template <typename T>
        static bool parse(std::stringstream& ss, T& h) {
            return static_cast<bool>(ss >> h);
        }

        template <typename T>
        static bool parse(std::stringstream& ss, std::optional<T>& h) {
            T tmp;
            const bool has_data = ss >> tmp;
            if (has_data) {
                h = tmp;
            }
            return true;
        }
};

template <>
class Parser<> {
    public:
        Parser(std::stringstream&&) {}

        bool is_good() const {
            return true;
        }
};

void item(EntitySystem&, RoseCommon::Entity, Parser<int, int>) {
}

void teleport(EntitySystem&, RoseCommon::Entity, Parser<int, int, int, std::optional<uint16_t>>) {
}

void zuly(EntitySystem&, RoseCommon::Entity, Parser<int>) {
}
}

#define REGISTER_FUNCTION(f) [](EntitySystem& en, Entity e, std::stringstream&& ss) { f(en, e, {std::move(ss)}); }

void help(EntitySystem&, RoseCommon::Entity, Parser<std::optional<std::string>>);

static constexpr const std::unordered_map<std::string, std::tuple<uint16_t, void(*)(EntitySystem&, Entity, std::stringstream&&), std::string>> commands = {
    //{"/item", {100, REGISTER_FUNCTION(item), "Creates an item. Usage: /item <type> <id>"}},
    {"/help", {100, REGISTER_FUNCTION(help), "Prints this help. Usage: /help [command]"}},
    //{"/zuly", {100, REGISTER_FUNCTION(zuly), "Adds zulies to your inventory (you can add a negative amount). Usage: /zuly <amount>"}},
    //{"/tp", {200, REGISTER_FUNCTION(teleport), "Teleports a player or self. usage: /tp <map_id> <x> <y> [client_id]"}}
};

void help(EntitySystem& entitySystem, RoseCommon::Entity entity, Parser<std::optional<std::string>> parser) {
    if (!parser.is_good()) {
        Chat::send_whisper(entitySystem, entity, "Error while parsing the command. Usage: /help [command]");
    }
    Chat::send_whisper(entitySystem, entity, "help (<required args> [optional args]):");
    if (!parser.get_arg<0>()) {
        for (const auto& command : commands) {
            Chat::send_whisper(entitySystem, entity, std::get<2>(command.second));
        }
    } else {
        if (const auto it = commands.find(parser.get_arg<0>().value()); it != commands.end()) {
            Chat::send_whisper(entitySystem, entity, std::get<2>(it->second));
        } else {
            Chat::send_whisper(entitySystem, entity, fmt::format("Error, no command {} found.", parser.get_arg<0>()));
        }
    }
}

void execute_gm(EntitySystem& entitySystem, RoseCommon::Entity entity, const std::string& message) {
    const uint16_t access_level = entitySystem.component<Component::SocketConnector>(entity).access_level;
    std::stringstream ss(message);
    std::string command;
    ss >> command;
    if (const auto it = commands.find(command); it != commands.end() && access_level >= std::get<0>(it->second)) {
        std::get<1>(it->second)(entitySystem, entity, std::move(ss));
    }
}
<|endoftext|>


<commit_before>/**
 * Based on: http://datenparkplatz.de/DiesUndDas/memory_overcommit.cc
 * via LKML: https://lkml.org/lkml/2009/5/10/148
 *
 * Modifications:
 * - Use C++ style instead of C.
 * - Parse cli arguments instead of interactive prompting
 * - Don't assume values are MiB (bytes unless trailing 'K', 'M', or 'G')
 */
#include <iostream>
#include <limits>
#include <new>
#include <string>
#include <vector>

namespace {

using namespace std;

#define FAIL(msg) { cout << msg << endl; exit(EXIT_FAILURE); }

// Parse a string size into an amount of memory to allocate.
static size_t parse(const string& size) {
  size_t converted = 0;
  unsigned long val = 0;
  unsigned long shift = 0;
  unsigned long max_ul = numeric_limits<unsigned long>::max();
  size_t max_sz = numeric_limits<size_t>::max();

  // Parse the size to an unsigned int.
  try {
    val = stoul(size, &converted, 0);
  } catch (const invalid_argument& e) {
    FAIL("Invalid input: [" << size << "]");
  } catch (const out_of_range& e) {
    FAIL("Value out of range: [" << size << "]");
  } catch (const exception& e) {
    FAIL("Couldn't parse [" << size << "]: " << e.what() << " failed");
  }

  // Parse out a 'K', 'M', or 'G' suffix.
  string left(size.c_str() + converted);
  if (left == "G") shift = 30;
  else if (left == "M") shift = 20;
  else if (left == "K") shift = 10;
  else if (left != "") FAIL("Unparsed: [" << left << "] in [" << size << "]");

  // Check that the value is within range.
  if (val > max_ul >> shift) FAIL("Too big for " << left << ": " << val);
  if (val == 0) FAIL("Can't alloc 0.");
  val <<= shift;
  if (val > max_sz) FAIL("Too big for size_t: " << val);
  return val;
}

}  // namespace

// Allocate one chunk of memory for each commandline argument.
int main(int argc, char** argv) {
  size_t total = 0;
  vector<size_t> sizes;
  vector<char*> alloced;

  // Parse arguments into sizes
  for (int i=1; i<argc; i++) {
    string arg(argv[i]);
    sizes.push_back(parse(arg));
  }

  // For each size, allocate a char[] of that size.
  for (const size_t& size : sizes) {
    cout << "malloc(" << size << ") ... ";
    fflush(stdout);
    char* mem = nullptr;
    try {
      mem = new char[size]();
    } catch (const exception& e) {
      FAIL("FAILED");
    }
    alloced.push_back(mem);
    cout << "OK" << endl;
    total += size;
    cout << "Running total: " << total << endl;
  }

  // Free everything allocated.
  for (char* mem : alloced) delete[] mem;

  return EXIT_SUCCESS;
}
<commit_msg>Add ways to specify "MemAvailable" in `force-swap`<commit_after>/**
 * Based on: http://datenparkplatz.de/DiesUndDas/memory_overcommit.cc
 * via LKML: https://lkml.org/lkml/2009/5/10/148
 *
 * Modifications:
 * - Use C++ style instead of C.
 * - Parse cli arguments instead of interactive prompting
 * - Don't assume values are MiB (bytes unless trailing 'K', 'M', or 'G')
 * - Adds some synonyms for "all available memory": "all", "avail", "--avail".
 */
#include <fstream>
#include <iostream>
#include <limits>
#include <new>
#include <sstream>
#include <string>
#include <vector>

namespace {

using namespace std;

#define FAIL(msg) { cout << msg << endl; exit(EXIT_FAILURE); }

// Constants.
static const vector<string> kAvailableFlags = {"all", "avail", "--avail"};
static const string kProcMeminfo("/proc/meminfo");
static const string kMemAvailable("MemAvailable:");

// Function declarations.
static size_t available_memory();
static bool has_any_prefix(const string&, const vector<string>&);
static bool has_prefix(const string&, const string&);
static size_t parse(const string&);

// Find the MemAvailable field from /proc/meminfo.
static size_t available_memory() {
  ifstream meminfo(kProcMeminfo);
  string line;
  while (getline(meminfo, line)) {
    if (!has_prefix(line, kMemAvailable)) continue;
    istringstream input(line.substr(kMemAvailable.size()));
    size_t kb;
    input >> kb;
    return kb << 10;
  }
  FAIL("Couldn't find " << kMemAvailable << " line in " << kProcMeminfo);
}

// Parse a string size into an amount of memory to allocate.
static size_t parse(const string& size) {
  size_t converted = 0;
  unsigned long val = 0;
  unsigned long shift = 0;
  unsigned long max_ul = numeric_limits<unsigned long>::max();
  size_t max_sz = numeric_limits<size_t>::max();

  if (has_any_prefix(size, kAvailableFlags)) return available_memory();

  // Parse the size to an unsigned int.
  try {
    val = stoul(size, &converted, 0);
  } catch (const invalid_argument& e) {
    FAIL("Invalid input: [" << size << "]");
  } catch (const out_of_range& e) {
    FAIL("Value out of range: [" << size << "]");
  } catch (const exception& e) {
    FAIL("Couldn't parse [" << size << "]: " << e.what() << " failed");
  }

  // Parse out a 'K', 'M', or 'G' suffix.
  string left(size.c_str() + converted);
  if (left == "G") shift = 30;
  else if (left == "M") shift = 20;
  else if (left == "K") shift = 10;
  else if (left != "") FAIL("Unparsed: [" << left << "] in [" << size << "]");

  // Check that the value is within range.
  if (val > max_ul >> shift) FAIL("Too big for " << left << ": " << val);
  if (val == 0) FAIL("Can't alloc 0.");
  val <<= shift;
  if (val > max_sz) FAIL("Too big for size_t: " << val);
  return val;
}

// Returns true if haystack has needle as a prefix.
static bool has_prefix(const string& haystack, const string& needle) {
  return equal(needle.begin(), needle.end(), haystack.begin());
}

// Returns true if haystack has any of the needles as a prefix.
static bool has_any_prefix(const string &haystack,
                           const vector<string> &needles) {
  for (const string& needle : needles) {
    if (has_prefix(haystack, needle)) return true;
  }
  return false;
}

}  // namespace

// Allocate one chunk of memory for each commandline argument.
int main(int argc, char** argv) {
  size_t total = 0;
  vector<size_t> sizes;
  vector<char*> alloced;

  // Parse arguments into sizes
  for (int i=1; i<argc; i++) {
    string arg(argv[i]);
    sizes.push_back(parse(arg));
  }

  // For each size, allocate a char[] of that size.
  for (const size_t& size : sizes) {
    cout << "malloc(" << size << ") ... ";
    fflush(stdout);
    char* mem = nullptr;
    try {
      mem = new char[size]();
    } catch (const exception& e) {
      FAIL("FAILED");
    }
    alloced.push_back(mem);
    cout << "OK" << endl;
    total += size;
    cout << "Running total: " << total << endl;
  }

  // Free everything allocated.
  for (char* mem : alloced) delete[] mem;

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Filename: show_ddb.cxx
// Created by:  drose (02Nov02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license.  You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////

#include "pandabase.h"
#include "downloadDb.h"
#include "filename.h"

int
main(int argc, char *argv[]) {
  if (argc != 3) {
    cerr << "Usage: show_ddb server.ddb client.ddb\n";
    return 1;
  }

  Filename server_ddb = Filename::from_os_specific(argv[1]);
  Filename client_ddb = Filename::from_os_specific(argv[2]);

  DownloadDb db(server_ddb, client_ddb);
  db.output_version_map(cout);

  return 0;
}
<commit_msg>write entire ddb<commit_after>// Filename: show_ddb.cxx
// Created by:  drose (02Nov02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license.  You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////

#include "pandabase.h"
#include "downloadDb.h"
#include "filename.h"

int
main(int argc, char *argv[]) {
  if (argc != 3) {
    cerr << "Usage: show_ddb server.ddb client.ddb\n";
    return 1;
  }

  Filename server_ddb = Filename::from_os_specific(argv[1]);
  Filename client_ddb = Filename::from_os_specific(argv[2]);

  DownloadDb db(server_ddb, client_ddb);
  db.write(cout);

  return 0;
}
<|endoftext|>