<commit_before>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2.1 of the Licence, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "util.h"

#include "grantlee_latin1literal_p.h"
#include "metaenumvariable_p.h"
#include "metatype.h"

#include <QtCore/QStringList>

QString Grantlee::unescapeStringLiteral( const QString &input )
{
  return input.mid( 1, input.size() - 2 )
         .replace( QLatin1String( "\\\'" ), QChar::fromLatin1( '\'' ) )
         .replace( QLatin1String( "\\\"" ), QChar::fromLatin1( '"' ) )
         .replace( QLatin1String( "\\\\" ), QChar::fromLatin1( '\\' ) );
}

bool Grantlee::variantIsTrue( const QVariant &variant )
{

  if ( !variant.isValid() )
    return false;
  switch ( variant.userType() ) {
  case QVariant::Bool: {
    return variant.toBool();
  }
  case QVariant::Int: {
    return ( variant.toInt() > 0 );
  }
  case QVariant::Double: {
    return ( variant.toDouble() > 0 );
  }
  case QMetaType::QObjectStar: {
    QObject *obj = variant.value<QObject *>();
    if ( !obj )
      return false;

    if ( obj->property( "__true__" ).isValid() ) {
      return obj->property( "__true__" ).toBool();
    }
    return true;
  }
  case QVariant::List: {
    return ( variant.toList().size() > 0 );
  }
  case QVariant::Hash: {
    return ( variant.toHash().size() > 0 );
  }
  }

  return !getSafeString( variant ).get().isEmpty();
}

QVariantList Grantlee::variantToList( const QVariant &var )
{
  return MetaType::toVariantList( var );
}

Grantlee::SafeString Grantlee::markSafe( const Grantlee::SafeString &input )
{
  Grantlee::SafeString sret = input;
  sret.setSafety( Grantlee::SafeString::IsSafe );
  return sret;
}

Grantlee::SafeString Grantlee::markForEscaping( const Grantlee::SafeString &input )
{
  Grantlee::SafeString temp = input;
  if ( input.isSafe() || input.needsEscape() )
    return input;

  temp.setNeedsEscape( true );
  return temp;
}

Grantlee::SafeString Grantlee::getSafeString( const QVariant &input )
{
  if ( input.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
    return input.value<Grantlee::SafeString>();
  } else {
    return input.toString();
  }
}

bool Grantlee::isSafeString( const QVariant &input )
{
  const int type = input.userType();
  return (( type == qMetaTypeId<Grantlee::SafeString>() )
          || type == QVariant::String );
}

static QList<int> getPrimitives()
{
  QList<int> primitives;
  primitives << qMetaTypeId<Grantlee::SafeString>()
             << QVariant::Bool
             << QVariant::Int
             << QVariant::Double
             << QVariant::DateTime;
  return primitives;
}

bool Grantlee::supportedOutputType( const QVariant &input )
{
  static const QList<int> primitives = getPrimitives();
  return primitives.contains( input.userType() );
}

bool Grantlee::equals( const QVariant &lhs, const QVariant &rhs )
{

  // TODO: Redesign...

  // QVariant doesn't use operator== to compare its held data, so we do it manually instead for SafeString.
  bool equal = false;
  if ( lhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
    if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
      equal = ( lhs.value<Grantlee::SafeString>() == rhs.value<Grantlee::SafeString>() );
    } else if ( rhs.userType() == QVariant::String ) {
      equal = ( lhs.value<Grantlee::SafeString>() == rhs.toString() );
    }
  } else if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() && lhs.userType() == QVariant::String ) {
    equal = ( rhs.value<Grantlee::SafeString>() == lhs.toString() );
  } else if ( rhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    if ( lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
      equal = ( rhs.value<MetaEnumVariable>() == lhs.value<MetaEnumVariable>() );
    } else if ( lhs.type() == QVariant::Int ) {
      equal = ( rhs.value<MetaEnumVariable>() == lhs.toInt() );
    }
  } else if ( lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    if ( rhs.type() == QVariant::Int ) {
      equal = ( lhs.value<MetaEnumVariable>() == rhs.toInt() );
    }
  } else {
    equal = (( lhs == rhs ) && ( lhs.userType() == rhs.userType() ) );
  }
  return equal;
}

Grantlee::SafeString Grantlee::toString( const QVariantList &list )
{
  QString output( QLatin1Char( '[' ) );
  QVariantList::const_iterator it = list.constBegin();
  const QVariantList::const_iterator end = list.constEnd();
  while ( it != end ) {
    const QVariant item = *it;
    if ( isSafeString( item ) ) {
      output += QLatin1Literal( "u\'" )
              + static_cast<QString>( getSafeString( item ).get() )
              + QLatin1Char( '\'' );
    }
    if ( ( item.type() == QVariant::Int )
      || ( item.type() == QVariant::UInt )
      || ( item.type() == QVariant::Double )
      || ( item.type() == QVariant::LongLong )
      || ( item.type() == QVariant::ULongLong )
    ) {
      output += item.toString();
    }
    if ( item.type() == QVariant::List ) {
      output += static_cast<QString>( toString( item.toList() ).get() );
    }
    if ( ( it + 1 ) != end )
      output += QLatin1String( ", " );
    ++it;
  }

  return output.append( QLatin1Char( ']' ) );
}

<commit_msg>Support QDate and QTime objects.<commit_after>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2.1 of the Licence, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "util.h"

#include "grantlee_latin1literal_p.h"
#include "metaenumvariable_p.h"
#include "metatype.h"

#include <QtCore/QStringList>

QString Grantlee::unescapeStringLiteral( const QString &input )
{
  return input.mid( 1, input.size() - 2 )
         .replace( QLatin1String( "\\\'" ), QChar::fromLatin1( '\'' ) )
         .replace( QLatin1String( "\\\"" ), QChar::fromLatin1( '"' ) )
         .replace( QLatin1String( "\\\\" ), QChar::fromLatin1( '\\' ) );
}

bool Grantlee::variantIsTrue( const QVariant &variant )
{

  if ( !variant.isValid() )
    return false;
  switch ( variant.userType() ) {
  case QVariant::Bool: {
    return variant.toBool();
  }
  case QVariant::Int: {
    return ( variant.toInt() > 0 );
  }
  case QVariant::Double: {
    return ( variant.toDouble() > 0 );
  }
  case QMetaType::QObjectStar: {
    QObject *obj = variant.value<QObject *>();
    if ( !obj )
      return false;

    if ( obj->property( "__true__" ).isValid() ) {
      return obj->property( "__true__" ).toBool();
    }
    return true;
  }
  case QVariant::List: {
    return ( variant.toList().size() > 0 );
  }
  case QVariant::Hash: {
    return ( variant.toHash().size() > 0 );
  }
  }

  return !getSafeString( variant ).get().isEmpty();
}

QVariantList Grantlee::variantToList( const QVariant &var )
{
  return MetaType::toVariantList( var );
}

Grantlee::SafeString Grantlee::markSafe( const Grantlee::SafeString &input )
{
  Grantlee::SafeString sret = input;
  sret.setSafety( Grantlee::SafeString::IsSafe );
  return sret;
}

Grantlee::SafeString Grantlee::markForEscaping( const Grantlee::SafeString &input )
{
  Grantlee::SafeString temp = input;
  if ( input.isSafe() || input.needsEscape() )
    return input;

  temp.setNeedsEscape( true );
  return temp;
}

Grantlee::SafeString Grantlee::getSafeString( const QVariant &input )
{
  if ( input.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
    return input.value<Grantlee::SafeString>();
  } else {
    return input.toString();
  }
}

bool Grantlee::isSafeString( const QVariant &input )
{
  const int type = input.userType();
  return (( type == qMetaTypeId<Grantlee::SafeString>() )
          || type == QVariant::String );
}

static QList<int> getPrimitives()
{
  QList<int> primitives;
  primitives << qMetaTypeId<Grantlee::SafeString>()
             << QVariant::Bool
             << QVariant::Int
             << QVariant::Double
             << QVariant::Date
             << QVariant::Time
             << QVariant::DateTime;
  return primitives;
}

bool Grantlee::supportedOutputType( const QVariant &input )
{
  static const QList<int> primitives = getPrimitives();
  return primitives.contains( input.userType() );
}

bool Grantlee::equals( const QVariant &lhs, const QVariant &rhs )
{

  // TODO: Redesign...

  // QVariant doesn't use operator== to compare its held data, so we do it manually instead for SafeString.
  bool equal = false;
  if ( lhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
    if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
      equal = ( lhs.value<Grantlee::SafeString>() == rhs.value<Grantlee::SafeString>() );
    } else if ( rhs.userType() == QVariant::String ) {
      equal = ( lhs.value<Grantlee::SafeString>() == rhs.toString() );
    }
  } else if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() && lhs.userType() == QVariant::String ) {
    equal = ( rhs.value<Grantlee::SafeString>() == lhs.toString() );
  } else if ( rhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    if ( lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
      equal = ( rhs.value<MetaEnumVariable>() == lhs.value<MetaEnumVariable>() );
    } else if ( lhs.type() == QVariant::Int ) {
      equal = ( rhs.value<MetaEnumVariable>() == lhs.toInt() );
    }
  } else if ( lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    if ( rhs.type() == QVariant::Int ) {
      equal = ( lhs.value<MetaEnumVariable>() == rhs.toInt() );
    }
  } else {
    equal = (( lhs == rhs ) && ( lhs.userType() == rhs.userType() ) );
  }
  return equal;
}

Grantlee::SafeString Grantlee::toString( const QVariantList &list )
{
  QString output( QLatin1Char( '[' ) );
  QVariantList::const_iterator it = list.constBegin();
  const QVariantList::const_iterator end = list.constEnd();
  while ( it != end ) {
    const QVariant item = *it;
    if ( isSafeString( item ) ) {
      output += QLatin1Literal( "u\'" )
              + static_cast<QString>( getSafeString( item ).get() )
              + QLatin1Char( '\'' );
    }
    if ( ( item.type() == QVariant::Int )
      || ( item.type() == QVariant::UInt )
      || ( item.type() == QVariant::Double )
      || ( item.type() == QVariant::LongLong )
      || ( item.type() == QVariant::ULongLong )
    ) {
      output += item.toString();
    }
    if ( item.type() == QVariant::List ) {
      output += static_cast<QString>( toString( item.toList() ).get() );
    }
    if ( ( it + 1 ) != end )
      output += QLatin1String( ", " );
    ++it;
  }

  return output.append( QLatin1Char( ']' ) );
}

<|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "c7a/api/dia_base.hpp"
#include "c7a/engine/stage_builder.hpp"
#include "c7a/api/dia.hpp"
#include "c7a/api/context.hpp"

using namespace c7a::engine;

TEST(Stage, GetStagesFromBuilder) {
    using c7a::DIA;
    using c7a::Context;
    Context ctx;
    auto doubles = ctx.ReadFromFileSystem("tests/inputs/test1", [](std::string line) {
            return std::stod(line);
        });

    auto key_ex = [](double in) { return (int) in; };
    auto red_fn = [](double in1, double in2) { return in1 + in2; };
    auto map_fn = [](double input) {
            std::cout << "Map" << std::endl;
            return input;
        };

    auto fmap_fn = [](double input, std::function<void(double)> emit_func) {
            std::cout << "FlatMap" << std::endl;
            emit_func(input);
            emit_func(input);
        };

    auto duplicates = doubles.Map(map_fn);
    // auto duplicates2 = duplicates.Map(map_fn);
    auto doubles2 = doubles.Reduce(key_ex, red_fn);

    // auto duplicates3 = red_duplicates.Map(map_fn);
    auto red_duplicates2 = doubles2.Reduce(key_ex, red_fn);

    std::vector<Stage> result;
    FindStages(red_duplicates2.get_node(), result);
    for (auto s : result)
    {
        s.Run();
    }
}
<commit_msg>Use g_workpath for input files.<commit_after>#include "gtest/gtest.h"
#include <tests/c7a-tests.hpp>
#include "c7a/api/dia_base.hpp"
#include "c7a/engine/stage_builder.hpp"
#include "c7a/api/dia.hpp"
#include "c7a/api/context.hpp"

using namespace c7a::engine;

TEST(Stage, GetStagesFromBuilder) {
    using c7a::DIA;
    using c7a::Context;
    Context ctx;
    auto doubles = ctx.ReadFromFileSystem(
        g_workpath + "/inputs/test1",
        [](std::string line) {
            return std::stod(line);
        });

    auto key_ex = [](double in) { return (int) in; };
    auto red_fn = [](double in1, double in2) { return in1 + in2; };
    auto map_fn = [](double input) {
            std::cout << "Map" << std::endl;
            return input;
        };

    auto fmap_fn = [](double input, std::function<void(double)> emit_func) {
            std::cout << "FlatMap" << std::endl;
            emit_func(input);
            emit_func(input);
        };

    auto duplicates = doubles.Map(map_fn);
    // auto duplicates2 = duplicates.Map(map_fn);
    auto doubles2 = doubles.Reduce(key_ex, red_fn);

    // auto duplicates3 = red_duplicates.Map(map_fn);
    auto red_duplicates2 = doubles2.Reduce(key_ex, red_fn);

    std::vector<Stage> result;
    FindStages(red_duplicates2.get_node(), result);
    for (auto s : result)
    {
        s.Run();
    }
}
<|endoftext|>


<commit_before>#define LOG_NDEBUG 0
#define LOG_TAG "volume"
#include <utils/Log.h>
#include <cutils/properties.h>
#include <media/AudioSystem.h>

using namespace android;

#define VOLUME_MAX_LEVEL 100

int clampVolume(int v) {
  if (v < 0) return 0;
  if (v > VOLUME_MAX_LEVEL) return VOLUME_MAX_LEVEL;
  return v;
}

#define OK(expression) \
  { \
    status_t err = expression; \
    if (err != 0) { \
      ALOGE(#expression " failed: %d\n", err); \
      printf("Error: " #expression " failed: %d\n", err); \
      exit(1); \
    } \
  } \

int main(int argc, char **argv)
{
  int level = clampVolume(property_get_int32("persist.silk.volume.level", 0));
  bool mute = property_get_bool("persist.silk.volume.mute", 0) != 0;
  bool init = property_get_bool("silk.volume.init", 0) != 0;

  if (!init) {
    ALOGV("Initializing audio system");
    for (int as = AUDIO_STREAM_MIN; as < AUDIO_STREAM_PUBLIC_CNT; ++as) {
      OK(AudioSystem::initStreamVolume(static_cast<audio_stream_type_t>(as),
        0, VOLUME_MAX_LEVEL));
    }
    OK(AudioSystem::setMasterVolume(1.0));
    OK(AudioSystem::setMode(AUDIO_MODE_NORMAL));
    property_set("silk.volume.init", "true");
  }

  ALOGW("Volume: %.1f%% (%d of %d) mute=%d", 100.0 * level / VOLUME_MAX_LEVEL,
    level, VOLUME_MAX_LEVEL, mute);

  OK(AudioSystem::setMasterMute(mute));
  for (int as = AUDIO_STREAM_MIN; as < AUDIO_STREAM_PUBLIC_CNT; ++as) {
    OK(AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(as),
      level, AUDIO_DEVICE_OUT_SPEAKER));
  }

  return 0;
}
<commit_msg>Suppress -Wunused-parameter<commit_after>#define LOG_NDEBUG 0
#define LOG_TAG "volume"
#include <utils/Log.h>
#include <cutils/properties.h>
#include <media/AudioSystem.h>

using namespace android;

#define VOLUME_MAX_LEVEL 100

int clampVolume(int v) {
  if (v < 0) return 0;
  if (v > VOLUME_MAX_LEVEL) return VOLUME_MAX_LEVEL;
  return v;
}

#define OK(expression) \
  { \
    status_t err = expression; \
    if (err != 0) { \
      ALOGE(#expression " failed: %d\n", err); \
      printf("Error: " #expression " failed: %d\n", err); \
      exit(1); \
    } \
  } \

int main(int argc, char **argv)
{
  (void) argc;
  (void) argv;

  int level = clampVolume(property_get_int32("persist.silk.volume.level", 0));
  bool mute = property_get_bool("persist.silk.volume.mute", 0) != 0;
  bool init = property_get_bool("silk.volume.init", 0) != 0;

  if (!init) {
    ALOGV("Initializing audio system");
    for (int as = AUDIO_STREAM_MIN; as < AUDIO_STREAM_PUBLIC_CNT; ++as) {
      OK(AudioSystem::initStreamVolume(static_cast<audio_stream_type_t>(as),
        0, VOLUME_MAX_LEVEL));
    }
    OK(AudioSystem::setMasterVolume(1.0));
    OK(AudioSystem::setMode(AUDIO_MODE_NORMAL));
    property_set("silk.volume.init", "true");
  }

  ALOGW("Volume: %.1f%% (%d of %d) mute=%d", 100.0 * level / VOLUME_MAX_LEVEL,
    level, VOLUME_MAX_LEVEL, mute);

  OK(AudioSystem::setMasterMute(mute));
  for (int as = AUDIO_STREAM_MIN; as < AUDIO_STREAM_PUBLIC_CNT; ++as) {
    OK(AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(as),
      level, AUDIO_DEVICE_OUT_SPEAKER));
  }

  return 0;
}
<|endoftext|>


<commit_before>/* Definition of member functions of class Scanner */

#include "../headers/Scanner.hpp"

#include <utility>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>

using namespace std;

Scanner::Scanner() :
  m_lineNo(1),
  m_column(1),
  m_errors(0),
  m_sourceFile(),
  m_currentToken(0),
  m_nTokens(0),
  m_tokensLexemes(),
  m_keywordsMap(),
  m_errorReporter()
{
  m_keywordsMap["alfanumerico"] = KEYWORD_ALPHANUM;
  m_keywordsMap["canal"] =        KEYWORD_CHANNEL;
  m_keywordsMap["caracter"] =     KEYWORD_CHAR;
  m_keywordsMap["caso"] =         KEYWORD_CASE;
  m_keywordsMap["const"] =        KEYWORD_CONST;
  m_keywordsMap["continua"] =     KEYWORD_CONTINUE;
  m_keywordsMap["defecto"] =      KEYWORD_DEFAULT;
  m_keywordsMap["desde"] =        KEYWORD_FOR;
  m_keywordsMap["diferir"] =      KEYWORD_DIFFER;
  m_keywordsMap["div"] =          KEYWORD_DIV;
  m_keywordsMap["entero"] =       KEYWORD_INT;
  m_keywordsMap["enteros"] =      KEYWORD_UINT;
  m_keywordsMap["estructura"] =   KEYWORD_STRUCT;
  m_keywordsMap["funcion"] =      KEYWORD_FUNCTION;
  m_keywordsMap["importar"] =     KEYWORD_IMPORT;
  m_keywordsMap["interfaz"] =     KEYWORD_INTERFACE;
  m_keywordsMap["interrumpe"] =   KEYWORD_BREAK;
  m_keywordsMap["ir"] =           KEYWORD_GO;
  m_keywordsMap["ir_a"] =         KEYWORD_GOTO;
  m_keywordsMap["logico"] =       KEYWORD_LOGIC;
  m_keywordsMap["mapa"] =         KEYWORD_MAP;
  m_keywordsMap["mod"] =          KEYWORD_MOD;
  m_keywordsMap["paquete"] =      KEYWORD_PACKET;
  m_keywordsMap["principal"] =    KEYWORD_MAIN;
  m_keywordsMap["rango"] =        KEYWORD_RANGE;
  m_keywordsMap["real"] =         KEYWORD_REAL;
  m_keywordsMap["regresa"] =      KEYWORD_RETURN;
  m_keywordsMap["si"] =           KEYWORD_IF;
  m_keywordsMap["sino"] =         KEYWORD_ELSE;
  m_keywordsMap["selecciona"] =   KEYWORD_SELECT;
  m_keywordsMap["tipo"] =         KEYWORD_TYPE;
  m_keywordsMap["valor"] =        KEYWORD_SWITCH;
  m_keywordsMap["variable"] =     KEYWORD_VAR;
}

void Scanner::scan(const string& fileName) {
  m_sourceFile.open(fileName.c_str());

  if (m_sourceFile.is_open())
  {

    char currentChar;
    int nextState = 0, currentState = 0;
    TokenType_t token;
    string lexeme;

    string line;
    size_t lineLength;
    m_lineNo = 1;
    while (m_sourceFile.good() && m_errors < ERRORS_MAX_LIMIT) {
      getline(m_sourceFile, line);
      line += "\n";

      lineLength = line.length();
      m_column = 1;
      while (m_column <= lineLength && m_errors <= ERRORS_MAX_LIMIT) {
        currentChar = line.at(m_column - 1);
        nextState = automata[currentState][getTransitionIndex(currentChar)];

#ifdef DEBUG
        cout << "CState: " << setw(2) << currentState << "  NState: " <<
                setw(2) << nextState << "  TIndex: " <<
                setw(2) << getTransitionIndex(currentChar) <<
                " Char: ";
        if (!isspace(currentChar))
            cout << currentChar;
        else
            cout << ' ';
        cout << " : " << setw(3) << (int)currentChar << endl;
#endif

        if (nextState == STATE_ACCEPT_ERROR) {
          switch (currentState) {
            case 1 :
            case 2 : token = TOKEN_OCT;
              break;
            case 4 :
              token = TOKEN_HEX;
              break;
            case 5 :
              token = TOKEN_DEC;
              break;
            case 6 :
            case 11 :
              token = TOKEN_FLOAT;
              break;
            case 7 :
            case 26 :
              token = TOKEN_DELIMITER;
              break;
            case 8 :
              token = TOKEN_FLOAT;
              break;
            case 13 :
              token = TOKEN_STRING;
              break;
            case 14 :
            case 19 :
              token = TOKEN_ARITHOP;
              break;
            case 16 :
              token = TOKEN_LINECOMMENT;
              break;
            case 18 :
              token = TOKEN_MULTICOMMENT;
              break;
            case 22 :
            case 24 :
              token = TOKEN_LOGICOP;
              break;
            case 23 :
            case 27 :
              token = TOKEN_ASSIGNOP;
              break;
            case 25 :
            case 35 :
            case 36 :
              token = TOKEN_RELOP;
              break;
            case 28 :
              token = TOKEN_IDEN;
              if (m_keywordsMap.find(lexeme) != m_keywordsMap.end()) {
                token = TOKEN_KEYWORD;
              }
              else if (lexeme.compare("verdadero") == 0 ||
                       lexeme.compare("falso") == 0) {
                token = TOKEN_LOGICCONST;
              }
              break;
            case 29 :
              token = TOKEN_DELIMITER;
              break;
            case 33 :
              token = TOKEN_CHARCONST;
              break;
            default :
              cerr << "vecomp: error de estado siguiente" << endl;
              break;
          }

          if (token != TOKEN_LINECOMMENT && token != TOKEN_MULTICOMMENT)
            m_tokensLexemes.push(TokenLexeme(token, lexeme, m_lineNo,
                                             m_column - lexeme.length()));

          token = TOKEN_INVALID;
          lexeme = "";
          nextState = 0;
          --m_column;
        }
        else if (nextState == STATE_ERROR) {
#ifdef DEBUG
          cout << "calling lexicalerror" << currentState << " " <<
              currentChar << endl;
#endif
          m_errorReporter.writeLexicalError(currentState, currentChar, line,
                                            lexeme, m_lineNo, m_column);
          ++m_errors;

          token = TOKEN_INVALID;
          lexeme = "";
          nextState = 0;
        }
        else if ( isspace(currentChar) &&
                 (currentState == 12 || currentState == 15 ||
                  currentState == 17))
          lexeme += currentChar;
        else if (!isspace(currentChar))
          lexeme += currentChar;

        currentState = nextState;

        ++m_column;
      }
      ++m_lineNo;
      line = "";
    }

    if (!m_sourceFile.good()) {
#ifdef DEBUG
      cout << "final state: " << currentState << endl;
#endif
      if (currentState != 0 && !isTerminalState(currentState))
        m_errorReporter.writeLexicalError(currentState, currentChar, line,
                                          lexeme, m_lineNo, m_column);
    }

    m_nTokens = m_tokensLexemes.size();

    if (m_tokensLexemes.empty())
      m_errorReporter.writeError("archivo vacio");
  }
  else {
    m_errorReporter.writeError("error al abrir codigo fuente");
    ++m_errors;
  }
}

TokenLexeme Scanner::getNextTokenLexeme() {
  TokenLexeme temporal;
  if (!m_tokensLexemes.empty()) {
    temporal = m_tokensLexemes.front();
    m_tokensLexemes.pop();
  }
  return temporal;
}

Transition_t Scanner::getTransitionIndex(char character) {
  Transition_t transitionIndex = TRANS_ANY;

  if (isdigit(character)) {
    if (character == '0')
      transitionIndex = TRANS_ZERO;
    else if (character <= '7')
      transitionIndex = TRANS_OCT;
    else
      transitionIndex = TRANS_DEC;
  }
  else if (isalpha(character)) {
    if (tolower(character) == 'e')
      transitionIndex = TRANS_E;
    else if (tolower(character) == 'x')
      transitionIndex = TRANS_X;
    else if (tolower(character) <= 'f')
      transitionIndex = TRANS_HEX;
    else
      transitionIndex = TRANS_LETTER;
  }
  else {
    switch (character) {
      case '|' :
        transitionIndex = TRANS_PIPE;
        break;
      case '&' :
        transitionIndex = TRANS_AMPERS;
        break;
      case '!' :
        transitionIndex = TRANS_EXCLAMATION;
        break;
      case ' ' :
      case '\t' :
      case '\r' :
        transitionIndex = TRANS_SPACE;
        break;
      case '\n' :
        transitionIndex = TRANS_NEWLINE;
        break;
      case ',' :
      case ';' :
      case '(' :
      case ')' :
      case '[' :
      case ']' :
      case '{' :
      case '}' :
        transitionIndex = TRANS_DELIMITER;
        break;
      case '+' :
      case '-' :
        transitionIndex = TRANS_SIGN;
        break;
      case '*' :
        transitionIndex = TRANS_ASTERISK;
        break;
      case '/' :
        transitionIndex = TRANS_SLASH;
        break;
      case '%' :
      case '^' :
        transitionIndex = TRANS_ARITHMETIC;
        break;
      case ':' :
        transitionIndex = TRANS_COLON;
        break;
      case '=' :
        transitionIndex = TRANS_EQUAL;
        break;
      case '<' :
        transitionIndex = TRANS_LESSER;
        break;
      case '>' :
        transitionIndex = TRANS_GREATER;
        break;
      case '_' :
        transitionIndex = TRANS_UNDERSCORE;
        break;
      case '\'' :
        transitionIndex = TRANS_SQUOTE;
        break;
      case '\\' :
        transitionIndex = TRANS_BACKSLASH;
      case '"' :
        transitionIndex = TRANS_DQUOTE;
        break;
      case '.' :
        transitionIndex = TRANS_DOT;
        break;
      default :
        transitionIndex = TRANS_ANY;
        break;
    }
  }

  return transitionIndex;
}

int Scanner::getMaxTokens() const {
  return m_nTokens;
}

int Scanner::getErrors() const {
  return m_errors;
}

bool Scanner::isTerminalState(int state) {
  switch (state) {
    case 1 :
    case 2 :
    case 4 :
    case 5 :
    case 6 :
    case 7 :
    case 8 :
    case 11 :
    case 13 :
    case 14 :
    case 16 :
    case 18 :
    case 19 :
    case 22 :
    case 23 :
    case 24 :
    case 25 :
    case 26 :
    case 27 :
    case 28 :
    case 29 :
    case 33 :
    case 35 :
    case 36 :
      return true;
      break;
  }

  return false;
}

<commit_msg>added increment in errors count when file empty<commit_after>/* Definition of member functions of class Scanner */

#include "../headers/Scanner.hpp"

#include <utility>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>

using namespace std;

Scanner::Scanner() :
  m_lineNo(1),
  m_column(1),
  m_errors(0),
  m_sourceFile(),
  m_currentToken(0),
  m_nTokens(0),
  m_tokensLexemes(),
  m_keywordsMap(),
  m_errorReporter()
{
  m_keywordsMap["alfanumerico"] = KEYWORD_ALPHANUM;
  m_keywordsMap["canal"] =        KEYWORD_CHANNEL;
  m_keywordsMap["caracter"] =     KEYWORD_CHAR;
  m_keywordsMap["caso"] =         KEYWORD_CASE;
  m_keywordsMap["const"] =        KEYWORD_CONST;
  m_keywordsMap["continua"] =     KEYWORD_CONTINUE;
  m_keywordsMap["defecto"] =      KEYWORD_DEFAULT;
  m_keywordsMap["desde"] =        KEYWORD_FOR;
  m_keywordsMap["diferir"] =      KEYWORD_DIFFER;
  m_keywordsMap["div"] =          KEYWORD_DIV;
  m_keywordsMap["entero"] =       KEYWORD_INT;
  m_keywordsMap["enteros"] =      KEYWORD_UINT;
  m_keywordsMap["estructura"] =   KEYWORD_STRUCT;
  m_keywordsMap["funcion"] =      KEYWORD_FUNCTION;
  m_keywordsMap["importar"] =     KEYWORD_IMPORT;
  m_keywordsMap["interfaz"] =     KEYWORD_INTERFACE;
  m_keywordsMap["interrumpe"] =   KEYWORD_BREAK;
  m_keywordsMap["ir"] =           KEYWORD_GO;
  m_keywordsMap["ir_a"] =         KEYWORD_GOTO;
  m_keywordsMap["logico"] =       KEYWORD_LOGIC;
  m_keywordsMap["mapa"] =         KEYWORD_MAP;
  m_keywordsMap["mod"] =          KEYWORD_MOD;
  m_keywordsMap["paquete"] =      KEYWORD_PACKET;
  m_keywordsMap["principal"] =    KEYWORD_MAIN;
  m_keywordsMap["rango"] =        KEYWORD_RANGE;
  m_keywordsMap["real"] =         KEYWORD_REAL;
  m_keywordsMap["regresa"] =      KEYWORD_RETURN;
  m_keywordsMap["si"] =           KEYWORD_IF;
  m_keywordsMap["sino"] =         KEYWORD_ELSE;
  m_keywordsMap["selecciona"] =   KEYWORD_SELECT;
  m_keywordsMap["tipo"] =         KEYWORD_TYPE;
  m_keywordsMap["valor"] =        KEYWORD_SWITCH;
  m_keywordsMap["variable"] =     KEYWORD_VAR;
}

void Scanner::scan(const string& fileName) {
  m_sourceFile.open(fileName.c_str());

  if (m_sourceFile.is_open())
  {

    char currentChar;
    int nextState = 0, currentState = 0;
    TokenType_t token;
    string lexeme;

    string line;
    size_t lineLength;
    m_lineNo = 1;
    while (m_sourceFile.good() && m_errors < ERRORS_MAX_LIMIT) {
      getline(m_sourceFile, line);
      line += "\n";

      lineLength = line.length();
      m_column = 1;
      while (m_column <= lineLength && m_errors <= ERRORS_MAX_LIMIT) {
        currentChar = line.at(m_column - 1);
        nextState = automata[currentState][getTransitionIndex(currentChar)];

#ifdef DEBUG
        cout << "CState: " << setw(2) << currentState << "  NState: " <<
                setw(2) << nextState << "  TIndex: " <<
                setw(2) << getTransitionIndex(currentChar) <<
                " Char: ";
        if (!isspace(currentChar))
            cout << currentChar;
        else
            cout << ' ';
        cout << " : " << setw(3) << (int)currentChar << endl;
#endif

        if (nextState == STATE_ACCEPT_ERROR) {
          switch (currentState) {
            case 1 :
            case 2 : token = TOKEN_OCT;
              break;
            case 4 :
              token = TOKEN_HEX;
              break;
            case 5 :
              token = TOKEN_DEC;
              break;
            case 6 :
            case 11 :
              token = TOKEN_FLOAT;
              break;
            case 7 :
            case 26 :
              token = TOKEN_DELIMITER;
              break;
            case 8 :
              token = TOKEN_FLOAT;
              break;
            case 13 :
              token = TOKEN_STRING;
              break;
            case 14 :
            case 19 :
              token = TOKEN_ARITHOP;
              break;
            case 16 :
              token = TOKEN_LINECOMMENT;
              break;
            case 18 :
              token = TOKEN_MULTICOMMENT;
              break;
            case 22 :
            case 24 :
              token = TOKEN_LOGICOP;
              break;
            case 23 :
            case 27 :
              token = TOKEN_ASSIGNOP;
              break;
            case 25 :
            case 35 :
            case 36 :
              token = TOKEN_RELOP;
              break;
            case 28 :
              token = TOKEN_IDEN;
              if (m_keywordsMap.find(lexeme) != m_keywordsMap.end()) {
                token = TOKEN_KEYWORD;
              }
              else if (lexeme.compare("verdadero") == 0 ||
                       lexeme.compare("falso") == 0) {
                token = TOKEN_LOGICCONST;
              }
              break;
            case 29 :
              token = TOKEN_DELIMITER;
              break;
            case 33 :
              token = TOKEN_CHARCONST;
              break;
            default :
              cerr << "vecomp: error de estado siguiente" << endl;
              break;
          }

          if (token != TOKEN_LINECOMMENT && token != TOKEN_MULTICOMMENT)
            m_tokensLexemes.push(TokenLexeme(token, lexeme, m_lineNo,
                                             m_column - lexeme.length()));

          token = TOKEN_INVALID;
          lexeme = "";
          nextState = 0;
          --m_column;
        }
        else if (nextState == STATE_ERROR) {
#ifdef DEBUG
          cout << "calling lexicalerror" << currentState << " " <<
              currentChar << endl;
#endif
          m_errorReporter.writeLexicalError(currentState, currentChar, line,
                                            lexeme, m_lineNo, m_column);
          ++m_errors;

          token = TOKEN_INVALID;
          lexeme = "";
          nextState = 0;
        }
        else if ( isspace(currentChar) &&
                 (currentState == 12 || currentState == 15 ||
                  currentState == 17))
          lexeme += currentChar;
        else if (!isspace(currentChar))
          lexeme += currentChar;

        currentState = nextState;

        ++m_column;
      }
      ++m_lineNo;
      line = "";
    }

    if (!m_sourceFile.good()) {
#ifdef DEBUG
      cout << "final state: " << currentState << endl;
#endif
      if (currentState != 0 && !isTerminalState(currentState))
        m_errorReporter.writeLexicalError(currentState, currentChar, line,
                                          lexeme, m_lineNo, m_column);
    }

    m_nTokens = m_tokensLexemes.size();

    if (m_tokensLexemes.empty()) {
      m_errorReporter.writeError("archivo vacio");
      ++m_errors;
    }
  }
  else {
    m_errorReporter.writeError("error al abrir codigo fuente");
    ++m_errors;
  }
}

TokenLexeme Scanner::getNextTokenLexeme() {
  TokenLexeme temporal;
  if (!m_tokensLexemes.empty()) {
    temporal = m_tokensLexemes.front();
    m_tokensLexemes.pop();
  }
  return temporal;
}

Transition_t Scanner::getTransitionIndex(char character) {
  Transition_t transitionIndex = TRANS_ANY;

  if (isdigit(character)) {
    if (character == '0')
      transitionIndex = TRANS_ZERO;
    else if (character <= '7')
      transitionIndex = TRANS_OCT;
    else
      transitionIndex = TRANS_DEC;
  }
  else if (isalpha(character)) {
    if (tolower(character) == 'e')
      transitionIndex = TRANS_E;
    else if (tolower(character) == 'x')
      transitionIndex = TRANS_X;
    else if (tolower(character) <= 'f')
      transitionIndex = TRANS_HEX;
    else
      transitionIndex = TRANS_LETTER;
  }
  else {
    switch (character) {
      case '|' :
        transitionIndex = TRANS_PIPE;
        break;
      case '&' :
        transitionIndex = TRANS_AMPERS;
        break;
      case '!' :
        transitionIndex = TRANS_EXCLAMATION;
        break;
      case ' ' :
      case '\t' :
      case '\r' :
        transitionIndex = TRANS_SPACE;
        break;
      case '\n' :
        transitionIndex = TRANS_NEWLINE;
        break;
      case ',' :
      case ';' :
      case '(' :
      case ')' :
      case '[' :
      case ']' :
      case '{' :
      case '}' :
        transitionIndex = TRANS_DELIMITER;
        break;
      case '+' :
      case '-' :
        transitionIndex = TRANS_SIGN;
        break;
      case '*' :
        transitionIndex = TRANS_ASTERISK;
        break;
      case '/' :
        transitionIndex = TRANS_SLASH;
        break;
      case '%' :
      case '^' :
        transitionIndex = TRANS_ARITHMETIC;
        break;
      case ':' :
        transitionIndex = TRANS_COLON;
        break;
      case '=' :
        transitionIndex = TRANS_EQUAL;
        break;
      case '<' :
        transitionIndex = TRANS_LESSER;
        break;
      case '>' :
        transitionIndex = TRANS_GREATER;
        break;
      case '_' :
        transitionIndex = TRANS_UNDERSCORE;
        break;
      case '\'' :
        transitionIndex = TRANS_SQUOTE;
        break;
      case '\\' :
        transitionIndex = TRANS_BACKSLASH;
      case '"' :
        transitionIndex = TRANS_DQUOTE;
        break;
      case '.' :
        transitionIndex = TRANS_DOT;
        break;
      default :
        transitionIndex = TRANS_ANY;
        break;
    }
  }

  return transitionIndex;
}

int Scanner::getMaxTokens() const {
  return m_nTokens;
}

int Scanner::getErrors() const {
  return m_errors;
}

bool Scanner::isTerminalState(int state) {
  switch (state) {
    case 1 :
    case 2 :
    case 4 :
    case 5 :
    case 6 :
    case 7 :
    case 8 :
    case 11 :
    case 13 :
    case 14 :
    case 16 :
    case 18 :
    case 19 :
    case 22 :
    case 23 :
    case 24 :
    case 25 :
    case 26 :
    case 27 :
    case 28 :
    case 29 :
    case 33 :
    case 35 :
    case 36 :
      return true;
      break;
  }

  return false;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#include "native-stack.hh"
#include "native-stack-impl.hh"
#include "net.hh"
#include "ip.hh"
#include "tcp-stack.hh"
#include "udp.hh"
#include "virtio.hh"
#include "xenfront.hh"
#include "proxy.hh"
#include "dhcp.hh"
#include <memory>
#include <queue>
#ifdef HAVE_OSV
#include <osv/firmware.hh>
#include <gnu/libc-version.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

namespace net {

// native_network_stack
class native_network_stack : public network_stack {
    static std::unique_ptr<native_network_stack> _s;
    interface _netif;
    ipv4 _inet;
    udp_v4 _udp;
    bool _dhcp = false;
    promise<> _config;
    timer _timer;

    void on_dhcp(bool, const dhcp::lease &, bool);

    using tcp4 = tcp<ipv4_traits>;
public:
    explicit native_network_stack(boost::program_options::variables_map opts);
    virtual server_socket listen(socket_address sa, listen_options opt) override;
    virtual udp_channel make_udp_channel(ipv4_addr addr) override;
    virtual future<> initialize() override;
    static std::unique_ptr<network_stack> create(boost::program_options::variables_map opts) {
        return std::make_unique<native_network_stack>(opts);
    }
    virtual bool has_per_core_namespace() override { return true; };
    friend class native_server_socket_impl<tcp4>;
};

udp_channel
native_network_stack::make_udp_channel(ipv4_addr addr) {
    return _udp.make_channel(addr);
}

enum class xen_info {
    nonxen = 0,
    userspace = 1,
    osv = 2,
};

#ifdef HAVE_XEN
static xen_info is_xen()
{
    struct stat buf;
    if (!stat("/proc/xen", &buf) || !stat("/dev/xen", &buf)) {
        return xen_info::userspace;
    }

#ifdef HAVE_OSV
    const char *str = gnu_get_libc_release();
    if (std::string("OSv") != str) {
        return xen_info::nonxen;
    }
    auto firmware = osv::firmware_vendor();
    if (firmware == "Xen") {
        return xen_info::osv;
    }
#endif

    return xen_info::nonxen;
}
#endif

std::unique_ptr<net::device> create_native_net_device(boost::program_options::variables_map opts) {

    if (!smp::main_thread()) {
        return create_proxy_net_device(opts);
    }

#ifdef HAVE_XEN
    auto xen = is_xen();
    if (xen != xen_info::nonxen) {
        return xen::create_xenfront_net_device(opts, xen == xen_info::userspace);
    }
#endif
    return create_virtio_net_device(opts["tap-device"].as<std::string>(), opts);
}

void
add_native_net_options_description(boost::program_options::options_description &opts) {

#ifdef HAVE_XEN
    auto xen = is_xen();
    if (xen != xen_info::nonxen) {
        opts.add(xen::get_xenfront_net_options_description());
        return;
    }
#endif
    opts.add(get_virtio_net_options_description());
}

native_network_stack::native_network_stack(boost::program_options::variables_map opts)
    : _netif(create_native_net_device(opts))
    , _inet(&_netif)
    , _udp(_inet) {
    _inet.set_host_address(ipv4_address(opts["host-ipv4-addr"].as<std::string>()));
    _inet.set_gw_address(ipv4_address(opts["gw-ipv4-addr"].as<std::string>()));
    _inet.set_netmask_address(ipv4_address(opts["netmask-ipv4-addr"].as<std::string>()));
    _udp.set_queue_size(opts["udpv4-queue-size"].as<int>());
    _dhcp = opts["host-ipv4-addr"].defaulted()
            && opts["gw-ipv4-addr"].defaulted()
            && opts["netmask-ipv4-addr"].defaulted() && opts["dhcp"].as<bool>();
}

server_socket
native_network_stack::listen(socket_address sa, listen_options opts) {
    assert(sa.as_posix_sockaddr().sa_family == AF_INET);
    return tcpv4_listen(_inet.get_tcp(), ntohs(sa.as_posix_sockaddr_in().sin_port), opts);
}

using namespace std::chrono_literals;

void native_network_stack::on_dhcp(bool success, const dhcp::lease & res, bool is_renew) {
    if (success) {
        _inet.set_host_address(res.ip);
        _inet.set_gw_address(res.gateway);
        _inet.set_netmask_address(res.netmask);
    }
    // Signal waiters.
    if (!is_renew) {
        _config.set_value();
    }

    if (smp::main_thread()) {
        // And the other cpus, which, in the case of initial discovery,
        // will be waiting for us.
        for (unsigned i = 1; i < smp::count; i++) {
            smp::submit_to(i, [success, res, is_renew]() {
                auto & ns = static_cast<native_network_stack&>(engine.net());
                ns.on_dhcp(success, res, is_renew);
            });
        }
        if (success) {
            // And set up to renew the lease later on.
            _timer.set_callback(
                    [this, res]() {
                        _config = promise<>();
                        shared_ptr<dhcp> d = make_shared<dhcp>(_inet);
                        d->renew(res).then([this, d](bool success, const dhcp::lease & res) {
                                    on_dhcp(success, res, true);
                                });
                    });
            _timer.arm(
                    std::chrono::duration_cast<clock_type::duration>(
                            res.lease_time));
        }
    }
}

future<> native_network_stack::initialize() {
    return network_stack::initialize().then([this]() {
        if (!_dhcp) {
            return make_ready_future();
        }
        // Only run actual discover on main cpu.
        // All other cpus must simply for main thread to complete and signal them.
        if (smp::main_thread()) {
            shared_ptr<dhcp> d = make_shared<dhcp>(_inet);
            return d->discover().then([this, d](bool success, const dhcp::lease & res) {
                on_dhcp(success, res, false);
            });
        }
        return _config.get_future();
    });
}

std::unique_ptr<native_network_stack> native_network_stack::_s;

boost::program_options::options_description nns_options() {
    boost::program_options::options_description opts(
            "Native networking stack options");
    opts.add_options()
        ("tap-device",
                boost::program_options::value<std::string>()->default_value("tap0"),
                "tap device to connect to")
        ("host-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("192.168.122.2"),
                "static IPv4 address to use")
        ("gw-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("192.168.122.1"),
                "static IPv4 gateway to use")
        ("netmask-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("255.255.255.0"),
                "static IPv4 netmask to use")
        ("udpv4-queue-size",
                boost::program_options::value<int>()->default_value(udp_v4::default_queue_size),
                "Default size of the UDPv4 per-channel packet queue")
        ("dhcp",
                boost::program_options::value<bool>()->default_value(true),
                        "Use DHCP discovery")
        ;

    add_native_net_options_description(opts);
    return opts;
}

network_stack_registrator nns_registrator{
    "native", nns_options(), native_network_stack::create
};

}
<commit_msg>net: remove unused variable in native_network_stack<commit_after>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#include "native-stack.hh"
#include "native-stack-impl.hh"
#include "net.hh"
#include "ip.hh"
#include "tcp-stack.hh"
#include "udp.hh"
#include "virtio.hh"
#include "xenfront.hh"
#include "proxy.hh"
#include "dhcp.hh"
#include <memory>
#include <queue>
#ifdef HAVE_OSV
#include <osv/firmware.hh>
#include <gnu/libc-version.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

namespace net {

// native_network_stack
class native_network_stack : public network_stack {
    interface _netif;
    ipv4 _inet;
    udp_v4 _udp;
    bool _dhcp = false;
    promise<> _config;
    timer _timer;

    void on_dhcp(bool, const dhcp::lease &, bool);

    using tcp4 = tcp<ipv4_traits>;
public:
    explicit native_network_stack(boost::program_options::variables_map opts);
    virtual server_socket listen(socket_address sa, listen_options opt) override;
    virtual udp_channel make_udp_channel(ipv4_addr addr) override;
    virtual future<> initialize() override;
    static std::unique_ptr<network_stack> create(boost::program_options::variables_map opts) {
        return std::make_unique<native_network_stack>(opts);
    }
    virtual bool has_per_core_namespace() override { return true; };
    friend class native_server_socket_impl<tcp4>;
};

udp_channel
native_network_stack::make_udp_channel(ipv4_addr addr) {
    return _udp.make_channel(addr);
}

enum class xen_info {
    nonxen = 0,
    userspace = 1,
    osv = 2,
};

#ifdef HAVE_XEN
static xen_info is_xen()
{
    struct stat buf;
    if (!stat("/proc/xen", &buf) || !stat("/dev/xen", &buf)) {
        return xen_info::userspace;
    }

#ifdef HAVE_OSV
    const char *str = gnu_get_libc_release();
    if (std::string("OSv") != str) {
        return xen_info::nonxen;
    }
    auto firmware = osv::firmware_vendor();
    if (firmware == "Xen") {
        return xen_info::osv;
    }
#endif

    return xen_info::nonxen;
}
#endif

std::unique_ptr<net::device> create_native_net_device(boost::program_options::variables_map opts) {

    if (!smp::main_thread()) {
        return create_proxy_net_device(opts);
    }

#ifdef HAVE_XEN
    auto xen = is_xen();
    if (xen != xen_info::nonxen) {
        return xen::create_xenfront_net_device(opts, xen == xen_info::userspace);
    }
#endif
    return create_virtio_net_device(opts["tap-device"].as<std::string>(), opts);
}

void
add_native_net_options_description(boost::program_options::options_description &opts) {

#ifdef HAVE_XEN
    auto xen = is_xen();
    if (xen != xen_info::nonxen) {
        opts.add(xen::get_xenfront_net_options_description());
        return;
    }
#endif
    opts.add(get_virtio_net_options_description());
}

native_network_stack::native_network_stack(boost::program_options::variables_map opts)
    : _netif(create_native_net_device(opts))
    , _inet(&_netif)
    , _udp(_inet) {
    _inet.set_host_address(ipv4_address(opts["host-ipv4-addr"].as<std::string>()));
    _inet.set_gw_address(ipv4_address(opts["gw-ipv4-addr"].as<std::string>()));
    _inet.set_netmask_address(ipv4_address(opts["netmask-ipv4-addr"].as<std::string>()));
    _udp.set_queue_size(opts["udpv4-queue-size"].as<int>());
    _dhcp = opts["host-ipv4-addr"].defaulted()
            && opts["gw-ipv4-addr"].defaulted()
            && opts["netmask-ipv4-addr"].defaulted() && opts["dhcp"].as<bool>();
}

server_socket
native_network_stack::listen(socket_address sa, listen_options opts) {
    assert(sa.as_posix_sockaddr().sa_family == AF_INET);
    return tcpv4_listen(_inet.get_tcp(), ntohs(sa.as_posix_sockaddr_in().sin_port), opts);
}

using namespace std::chrono_literals;

void native_network_stack::on_dhcp(bool success, const dhcp::lease & res, bool is_renew) {
    if (success) {
        _inet.set_host_address(res.ip);
        _inet.set_gw_address(res.gateway);
        _inet.set_netmask_address(res.netmask);
    }
    // Signal waiters.
    if (!is_renew) {
        _config.set_value();
    }

    if (smp::main_thread()) {
        // And the other cpus, which, in the case of initial discovery,
        // will be waiting for us.
        for (unsigned i = 1; i < smp::count; i++) {
            smp::submit_to(i, [success, res, is_renew]() {
                auto & ns = static_cast<native_network_stack&>(engine.net());
                ns.on_dhcp(success, res, is_renew);
            });
        }
        if (success) {
            // And set up to renew the lease later on.
            _timer.set_callback(
                    [this, res]() {
                        _config = promise<>();
                        shared_ptr<dhcp> d = make_shared<dhcp>(_inet);
                        d->renew(res).then([this, d](bool success, const dhcp::lease & res) {
                                    on_dhcp(success, res, true);
                                });
                    });
            _timer.arm(
                    std::chrono::duration_cast<clock_type::duration>(
                            res.lease_time));
        }
    }
}

future<> native_network_stack::initialize() {
    return network_stack::initialize().then([this]() {
        if (!_dhcp) {
            return make_ready_future();
        }
        // Only run actual discover on main cpu.
        // All other cpus must simply for main thread to complete and signal them.
        if (smp::main_thread()) {
            shared_ptr<dhcp> d = make_shared<dhcp>(_inet);
            return d->discover().then([this, d](bool success, const dhcp::lease & res) {
                on_dhcp(success, res, false);
            });
        }
        return _config.get_future();
    });
}

boost::program_options::options_description nns_options() {
    boost::program_options::options_description opts(
            "Native networking stack options");
    opts.add_options()
        ("tap-device",
                boost::program_options::value<std::string>()->default_value("tap0"),
                "tap device to connect to")
        ("host-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("192.168.122.2"),
                "static IPv4 address to use")
        ("gw-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("192.168.122.1"),
                "static IPv4 gateway to use")
        ("netmask-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("255.255.255.0"),
                "static IPv4 netmask to use")
        ("udpv4-queue-size",
                boost::program_options::value<int>()->default_value(udp_v4::default_queue_size),
                "Default size of the UDPv4 per-channel packet queue")
        ("dhcp",
                boost::program_options::value<bool>()->default_value(true),
                        "Use DHCP discovery")
        ;

    add_native_net_options_description(opts);
    return opts;
}

network_stack_registrator nns_registrator{
    "native", nns_options(), native_network_stack::create
};

}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _WIN32
#pragma warning( 4: 4786)
#endif

#include <iostream>

#include "BZAdminClient.h"
#include "version.h"

BZAdminClient::BZAdminClient(std::string callsign, std::string host,
			     int port, BZAdminUI* bzInterface)
  : myTeam(ObserverTeam), sLink(Address(host), port), valid(false),
    ui(bzInterface) {

  if (sLink.getState() != ServerLink::Okay) {
    std::cerr<<"Could not connect to "<<host<<':'<<port<<'.'<<std::endl;
    return;
  }
  sLink.sendEnter(TankPlayer, myTeam, callsign.c_str(), "");
  if (sLink.getState() != ServerLink::Okay) {
    std::cerr<<"Rejected."<<std::endl;
    return;
  }
  valid = true;
}

PlayerId BZAdminClient::getMyId() {
  return sLink.getId();
}

BZAdminClient::ServerCode BZAdminClient::getServerString(std::string& str) {
  uint16_t code, len;
  char inbuf[MaxPacketLen];
  int e;
  std::string dstName, srcName;
  str = "";

  /* read until we have a package that we want, or until there are no more
     packages for 100 ms */
  while ((e = sLink.read(code, len, inbuf, 100)) == 1) {
    void* vbuf = inbuf;
    PlayerId p;
    switch (code) {

    case MsgAddPlayer:

      vbuf = nboUnpackUByte(vbuf, p);

      uint16_t team, type, wins, losses, tks;
      char callsign[CallSignLen];
      char email[EmailLen];
      vbuf = nboUnpackUShort(vbuf, type);
      vbuf = nboUnpackUShort(vbuf, team);
      vbuf = nboUnpackUShort(vbuf, wins);
      vbuf = nboUnpackUShort(vbuf, losses);
      vbuf = nboUnpackUShort(vbuf, tks);
      vbuf = nboUnpackString(vbuf, callsign, CallSignLen);
      vbuf = nboUnpackString(vbuf, email, EmailLen);
      players[p] = callsign;
      if (p != sLink.getId() && ui != NULL)
	ui->addedPlayer(p);
      str = str + "*** '" + callsign + "' joined the game.";
      return GotMessage;

    case MsgRemovePlayer:
      vbuf = nboUnpackUByte(vbuf, p);
      str = str + "*** '" + players[p] + "' left the game.";
      if (ui != NULL)
	ui->removingPlayer(p);
      players.erase(p);
      return GotMessage;

    case MsgSuperKill:
      return Superkilled;

    case MsgMessage:

      // unpack the message header
      PlayerId src;
      PlayerId dst;
      PlayerId me = sLink.getId();
      vbuf = nboUnpackUByte(vbuf, src);
      vbuf = nboUnpackUByte(vbuf, dst);

      // is the message for me?
      TeamColor dstTeam = (dst >= 244 && dst <= 250 ?
			   TeamColor(250 - dst) : NoTeam);
      if (dst == AllPlayers || src == me || dst == me || dstTeam == myTeam) {
	str = (char*)vbuf;
	if (str == "CLIENTQUERY") {
	  sendMessage(std::string("bzadmin ") + getAppVersion(), src);
	  if (ui != NULL)
	    ui->outputMessage("    [Sent versioninfo per request]");
	}
	else {
	  str = formatMessage((char*)vbuf, src, dst, dstTeam, me);
	  return GotMessage;
	}
      }
    }
  }

  if (sLink.getState() != ServerLink::Okay) {
    return CommError;
  }

  return NoMessage;
}

std::map<PlayerId, std::string>& BZAdminClient::getPlayers() {
  return players;
}

bool BZAdminClient::isValid() const {
  return valid;
}

void BZAdminClient::runLoop() {
  std::string str;
  ServerCode what(NoMessage);
  while (true) {
    while ((what = getServerString(str)) == GotMessage) {
      if (ui != NULL)
	ui->outputMessage(str);
    }
    if (what == Superkilled || what == CommError)
      break;
    if (ui != NULL && ui->checkCommand(str)) {
      if (str == "/quit")
	break;
      sendMessage(str, ui->getTarget());
    }
  }

  // why did we leave the loop?
  switch (what) {
  case Superkilled:
    if (ui != NULL)
      ui->outputMessage("--- ERROR: Server forced disconnect");
    break;
  case CommError:
    if (ui != NULL)
      ui->outputMessage("--- ERROR: Connection to server lost");
    break;
  default:
    waitForServer();
  }
}

void BZAdminClient::sendMessage(const std::string& msg,
				PlayerId target) {
  char buffer[MessageLen];
  char buffer2[1 + MessageLen];
  void* buf = buffer2;

  buf = nboPackUByte(buf, target);
  memset(buffer, 0, MessageLen);
  strncpy(buffer, msg.c_str(), MessageLen - 1);
  nboPackString(buffer2 + 1, buffer, MessageLen);
  sLink.send(MsgMessage, sizeof(buffer2), buffer2);
}

std::string BZAdminClient::formatMessage(const std::string& msg, PlayerId src,
				    PlayerId dst, TeamColor dstTeam,
				    PlayerId me) {
  std::string formatted = "    ";

  // get sender and receiver
  const std::string srcName = (src == ServerPlayer ? "SERVER" :
			  (players.count(src) ? players[src] : "(UNKNOWN)"));
  const std::string dstName = (players.count(dst) ? players[dst] : "(UNKNOWN)");

  // direct message to or from me
  if (dst == me || players.count(dst)) {
    if (!(src == me && dst == me)) {
      formatted += "[";
      if (src == me) {
	formatted += "->";
	formatted += dstName;
      }
      else {
	formatted += srcName;
	formatted += "->";
      }
      formatted += "] ";
    }
    formatted += msg;
  }

  // public or team message
  else {
    if (dstTeam != NoTeam)
      formatted += "[Team] ";
    formatted += srcName;
    formatted += ": ";
    formatted += msg;
  }

  return formatted;
}

void BZAdminClient::setUI(BZAdminUI* bzInterface) {
  ui = bzInterface;
}

void BZAdminClient::waitForServer() {
  // we need to know that the server has processed all our messages
  // send a private message to ourself and wait for it to come back
  // this assumes that the order of messages isn't changed along the way
  PlayerId me = sLink.getId();
  if (sLink.getState() == ServerLink::Okay) {
    sendMessage("bzadminping", me);
    std::string expected = formatMessage("bzadminping", me, me, NoTeam, me);
    std::string str;
    do {
      getServerString(str);
    } while (str != expected);
  }
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>quell some deep compiler moaning (header error) on os x gcc 3.3<commit_after>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _WIN32
#pragma warning( 4: 4786)
#endif

#include <iostream>

#include "BZAdminClient.h"
#include "version.h"

BZAdminClient::BZAdminClient(std::string callsign, std::string host,
			     int port, BZAdminUI* bzInterface)
  : myTeam(ObserverTeam), sLink(Address(host), port), valid(false),
    ui(bzInterface) {

  if (sLink.getState() != ServerLink::Okay) {
    std::cerr<<"Could not connect to "<<host<<':'<<port<<'.'<<std::endl;
    return;
  }
  sLink.sendEnter(TankPlayer, myTeam, callsign.c_str(), "");
  if (sLink.getState() != ServerLink::Okay) {
    std::cerr<<"Rejected."<<std::endl;
    return;
  }
  valid = true;
}

PlayerId BZAdminClient::getMyId() {
  return sLink.getId();
}

BZAdminClient::ServerCode BZAdminClient::getServerString(std::string& str) {
  uint16_t code, len;
  char inbuf[MaxPacketLen];
  int e;
  std::string dstName, srcName;
  str = "";

  /* read until we have a package that we want, or until there are no more
     packages for 100 ms */
  while ((e = sLink.read(code, len, inbuf, 100)) == 1) {
    void* vbuf = inbuf;
    PlayerId p;
    switch (code) {

    case MsgAddPlayer:

      vbuf = nboUnpackUByte(vbuf, p);

      uint16_t team, type, wins, losses, tks;
      char callsign[CallSignLen];
      char email[EmailLen];
      vbuf = nboUnpackUShort(vbuf, type);
      vbuf = nboUnpackUShort(vbuf, team);
      vbuf = nboUnpackUShort(vbuf, wins);
      vbuf = nboUnpackUShort(vbuf, losses);
      vbuf = nboUnpackUShort(vbuf, tks);
      vbuf = nboUnpackString(vbuf, callsign, CallSignLen);
      vbuf = nboUnpackString(vbuf, email, EmailLen);
      players[p].clear();
      players[p].append(callsign);
      if (p != sLink.getId() && ui != NULL)
	ui->addedPlayer(p);
      str = str + "*** '" + callsign + "' joined the game.";
      return GotMessage;

    case MsgRemovePlayer:
      vbuf = nboUnpackUByte(vbuf, p);
      str = str + "*** '" + players[p] + "' left the game.";
      if (ui != NULL)
	ui->removingPlayer(p);
      players.erase(p);
      return GotMessage;

    case MsgSuperKill:
      return Superkilled;

    case MsgMessage:

      // unpack the message header
      PlayerId src;
      PlayerId dst;
      PlayerId me = sLink.getId();
      vbuf = nboUnpackUByte(vbuf, src);
      vbuf = nboUnpackUByte(vbuf, dst);

      // is the message for me?
      TeamColor dstTeam = (dst >= 244 && dst <= 250 ?
			   TeamColor(250 - dst) : NoTeam);
      if (dst == AllPlayers || src == me || dst == me || dstTeam == myTeam) {
	str = (char*)vbuf;
	if (str == "CLIENTQUERY") {
	  sendMessage(std::string("bzadmin ") + getAppVersion(), src);
	  if (ui != NULL)
	    ui->outputMessage("    [Sent versioninfo per request]");
	}
	else {
	  str = formatMessage((char*)vbuf, src, dst, dstTeam, me);
	  return GotMessage;
	}
      }
    }
  }

  if (sLink.getState() != ServerLink::Okay) {
    return CommError;
  }

  return NoMessage;
}

std::map<PlayerId, std::string>& BZAdminClient::getPlayers() {
  return players;
}

bool BZAdminClient::isValid() const {
  return valid;
}

void BZAdminClient::runLoop() {
  std::string str;
  ServerCode what(NoMessage);
  while (true) {
    while ((what = getServerString(str)) == GotMessage) {
      if (ui != NULL)
	ui->outputMessage(str);
    }
    if (what == Superkilled || what == CommError)
      break;
    if (ui != NULL && ui->checkCommand(str)) {
      if (str == "/quit")
	break;
      sendMessage(str, ui->getTarget());
    }
  }

  // why did we leave the loop?
  switch (what) {
  case Superkilled:
    if (ui != NULL)
      ui->outputMessage("--- ERROR: Server forced disconnect");
    break;
  case CommError:
    if (ui != NULL)
      ui->outputMessage("--- ERROR: Connection to server lost");
    break;
  default:
    waitForServer();
  }
}

void BZAdminClient::sendMessage(const std::string& msg,
				PlayerId target) {
  char buffer[MessageLen];
  char buffer2[1 + MessageLen];
  void* buf = buffer2;

  buf = nboPackUByte(buf, target);
  memset(buffer, 0, MessageLen);
  strncpy(buffer, msg.c_str(), MessageLen - 1);
  nboPackString(buffer2 + 1, buffer, MessageLen);
  sLink.send(MsgMessage, sizeof(buffer2), buffer2);
}

std::string BZAdminClient::formatMessage(const std::string& msg, PlayerId src,
				    PlayerId dst, TeamColor dstTeam,
				    PlayerId me) {
  std::string formatted = "    ";

  // get sender and receiver
  const std::string srcName = (src == ServerPlayer ? "SERVER" :
			  (players.count(src) ? players[src] : "(UNKNOWN)"));
  const std::string dstName = (players.count(dst) ? players[dst] : "(UNKNOWN)");

  // direct message to or from me
  if (dst == me || players.count(dst)) {
    if (!(src == me && dst == me)) {
      formatted += "[";
      if (src == me) {
	formatted += "->";
	formatted += dstName;
      }
      else {
	formatted += srcName;
	formatted += "->";
      }
      formatted += "] ";
    }
    formatted += msg;
  }

  // public or team message
  else {
    if (dstTeam != NoTeam)
      formatted += "[Team] ";
    formatted += srcName;
    formatted += ": ";
    formatted += msg;
  }

  return formatted;
}

void BZAdminClient::setUI(BZAdminUI* bzInterface) {
  ui = bzInterface;
}

void BZAdminClient::waitForServer() {
  // we need to know that the server has processed all our messages
  // send a private message to ourself and wait for it to come back
  // this assumes that the order of messages isn't changed along the way
  PlayerId me = sLink.getId();
  if (sLink.getState() == ServerLink::Okay) {
    sendMessage("bzadminping", me);
    std::string expected = formatMessage("bzadminping", me, me, NoTeam, me);
    std::string str;
    do {
      getServerString(str);
    } while (str != expected);
  }
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2011-2013 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include "utils.h"

#ifdef HAVE_PTHREAD_NAMING
#define NAME_THREAD_USING_PTHREAD
#ifdef HAVE_PTHREAD_SET_NAME_NP
#ifdef NDEBUG
// The mechanism only make sense in debugging mode.
#undef NAME_THREAD_USING_PTHREAD
#endif
#endif
#endif

#ifdef HAVE_SETPROCTITLE
#define NAME_THREAD_USING_SETPROCTITLE
#endif

#ifdef __linux__
#define NAME_THREAD_USING_PRCTL
#endif

#if defined(_WIN32) || defined(_WIN64)
#ifndef NDEBUG
// The mechanism only make sense in debugging mode.
#define NAME_THREAD_USING_WIN32
#endif
#endif

#ifdef NAME_THREAD_USING_PTHREAD
#include <pthread.h>
#ifdef HAVE_PTHREAD_SET_NAME_NP
#include <pthread_np.h>
#endif
#endif

#ifdef NAME_THREAD_USING_PRCTL
#include <sys/prctl.h>
#endif

#if defined(_WIN32) || defined(_WIN64)
#include <boost/scoped_array.hpp>

#include <windows.h>
#else
#include <cstdlib>
#endif

/**
 * \file utils.cxx
 *
 * \brief Implementation of pipeline utilities.
 */

namespace vistk
{

#ifdef NAME_THREAD_USING_PRCTL
static bool name_thread_prctl(thread_name_t const& name);
#endif

#ifdef NAME_THREAD_USING_SETPROCTITLE
static bool name_thread_setproctitle(thread_name_t const& name);
#endif

#ifdef NAME_THREAD_USING_PTHREAD
static bool name_thread_pthread(thread_name_t const& name);
#endif

#ifdef NAME_THREAD_USING_WIN32
static bool name_thread_win32(thread_name_t const& name);
#endif

bool
name_thread(thread_name_t const& name)
{
  bool ret = false;

#ifdef NAME_THREAD_USING_PRCTL
  if (!ret)
  {
    ret = name_thread_prctl(name);
  }
#endif

#ifdef NAME_THREAD_USING_SETPROCTITLE
  if (!ret)
  {
    ret = name_thread_setproctitle(name);
  }
#endif

#ifdef NAME_THREAD_USING_PTHREAD
  if (!ret)
  {
    ret = name_thread_pthread(name);
  }
#endif

#ifdef NAME_THREAD_USING_WIN32
  if (!ret)
  {
    ret = name_thread_win32(name);
  }
#endif

  return ret;
}

envvar_value_t
get_envvar(envvar_name_t const& name)
{
  envvar_value_t value;

#if defined(_WIN32) || defined(_WIN64)
  char const* const name_cstr = name.c_str();

  DWORD sz = GetEnvironmentVariable(name_cstr, NULL, 0);

  if (sz)
  {
    typedef boost::scoped_array<char> raw_envvar_value_t;
    raw_envvar_value_t const envvalue(new char[sz]);

    sz = GetEnvironmentVariable(name_cstr, envvalue.get(), sz);

    value = envvalue.get();
  }

  if (!sz)
  {
    /// \todo Log error that the environment reading failed.
  }
#else
  char const* const envvalue = getenv(name.c_str());

  if (envvalue)
  {
    value = envvalue;
  }
#endif

  return value;
}

#ifdef NAME_THREAD_USING_PRCTL
bool
name_thread_prctl(thread_name_t const& name)
{
  int const ret = prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name.c_str()), 0, 0, 0);

  return (ret == 0);
}
#endif

#ifdef NAME_THREAD_USING_SETPROCTITLE
bool
name_thread_setproctitle(thread_name_t const& name)
{
  setproctitle("%s", name.c_str());
}
#endif

#ifdef NAME_THREAD_USING_PTHREAD
bool
name_thread_pthread(thread_name_t const& name)
{
  int ret;

#ifdef HAVE_PTHREAD_SETNAME_NP
#ifdef PTHREAD_SETNAME_NP_TAKES_ID
  pthread_t const tid = pthread_self();

  ret = pthread_setname_np(tid, name.c_str());
#else
  ret = pthread_setname_np(name.c_str());
#endif
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
  pthread_t const tid = pthread_self();

  ret = pthread_set_name_np(tid, name.c_str());
#endif

  return (ret == 0);
}
#endif

#ifdef NAME_THREAD_USING_WIN32
static void set_thread_name(DWORD thread_id, LPCSTR name);

bool
name_thread_win32(thread_name_t const& name)
{
  static DWORD const current_thread = -1;

  set_thread_name(current_thread, name.c_str());

  return true;
}

// Code obtained from http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
   DWORD dwType;     // Must be 0x1000.
   LPCSTR szName;    // Pointer to name (in user addr space).
   DWORD dwThreadID; // Thread ID (-1 = caller thread).
   DWORD dwFlags;    // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)

void
set_thread_name(DWORD thread_id, LPCSTR name)
{
   THREADNAME_INFO info;
   info.dwType = 0x1000;
   info.szName = name;
   info.dwThreadID = thread_id;
   info.dwFlags = 0;

   __try
   {
      static DWORD const MS_VC_EXCEPTION = 0x406D1388;

      RaiseException(MS_VC_EXCEPTION,
        0,
        sizeof(info) / sizeof(ULONG_PTR),
        reinterpret_cast<ULONG_PTR*>&info);
   }
   __except(EXCEPTION_EXECUTE_HANDLER)
   {
   }
}
#endif

}
<commit_msg>Initialize the return value to -ENOTSUP<commit_after>/*ckwg +5
 * Copyright 2011-2013 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include "utils.h"

#ifdef HAVE_PTHREAD_NAMING
#define NAME_THREAD_USING_PTHREAD
#ifdef HAVE_PTHREAD_SET_NAME_NP
#ifdef NDEBUG
// The mechanism only make sense in debugging mode.
#undef NAME_THREAD_USING_PTHREAD
#endif
#endif
#endif

#ifdef HAVE_SETPROCTITLE
#define NAME_THREAD_USING_SETPROCTITLE
#endif

#ifdef __linux__
#define NAME_THREAD_USING_PRCTL
#endif

#if defined(_WIN32) || defined(_WIN64)
#ifndef NDEBUG
// The mechanism only make sense in debugging mode.
#define NAME_THREAD_USING_WIN32
#endif
#endif

#ifdef NAME_THREAD_USING_PTHREAD
#include <errno.h>
#include <pthread.h>
#ifdef HAVE_PTHREAD_SET_NAME_NP
#include <pthread_np.h>
#endif
#endif

#ifdef NAME_THREAD_USING_PRCTL
#include <sys/prctl.h>
#endif

#if defined(_WIN32) || defined(_WIN64)
#include <boost/scoped_array.hpp>

#include <windows.h>
#else
#include <cstdlib>
#endif

/**
 * \file utils.cxx
 *
 * \brief Implementation of pipeline utilities.
 */

namespace vistk
{

#ifdef NAME_THREAD_USING_PRCTL
static bool name_thread_prctl(thread_name_t const& name);
#endif

#ifdef NAME_THREAD_USING_SETPROCTITLE
static bool name_thread_setproctitle(thread_name_t const& name);
#endif

#ifdef NAME_THREAD_USING_PTHREAD
static bool name_thread_pthread(thread_name_t const& name);
#endif

#ifdef NAME_THREAD_USING_WIN32
static bool name_thread_win32(thread_name_t const& name);
#endif

bool
name_thread(thread_name_t const& name)
{
  bool ret = false;

#ifdef NAME_THREAD_USING_PRCTL
  if (!ret)
  {
    ret = name_thread_prctl(name);
  }
#endif

#ifdef NAME_THREAD_USING_SETPROCTITLE
  if (!ret)
  {
    ret = name_thread_setproctitle(name);
  }
#endif

#ifdef NAME_THREAD_USING_PTHREAD
  if (!ret)
  {
    ret = name_thread_pthread(name);
  }
#endif

#ifdef NAME_THREAD_USING_WIN32
  if (!ret)
  {
    ret = name_thread_win32(name);
  }
#endif

  return ret;
}

envvar_value_t
get_envvar(envvar_name_t const& name)
{
  envvar_value_t value;

#if defined(_WIN32) || defined(_WIN64)
  char const* const name_cstr = name.c_str();

  DWORD sz = GetEnvironmentVariable(name_cstr, NULL, 0);

  if (sz)
  {
    typedef boost::scoped_array<char> raw_envvar_value_t;
    raw_envvar_value_t const envvalue(new char[sz]);

    sz = GetEnvironmentVariable(name_cstr, envvalue.get(), sz);

    value = envvalue.get();
  }

  if (!sz)
  {
    /// \todo Log error that the environment reading failed.
  }
#else
  char const* const envvalue = getenv(name.c_str());

  if (envvalue)
  {
    value = envvalue;
  }
#endif

  return value;
}

#ifdef NAME_THREAD_USING_PRCTL
bool
name_thread_prctl(thread_name_t const& name)
{
  int const ret = prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name.c_str()), 0, 0, 0);

  return (ret == 0);
}
#endif

#ifdef NAME_THREAD_USING_SETPROCTITLE
bool
name_thread_setproctitle(thread_name_t const& name)
{
  setproctitle("%s", name.c_str());
}
#endif

#ifdef NAME_THREAD_USING_PTHREAD
bool
name_thread_pthread(thread_name_t const& name)
{
  int ret = -ENOTSUP;

#ifdef HAVE_PTHREAD_SETNAME_NP
#ifdef PTHREAD_SETNAME_NP_TAKES_ID
  pthread_t const tid = pthread_self();

  ret = pthread_setname_np(tid, name.c_str());
#else
  ret = pthread_setname_np(name.c_str());
#endif
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
  pthread_t const tid = pthread_self();

  ret = pthread_set_name_np(tid, name.c_str());
#endif

  return (ret == 0);
}
#endif

#ifdef NAME_THREAD_USING_WIN32
static void set_thread_name(DWORD thread_id, LPCSTR name);

bool
name_thread_win32(thread_name_t const& name)
{
  static DWORD const current_thread = -1;

  set_thread_name(current_thread, name.c_str());

  return true;
}

// Code obtained from http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
   DWORD dwType;     // Must be 0x1000.
   LPCSTR szName;    // Pointer to name (in user addr space).
   DWORD dwThreadID; // Thread ID (-1 = caller thread).
   DWORD dwFlags;    // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)

void
set_thread_name(DWORD thread_id, LPCSTR name)
{
   THREADNAME_INFO info;
   info.dwType = 0x1000;
   info.szName = name;
   info.dwThreadID = thread_id;
   info.dwFlags = 0;

   __try
   {
      static DWORD const MS_VC_EXCEPTION = 0x406D1388;

      RaiseException(MS_VC_EXCEPTION,
        0,
        sizeof(info) / sizeof(ULONG_PTR),
        reinterpret_cast<ULONG_PTR*>&info);
   }
   __except(EXCEPTION_EXECUTE_HANDLER)
   {
   }
}
#endif

}
<|endoftext|>


<commit_before>// -*- Mode: C++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
#define YBORM_SOURCE

#ifdef YB_DEBUG_DOMAIN_REG
#include <iostream>
#endif
#include "orm/domain_object.h"

namespace Yb {

NoDataObject::NoDataObject()
    : ORMError(_T("No ROW data is associated with DomainObject"))
{}

NoSessionBaseGiven::NoSessionBaseGiven()
    : ORMError(_T("No session given to the WeakObject"))
{}

AlreadySavedInAnotherSession::AlreadySavedInAnotherSession()
    : ORMError(_T("Object has been already saved in some other session"))
{}

CouldNotSaveEmptyObject::CouldNotSaveEmptyObject()
    : ORMError(_T("Attempt to save an empty object failed"))
{}

OutOfManagedList::OutOfManagedList(int pos, int sz)
    : ORMError(_T("Trying to access index ") +
            to_string(pos) +
            _T(" that falls out of ManagedList of size ") +
            to_string(sz))
{}

InvalidIterator::InvalidIterator()
    : ORMError(_T("Trying to use an invalid iterator"))
{}

namespace {
typedef std::pair<Tables, Relations> SchemaInfo;
}

int DomainObject::init_flag_ = 0;
void *DomainObject::pending_ = NULL;

bool DomainObject::register_table_meta(Table::Ptr tbl)
{
#ifdef YB_DEBUG_DOMAIN_REG
    std::cerr << "register_table_meta(" << tbl->name()
              << "), init_flag_=" << init_flag_ << std::endl;
#endif
    if (init_flag_)
        return false;
    SchemaInfo *&items =
        *reinterpret_cast<SchemaInfo **> (&pending_);
    if (!items)
        items = new SchemaInfo();
    items->first.push_back(tbl);
    return true;
}

bool DomainObject::register_relation_meta(Relation::Ptr rel)
{
#ifdef YB_DEBUG_DOMAIN_REG
    std::cerr << "register_relation_meta(" << rel->side(0)
              << ", " << rel->side(1)
              << "), init_flag_=" << init_flag_ << std::endl;
#endif
    if (init_flag_)
        return false;
    SchemaInfo *&items =
        *reinterpret_cast<SchemaInfo **> (&pending_);
    if (!items)
        items = new SchemaInfo();
    items->second.push_back(rel);
    return true;
}

void DomainObject::save_registered(Schema &schema)
{
#ifdef YB_DEBUG_DOMAIN_REG
    std::cerr << "save_registered(), init_flag_=" << init_flag_ << std::endl;
#endif
    if (init_flag_)
        return;
    init_flag_ = 1;
    SchemaInfo *&items =
        *reinterpret_cast<SchemaInfo **> (&pending_);
    if (items) {
        Tables &tables = items->first;
        Tables::iterator i = tables.begin(), iend = tables.end();
        for (; i != iend; ++i) {
#ifdef YB_DEBUG_DOMAIN_REG
            std::cerr << "table: " << (*i)->name() << std::endl;
#endif
            schema.add_table(*i);
        }
        Relations &relations = items->second;
        Relations::iterator j = relations.begin(), jend = relations.end();
        for (; j != jend; ++j) {
#ifdef YB_DEBUG_DOMAIN_REG
            std::cerr << "relation: " << (*j)->side(0) << "," << (*j)->side(1) << std::endl;
#endif
            schema.add_relation(*j);
        }
        delete items;
        items = NULL;
    }
}

void DomainObject::check_ptr() const
{
    if (!shptr_get(d_))
        throw NoDataObject();
}

DomainObject::DomainObject(const Table &table,
        DomainObject *owner, const String &prop_name)
    : owner_(owner)
    , prop_name_(prop_name)
{}

DataObject::Ptr DomainObject::get_data_object(bool check) const
{
    if (owner_)
        return DataObject::get_master(owner_->get_data_object(check), prop_name_);
    if (check)
        check_ptr();
    return d_;
}

void DomainObject::set_data_object(DataObject::Ptr d)
{
    if (owner_) {
        owner_->check_ptr();
        DomainObject master(d);
        owner_->link_to_master(master, prop_name_);
    }
    else
        d_ = d;
}

DomainObject::DomainObject()
    : owner_(NULL)
{}

DomainObject::DomainObject(DataObject::Ptr d)
    : d_(d)
    , owner_(NULL)
{}

DomainObject::DomainObject(const Table &table)
    : d_(DataObject::create_new(table))
    , owner_(NULL)
{}

DomainObject::DomainObject(const Schema &schema, const String &table_name)
    : d_(DataObject::create_new(schema.table(table_name)))
    , owner_(NULL)
{}

DomainObject::DomainObject(Session &session, const Key &key)
    : d_(session.get_lazy(key))
    , owner_(NULL)
{}

DomainObject::DomainObject(Session &session, const String &tbl_name,
        LongInt id)
    : d_(session.get_lazy(session.schema().table(tbl_name).mk_key(id)))
    , owner_(NULL)
{}

DomainObject::DomainObject(const DomainObject &obj)
    : d_(obj.get_data_object())
    , owner_(NULL)
{}

DomainObject::~DomainObject()
{}

DomainObject &DomainObject::operator=(const DomainObject &obj)
{
    if (this != &obj)
        set_data_object(obj.get_data_object());
    return *this;
}

void DomainObject::save(Session &session)
{
    session.save(get_data_object());
}

void DomainObject::detach(Session &session)
{
    session.detach(get_data_object());
}

bool DomainObject::is_empty() const
{
    return !shptr_get(get_data_object(false));
}

Session *DomainObject::get_session() const
{
    return get_data_object()->session();
}

const Value &DomainObject::get(const String &col_name) const
{
    return get_data_object()->get(col_name);
}

void DomainObject::set(const String &col_name, const Value &value)
{
    get_data_object()->set(col_name, value);
}

const Value &DomainObject::get(int col_num) const
{
    return get_data_object()->get(col_num);
}

void DomainObject::set(int col_num, const Value &value)
{
    get_data_object()->set(col_num, value);
}

const DomainObject DomainObject::get_master(
        const String &relation_name) const
{
    return DomainObject(
            DataObject::get_master(get_data_object(), relation_name));
}

RelationObject *DomainObject::get_slaves_ro(
        const String &relation_name) const
{
    return get_data_object()->get_slaves(relation_name);
}

ManagedList<DomainObject> DomainObject::get_slaves(
        const String &relation_name) const
{
    DataObject::Ptr p = get_data_object();
    return ManagedList<DomainObject>(p->get_slaves(relation_name), p);
}

void DomainObject::link_to_master(DomainObject &master,
        const String relation_name)
{
    DataObject::link_slave_to_master(get_data_object(),
            master.get_data_object(), relation_name);
}

void DomainObject::link_to_slave(DomainObject &slave,
        const String relation_name)
{
    DataObject::link_master_to_slave(get_data_object(),
            slave.get_data_object(), relation_name);
}

void DomainObject::delete_object()
{
    get_data_object()->delete_object();
}

DataObject::Status DomainObject::status() const
{
    return get_data_object()->status();
}

const Table &DomainObject::get_table() const
{
    return get_data_object()->table();
}

int DomainObject::cmp(const DomainObject &x) const
{
    DataObject::Ptr p1 = get_data_object(false), p2 = x.get_data_object(false);
    if (p1 == p2)
        return 0;
    if (!shptr_get(p1))
        return -1;
    if (!shptr_get(p2))
        return 1;
    if (p1->raw_values() == p2->raw_values())
        return 0;
    return p1->raw_values() < p2->raw_values()? -1: 1;
}

ElementTree::ElementPtr DomainObject::xmlize(
        int depth, const String &alt_name) const
{
    Session *s = get_session();
    if (!s)
        throw NoSessionBaseGiven();
    return deep_xmlize(*s, get_data_object(), depth, alt_name);
}

} // namespace Yb

// vim:ts=4:sts=4:sw=4:et:
<commit_msg>thanks msvc: fixed a bug<commit_after>// -*- Mode: C++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
#define YBORM_SOURCE

#ifdef YB_DEBUG_DOMAIN_REG
#include <iostream>
#endif
#include "orm/domain_object.h"

namespace Yb {

NoDataObject::NoDataObject()
    : ORMError(_T("No ROW data is associated with DomainObject"))
{}

NoSessionBaseGiven::NoSessionBaseGiven()
    : ORMError(_T("No session given to the WeakObject"))
{}

AlreadySavedInAnotherSession::AlreadySavedInAnotherSession()
    : ORMError(_T("Object has been already saved in some other session"))
{}

CouldNotSaveEmptyObject::CouldNotSaveEmptyObject()
    : ORMError(_T("Attempt to save an empty object failed"))
{}

OutOfManagedList::OutOfManagedList(int pos, int sz)
    : ORMError(_T("Trying to access index ") +
            to_string(pos) +
            _T(" that falls out of ManagedList of size ") +
            to_string(sz))
{}

InvalidIterator::InvalidIterator()
    : ORMError(_T("Trying to use an invalid iterator"))
{}

namespace {
typedef std::pair<Tables, Relations> SchemaInfo;
}

int DomainObject::init_flag_ = 0;
void *DomainObject::pending_ = NULL;

bool DomainObject::register_table_meta(Table::Ptr tbl)
{
#ifdef YB_DEBUG_DOMAIN_REG
    std::cerr << "register_table_meta(" << tbl->name()
              << "), init_flag_=" << init_flag_ << std::endl;
#endif
    if (init_flag_)
        return false;
    SchemaInfo *&items =
        *reinterpret_cast<SchemaInfo **> (&pending_);
    if (!items)
        items = new SchemaInfo();
    items->first.push_back(tbl);
    return true;
}

bool DomainObject::register_relation_meta(Relation::Ptr rel)
{
#ifdef YB_DEBUG_DOMAIN_REG
    std::cerr << "register_relation_meta(" << rel->side(0)
              << ", " << rel->side(1)
              << "), init_flag_=" << init_flag_ << std::endl;
#endif
    if (init_flag_)
        return false;
    SchemaInfo *&items =
        *reinterpret_cast<SchemaInfo **> (&pending_);
    if (!items)
        items = new SchemaInfo();
    items->second.push_back(rel);
    return true;
}

void DomainObject::save_registered(Schema &schema)
{
#ifdef YB_DEBUG_DOMAIN_REG
    std::cerr << "save_registered(), init_flag_=" << init_flag_ << std::endl;
#endif
    if (init_flag_)
        return;
    init_flag_ = 1;
    SchemaInfo *&items =
        *reinterpret_cast<SchemaInfo **> (&pending_);
    if (items) {
        Tables &tables = items->first;
        Tables::iterator i = tables.begin(), iend = tables.end();
        for (; i != iend; ++i) {
#ifdef YB_DEBUG_DOMAIN_REG
            std::cerr << "table: " << (*i)->name() << std::endl;
#endif
            schema.add_table(*i);
        }
        Relations &relations = items->second;
        Relations::iterator j = relations.begin(), jend = relations.end();
        for (; j != jend; ++j) {
#ifdef YB_DEBUG_DOMAIN_REG
            std::cerr << "relation: " << (*j)->side(0) << "," << (*j)->side(1) << std::endl;
#endif
            schema.add_relation(*j);
        }
        delete items;
        items = NULL;
    }
}

void DomainObject::check_ptr() const
{
    if (!shptr_get(d_))
        throw NoDataObject();
}

DomainObject::DomainObject(const Table &table,
        DomainObject *owner, const String &prop_name)
    : owner_(owner)
    , prop_name_(prop_name)
{}

DataObject::Ptr DomainObject::get_data_object(bool check) const
{
    if (owner_)
        return DataObject::get_master(owner_->get_data_object(check), prop_name_);
    if (check)
        check_ptr();
    return d_;
}

void DomainObject::set_data_object(DataObject::Ptr d)
{
    if (owner_) {
        owner_->check_ptr();
        DomainObject master(d);
        owner_->link_to_master(master, prop_name_);
    }
    else
        d_ = d;
}

DomainObject::DomainObject()
    : owner_(NULL)
{}

DomainObject::DomainObject(DataObject::Ptr d)
    : d_(d)
    , owner_(NULL)
{}

DomainObject::DomainObject(const Table &table)
    : d_(DataObject::create_new(table))
    , owner_(NULL)
{}

DomainObject::DomainObject(const Schema &schema, const String &table_name)
    : d_(DataObject::create_new(schema.table(table_name)))
    , owner_(NULL)
{}

DomainObject::DomainObject(Session &session, const Key &key)
    : d_(session.get_lazy(key))
    , owner_(NULL)
{}

DomainObject::DomainObject(Session &session, const String &tbl_name,
        LongInt id)
    : d_(session.get_lazy(session.schema().table(tbl_name).mk_key(id)))
    , owner_(NULL)
{}

DomainObject::DomainObject(const DomainObject &obj)
    : d_(obj.get_data_object(false))
    , owner_(NULL)
{}

DomainObject::~DomainObject()
{}

DomainObject &DomainObject::operator=(const DomainObject &obj)
{
    if (this != &obj)
        set_data_object(obj.get_data_object(false));
    return *this;
}

void DomainObject::save(Session &session)
{
    session.save(get_data_object());
}

void DomainObject::detach(Session &session)
{
    session.detach(get_data_object());
}

bool DomainObject::is_empty() const
{
    return !shptr_get(get_data_object(false));
}

Session *DomainObject::get_session() const
{
    return get_data_object()->session();
}

const Value &DomainObject::get(const String &col_name) const
{
    return get_data_object()->get(col_name);
}

void DomainObject::set(const String &col_name, const Value &value)
{
    get_data_object()->set(col_name, value);
}

const Value &DomainObject::get(int col_num) const
{
    return get_data_object()->get(col_num);
}

void DomainObject::set(int col_num, const Value &value)
{
    get_data_object()->set(col_num, value);
}

const DomainObject DomainObject::get_master(
        const String &relation_name) const
{
    return DomainObject(
            DataObject::get_master(get_data_object(), relation_name));
}

RelationObject *DomainObject::get_slaves_ro(
        const String &relation_name) const
{
    return get_data_object()->get_slaves(relation_name);
}

ManagedList<DomainObject> DomainObject::get_slaves(
        const String &relation_name) const
{
    DataObject::Ptr p = get_data_object();
    return ManagedList<DomainObject>(p->get_slaves(relation_name), p);
}

void DomainObject::link_to_master(DomainObject &master,
        const String relation_name)
{
    DataObject::link_slave_to_master(get_data_object(),
            master.get_data_object(), relation_name);
}

void DomainObject::link_to_slave(DomainObject &slave,
        const String relation_name)
{
    DataObject::link_master_to_slave(get_data_object(),
            slave.get_data_object(), relation_name);
}

void DomainObject::delete_object()
{
    get_data_object()->delete_object();
}

DataObject::Status DomainObject::status() const
{
    return get_data_object()->status();
}

const Table &DomainObject::get_table() const
{
    return get_data_object()->table();
}

int DomainObject::cmp(const DomainObject &x) const
{
    DataObject::Ptr p1 = get_data_object(false), p2 = x.get_data_object(false);
    if (p1 == p2)
        return 0;
    if (!shptr_get(p1))
        return -1;
    if (!shptr_get(p2))
        return 1;
    if (p1->raw_values() == p2->raw_values())
        return 0;
    return p1->raw_values() < p2->raw_values()? -1: 1;
}

ElementTree::ElementPtr DomainObject::xmlize(
        int depth, const String &alt_name) const
{
    Session *s = get_session();
    if (!s)
        throw NoSessionBaseGiven();
    return deep_xmlize(*s, get_data_object(), depth, alt_name);
}

} // namespace Yb

// vim:ts=4:sts=4:sw=4:et:
<|endoftext|>