<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
// Copyright 2011 Bernahrd Beschow <bbeschow@cs.tu-berlin.de>
//

// Own
#include "LayerManager.h"

// Qt
#include <QtGui/QAction>

// Local dir
#include "MarbleDebug.h"
#include "AbstractDataPlugin.h"
#include "AbstractDataPluginItem.h"
#include "AbstractFloatItem.h"
#include "GeoPainter.h"
#include "GeoSceneDocument.h"
#include "GeoSceneSettings.h"
#include "MarbleModel.h"
#include "PluginManager.h"
#include "RenderPlugin.h"
#include "LayerInterface.h"

namespace Marble
{

/**
  * Returns true if the zValue of one is lower than that of two. Null must not be passed
  * as parameter.
  */
bool zValueLessThan( const LayerInterface * const one, const LayerInterface * const two )
{
    Q_ASSERT( one && two );
    return one->zValue() < two->zValue();
}

class LayerManagerPrivate
{
 public:
    LayerManagerPrivate( const MarbleModel* model );
    ~LayerManagerPrivate();

    GeoSceneDocument *m_mapTheme;

    const MarbleModel *m_marbleModel;
    const PluginManager *m_pluginManager;
    QList<RenderPlugin *> m_renderPlugins;
    QList<AbstractFloatItem *> m_floatItems;
    QList<AbstractDataPlugin *> m_dataPlugins;
    QList<LayerInterface *> m_internalLayers;

    bool m_showBackground;
};

LayerManagerPrivate::LayerManagerPrivate( const MarbleModel* model )
    : m_mapTheme( 0 ),
      m_marbleModel( model ),
      m_pluginManager( model->pluginManager() ),
      m_renderPlugins( m_pluginManager->createRenderPlugins() ),
      m_showBackground( true )
{
}

LayerManagerPrivate::~LayerManagerPrivate()
{
    foreach( RenderPlugin * renderPlugin, m_renderPlugins )
        renderPlugin->setMarbleModel( 0 );
    qDeleteAll( m_renderPlugins );
}

LayerManager::LayerManager( const MarbleModel* model, QObject *parent )
    : QObject( parent ),
      d( new LayerManagerPrivate( model ) )
{

    // get float items and data plugins
    foreach( RenderPlugin * renderPlugin, d->m_renderPlugins ) {
        connect( renderPlugin, SIGNAL( settingsChanged( QString ) ),
                 this, SIGNAL( pluginSettingsChanged() ) );
        connect( renderPlugin, SIGNAL( settingsChanged( QString ) ),
                 this, SIGNAL( repaintNeeded() ) );
        connect( renderPlugin, SIGNAL( repaintNeeded( QRegion ) ),
                 this, SIGNAL( repaintNeeded( QRegion ) ) );

        AbstractFloatItem * const floatItem =
            qobject_cast<AbstractFloatItem *>( renderPlugin );
        if ( floatItem )
            d->m_floatItems.append( floatItem );

        AbstractDataPlugin * const dataPlugin =
            qobject_cast<AbstractDataPlugin *>( renderPlugin );
        if( dataPlugin )
            d->m_dataPlugins.append( dataPlugin );
    }

    foreach( RenderPlugin * renderPlugin, d->m_renderPlugins ) {
        renderPlugin->setMarbleModel( d->m_marbleModel );
    }
}

LayerManager::~LayerManager()
{
    delete d;
}

bool LayerManager::showBackground() const
{
    return d->m_showBackground;
}

QList<RenderPlugin *> LayerManager::renderPlugins() const
{
    return d->m_renderPlugins;
}

QList<AbstractFloatItem *> LayerManager::floatItems() const
{
    return d->m_floatItems;
}

QList<AbstractDataPlugin *> LayerManager::dataPlugins() const
{
    return d->m_dataPlugins;
}

QList<AbstractDataPluginItem *> LayerManager::whichItemAt( const QPoint& curpos ) const
{
    QList<AbstractDataPluginItem *> itemList;

    foreach( AbstractDataPlugin *plugin, d->m_dataPlugins ) {
        itemList.append( plugin->whichItemAt( curpos ) );
    }
    return itemList;
}

void LayerManager::renderLayers( GeoPainter *painter, ViewportParams *viewport )
{
    QStringList renderPositions;

    if ( d->m_showBackground ) {
        renderPositions << "STARS" << "BEHIND_TARGET";
    }

    renderPositions << "SURFACE" << "HOVERS_ABOVE_SURFACE" << "ATMOSPHERE"
                    << "ORBIT" << "ALWAYS_ON_TOP" << "FLOAT_ITEM" << "USER_TOOLS";

    foreach( const QString& renderPosition, renderPositions ) {
        renderLayer( painter, viewport, renderPosition );
    }
}

void LayerManager::renderLayer( GeoPainter *painter, ViewportParams *viewport,
                                const QString& renderPosition )
{
    if ( !viewport ) {
        mDebug() << "LayerManager: No valid viewParams set!";
        return;
    }

    QList<LayerInterface*> layers;

    foreach( RenderPlugin *renderPlugin, d->m_renderPlugins ) {
        if ( renderPlugin && renderPlugin->renderPosition().contains( renderPosition )  ){
            if ( renderPlugin->enabled() && renderPlugin->visible() ) {
                if ( !renderPlugin->isInitialized() )
                {
                    renderPlugin->initialize();
                    emit renderPluginInitialized( renderPlugin );
                }
                layers.push_back( renderPlugin );
            }
        }
    }

    foreach( LayerInterface *layer, d->m_internalLayers ) {
        if ( layer && layer->renderPosition().contains( renderPosition ) ) {
            layers.push_back( layer );
        }
    }

    qSort( layers.begin(), layers.end(), zValueLessThan );
    foreach( LayerInterface *layer, layers ) {
        layer->render( painter, viewport, renderPosition, 0 );
    }
}

void LayerManager::setShowBackground( bool show )
{
    d->m_showBackground = show;
}

void LayerManager::syncViewParamsAndPlugins( GeoSceneDocument *mapTheme )
{
    d->m_mapTheme = mapTheme;

    foreach( RenderPlugin * renderPlugin, d->m_renderPlugins ) {
        bool propertyAvailable = false;
        mapTheme->settings()->propertyAvailable( renderPlugin->nameId(),
						 propertyAvailable );
        bool propertyValue = false;
        mapTheme->settings()->propertyValue( renderPlugin->nameId(),
					     propertyValue );

        if ( propertyAvailable ) {
            renderPlugin->setVisible( propertyValue );
        }

        disconnect( renderPlugin->action(), SIGNAL( changed() ),
                 this,                   SIGNAL( repaintNeeded() ) );
        disconnect( renderPlugin, SIGNAL( visibilityChanged( QString, bool ) ),
                 this,         SLOT( syncPropertyWithAction( QString, bool ) ) );
        connect( renderPlugin->action(), SIGNAL( changed() ),
                 this,                   SIGNAL( repaintNeeded() ) );
        connect( renderPlugin, SIGNAL( visibilityChanged( QString, bool ) ),
                 this,         SLOT( syncPropertyWithAction( QString, bool ) ) );

    }

    disconnect( mapTheme->settings(), 0, this, 0 );
    connect( mapTheme->settings(), SIGNAL( valueChanged( QString, bool ) ),
             this,                 SLOT( syncActionWithProperty( QString, bool ) ) );
}

void LayerManager::syncActionWithProperty( QString nameId, bool checked )
{
    foreach( RenderPlugin * renderPlugin, d->m_renderPlugins ) {
        if ( nameId == renderPlugin->nameId() ) {
            if ( renderPlugin->visible() == checked )
                return;

            renderPlugin->setVisible( checked );

            return;
        }
    }
}

void LayerManager::syncPropertyWithAction( QString nameId, bool checked )
{
    bool propertyAvailable = false;
    d->m_mapTheme->settings()->propertyAvailable( nameId, propertyAvailable );

    if ( propertyAvailable ) {
        bool propertyValue = false;
        d->m_mapTheme->settings()->propertyValue( nameId, propertyValue );

        if ( propertyValue == checked ) {
            return;
        }
        d->m_mapTheme->settings()->setPropertyValue( nameId, checked );
    }
}

void LayerManager::addLayer(LayerInterface *layer)
{
    d->m_internalLayers.push_back(layer);
}

void LayerManager::removeLayer(LayerInterface *layer)
{
    d->m_internalLayers.removeAll(layer);
}

}

#include "LayerManager.moc"
<commit_msg>no need to set MarbleModel to nullpointer just before RenderPlugins are deleted<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
// Copyright 2011 Bernahrd Beschow <bbeschow@cs.tu-berlin.de>
//

// Own
#include "LayerManager.h"

// Qt
#include <QtGui/QAction>

// Local dir
#include "MarbleDebug.h"
#include "AbstractDataPlugin.h"
#include "AbstractDataPluginItem.h"
#include "AbstractFloatItem.h"
#include "GeoPainter.h"
#include "GeoSceneDocument.h"
#include "GeoSceneSettings.h"
#include "MarbleModel.h"
#include "PluginManager.h"
#include "RenderPlugin.h"
#include "LayerInterface.h"

namespace Marble
{

/**
  * Returns true if the zValue of one is lower than that of two. Null must not be passed
  * as parameter.
  */
bool zValueLessThan( const LayerInterface * const one, const LayerInterface * const two )
{
    Q_ASSERT( one && two );
    return one->zValue() < two->zValue();
}

class LayerManagerPrivate
{
 public:
    LayerManagerPrivate( const MarbleModel* model );
    ~LayerManagerPrivate();

    GeoSceneDocument *m_mapTheme;

    const MarbleModel *m_marbleModel;
    const PluginManager *m_pluginManager;
    QList<RenderPlugin *> m_renderPlugins;
    QList<AbstractFloatItem *> m_floatItems;
    QList<AbstractDataPlugin *> m_dataPlugins;
    QList<LayerInterface *> m_internalLayers;

    bool m_showBackground;
};

LayerManagerPrivate::LayerManagerPrivate( const MarbleModel* model )
    : m_mapTheme( 0 ),
      m_marbleModel( model ),
      m_pluginManager( model->pluginManager() ),
      m_renderPlugins( m_pluginManager->createRenderPlugins() ),
      m_showBackground( true )
{
}

LayerManagerPrivate::~LayerManagerPrivate()
{
    qDeleteAll( m_renderPlugins );
}

LayerManager::LayerManager( const MarbleModel* model, QObject *parent )
    : QObject( parent ),
      d( new LayerManagerPrivate( model ) )
{

    // get float items and data plugins
    foreach( RenderPlugin * renderPlugin, d->m_renderPlugins ) {
        connect( renderPlugin, SIGNAL( settingsChanged( QString ) ),
                 this, SIGNAL( pluginSettingsChanged() ) );
        connect( renderPlugin, SIGNAL( settingsChanged( QString ) ),
                 this, SIGNAL( repaintNeeded() ) );
        connect( renderPlugin, SIGNAL( repaintNeeded( QRegion ) ),
                 this, SIGNAL( repaintNeeded( QRegion ) ) );

        AbstractFloatItem * const floatItem =
            qobject_cast<AbstractFloatItem *>( renderPlugin );
        if ( floatItem )
            d->m_floatItems.append( floatItem );

        AbstractDataPlugin * const dataPlugin =
            qobject_cast<AbstractDataPlugin *>( renderPlugin );
        if( dataPlugin )
            d->m_dataPlugins.append( dataPlugin );
    }

    foreach( RenderPlugin * renderPlugin, d->m_renderPlugins ) {
        renderPlugin->setMarbleModel( d->m_marbleModel );
    }
}

LayerManager::~LayerManager()
{
    delete d;
}

bool LayerManager::showBackground() const
{
    return d->m_showBackground;
}

QList<RenderPlugin *> LayerManager::renderPlugins() const
{
    return d->m_renderPlugins;
}

QList<AbstractFloatItem *> LayerManager::floatItems() const
{
    return d->m_floatItems;
}

QList<AbstractDataPlugin *> LayerManager::dataPlugins() const
{
    return d->m_dataPlugins;
}

QList<AbstractDataPluginItem *> LayerManager::whichItemAt( const QPoint& curpos ) const
{
    QList<AbstractDataPluginItem *> itemList;

    foreach( AbstractDataPlugin *plugin, d->m_dataPlugins ) {
        itemList.append( plugin->whichItemAt( curpos ) );
    }
    return itemList;
}

void LayerManager::renderLayers( GeoPainter *painter, ViewportParams *viewport )
{
    QStringList renderPositions;

    if ( d->m_showBackground ) {
        renderPositions << "STARS" << "BEHIND_TARGET";
    }

    renderPositions << "SURFACE" << "HOVERS_ABOVE_SURFACE" << "ATMOSPHERE"
                    << "ORBIT" << "ALWAYS_ON_TOP" << "FLOAT_ITEM" << "USER_TOOLS";

    foreach( const QString& renderPosition, renderPositions ) {
        renderLayer( painter, viewport, renderPosition );
    }
}

void LayerManager::renderLayer( GeoPainter *painter, ViewportParams *viewport,
                                const QString& renderPosition )
{
    if ( !viewport ) {
        mDebug() << "LayerManager: No valid viewParams set!";
        return;
    }

    QList<LayerInterface*> layers;

    foreach( RenderPlugin *renderPlugin, d->m_renderPlugins ) {
        if ( renderPlugin && renderPlugin->renderPosition().contains( renderPosition )  ){
            if ( renderPlugin->enabled() && renderPlugin->visible() ) {
                if ( !renderPlugin->isInitialized() )
                {
                    renderPlugin->initialize();
                    emit renderPluginInitialized( renderPlugin );
                }
                layers.push_back( renderPlugin );
            }
        }
    }

    foreach( LayerInterface *layer, d->m_internalLayers ) {
        if ( layer && layer->renderPosition().contains( renderPosition ) ) {
            layers.push_back( layer );
        }
    }

    qSort( layers.begin(), layers.end(), zValueLessThan );
    foreach( LayerInterface *layer, layers ) {
        layer->render( painter, viewport, renderPosition, 0 );
    }
}

void LayerManager::setShowBackground( bool show )
{
    d->m_showBackground = show;
}

void LayerManager::syncViewParamsAndPlugins( GeoSceneDocument *mapTheme )
{
    d->m_mapTheme = mapTheme;

    foreach( RenderPlugin * renderPlugin, d->m_renderPlugins ) {
        bool propertyAvailable = false;
        mapTheme->settings()->propertyAvailable( renderPlugin->nameId(),
						 propertyAvailable );
        bool propertyValue = false;
        mapTheme->settings()->propertyValue( renderPlugin->nameId(),
					     propertyValue );

        if ( propertyAvailable ) {
            renderPlugin->setVisible( propertyValue );
        }

        disconnect( renderPlugin->action(), SIGNAL( changed() ),
                 this,                   SIGNAL( repaintNeeded() ) );
        disconnect( renderPlugin, SIGNAL( visibilityChanged( QString, bool ) ),
                 this,         SLOT( syncPropertyWithAction( QString, bool ) ) );
        connect( renderPlugin->action(), SIGNAL( changed() ),
                 this,                   SIGNAL( repaintNeeded() ) );
        connect( renderPlugin, SIGNAL( visibilityChanged( QString, bool ) ),
                 this,         SLOT( syncPropertyWithAction( QString, bool ) ) );

    }

    disconnect( mapTheme->settings(), 0, this, 0 );
    connect( mapTheme->settings(), SIGNAL( valueChanged( QString, bool ) ),
             this,                 SLOT( syncActionWithProperty( QString, bool ) ) );
}

void LayerManager::syncActionWithProperty( QString nameId, bool checked )
{
    foreach( RenderPlugin * renderPlugin, d->m_renderPlugins ) {
        if ( nameId == renderPlugin->nameId() ) {
            if ( renderPlugin->visible() == checked )
                return;

            renderPlugin->setVisible( checked );

            return;
        }
    }
}

void LayerManager::syncPropertyWithAction( QString nameId, bool checked )
{
    bool propertyAvailable = false;
    d->m_mapTheme->settings()->propertyAvailable( nameId, propertyAvailable );

    if ( propertyAvailable ) {
        bool propertyValue = false;
        d->m_mapTheme->settings()->propertyValue( nameId, propertyValue );

        if ( propertyValue == checked ) {
            return;
        }
        d->m_mapTheme->settings()->setPropertyValue( nameId, checked );
    }
}

void LayerManager::addLayer(LayerInterface *layer)
{
    d->m_internalLayers.push_back(layer);
}

void LayerManager::removeLayer(LayerInterface *layer)
{
    d->m_internalLayers.removeAll(layer);
}

}

#include "LayerManager.moc"
<|endoftext|>


<commit_before>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <memory>
#include <stdexcept>

#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>

#include "sdl_renderer.h"
#include "units.h"

#define radiansToDegrees(angleRadians) (angleRadians * 180.0 / M_PI)

namespace aronnax {
  using std::cout;
  using std::cerr;
  using std::endl;

  //float RADTODEG = 180 / M_PI;

  SDLRenderer::~SDLRenderer()
  {
    TTF_CloseFont(font_);
    SDL_DestroyRenderer(renderer_);
    SDL_DestroyWindow(&screen_);
  }

  SDLRenderer::SDLRenderer(SDL_Window* window):
    screen_(*window)
  {
    SDL_Renderer* rendererPtr = nullptr;
    rendererPtr = SDL_CreateRenderer(window, -1, 0);
    if (rendererPtr == nullptr) {
      std::cerr << "creating renderer failed: " << SDL_GetError() << std::endl;
    }
    renderer_ = rendererPtr;

    TTF_Font* fixed = TTF_OpenFont("fonts/DejaVuSansMono.ttf", 16);
    if (fixed == NULL) {
      cerr << "TTF_OpenFont() Failed: " << TTF_GetError() << endl;
      TTF_Quit();
      SDL_Quit();
      throw std::runtime_error(TTF_GetError());
    }
    font_ = fixed;
  }

  void SDLRenderer::render()
  {
  }

  void SDLRenderer::beforeRender()
  {
    // TODO move bg color elsewhere
    SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255);
    SDL_RenderClear(renderer_);
  }

  void SDLRenderer::afterRender()
  {
    SDL_RenderPresent(renderer_);
  }

  void SDLRenderer::drawRectangle(const Vector2d& pos,
                                  const Vector2d& box,
                                  SDL_Texture* texture,
                                  float angle
                                  )
  {
    SDL_Rect r;
    auto halfW = box.x / 2;
    auto halfH = box.y / 2;
    r.x = pos.x - halfW;
    r.y = pos.y - halfH;
    r.w = int(box.x);
    r.h = int(box.y);

    SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);

    SDL_RenderCopyEx(
      renderer_,
      texture,
      NULL,
      &r,
      radiansToDegrees(angle),
      NULL,
      SDL_FLIP_NONE
    );
  }

  void SDLRenderer::drawCircle(const Vector2d& pos, const Vector2d& r)
  {
  }

  void SDLRenderer::drawPolygon(const Vector2d& pos)
  {
  }

  void SDLRenderer::drawText(
        const Vector2d& pos,
        string message,
        const Color& color)
  {
    SDL_Color sdlCol = { color.r, color.g, color.b, color.a };
    SDL_Surface* surface = TTF_RenderText_Solid(font_,
        message.c_str(), sdlCol);
    if (surface == NULL) {
      cerr << "TTF surface Failed: " << TTF_GetError() << endl;
      TTF_Quit();
      SDL_Quit();
      exit(1);
    }
    SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer_, surface);

    int width = surface->w;
    int height = surface->h;

    SDL_Rect messageRect;
    messageRect.x = pos.x;
    messageRect.y = pos.y;
    messageRect.w = width;
    messageRect.h = height;

    SDL_FreeSurface(surface);
    SDL_RenderCopy(renderer_, texture, NULL, &messageRect);
    SDL_DestroyTexture(texture);
  }

  SDL_Texture* SDLRenderer::createTexture(SDL_Surface& s)
  {
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer_, &s);

    if (texture == NULL) {
      // fprintf(stderr, "CreateTexture failed: %s\n", SDL_GetError());
      exit(1);
    }

    return texture;
  }

}
<commit_msg>REmove unnecessary include<commit_after>
#include <iostream>
#include <math.h>
#include <memory>
#include <stdexcept>

#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>

#include "sdl_renderer.h"
#include "units.h"

#define radiansToDegrees(angleRadians) (angleRadians * 180.0 / M_PI)

namespace aronnax {
  using std::cout;
  using std::cerr;
  using std::endl;

  //float RADTODEG = 180 / M_PI;

  SDLRenderer::~SDLRenderer()
  {
    TTF_CloseFont(font_);
    SDL_DestroyRenderer(renderer_);
    SDL_DestroyWindow(&screen_);
  }

  SDLRenderer::SDLRenderer(SDL_Window* window):
    screen_(*window)
  {
    SDL_Renderer* rendererPtr = nullptr;
    rendererPtr = SDL_CreateRenderer(window, -1, 0);
    if (rendererPtr == nullptr) {
      std::cerr << "creating renderer failed: " << SDL_GetError() << std::endl;
    }
    renderer_ = rendererPtr;

    TTF_Font* fixed = TTF_OpenFont("fonts/DejaVuSansMono.ttf", 16);
    if (fixed == NULL) {
      cerr << "TTF_OpenFont() Failed: " << TTF_GetError() << endl;
      TTF_Quit();
      SDL_Quit();
      throw std::runtime_error(TTF_GetError());
    }
    font_ = fixed;
  }

  void SDLRenderer::render()
  {
  }

  void SDLRenderer::beforeRender()
  {
    // TODO move bg color elsewhere
    SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255);
    SDL_RenderClear(renderer_);
  }

  void SDLRenderer::afterRender()
  {
    SDL_RenderPresent(renderer_);
  }

  void SDLRenderer::drawRectangle(const Vector2d& pos,
                                  const Vector2d& box,
                                  SDL_Texture* texture,
                                  float angle
                                  )
  {
    SDL_Rect r;
    auto halfW = box.x / 2;
    auto halfH = box.y / 2;
    r.x = pos.x - halfW;
    r.y = pos.y - halfH;
    r.w = int(box.x);
    r.h = int(box.y);

    SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);

    SDL_RenderCopyEx(
      renderer_,
      texture,
      NULL,
      &r,
      radiansToDegrees(angle),
      NULL,
      SDL_FLIP_NONE
    );
  }

  void SDLRenderer::drawCircle(const Vector2d& pos, const Vector2d& r)
  {
  }

  void SDLRenderer::drawPolygon(const Vector2d& pos)
  {
  }

  void SDLRenderer::drawText(
        const Vector2d& pos,
        string message,
        const Color& color)
  {
    SDL_Color sdlCol = { color.r, color.g, color.b, color.a };
    SDL_Surface* surface = TTF_RenderText_Solid(font_,
        message.c_str(), sdlCol);
    if (surface == NULL) {
      cerr << "TTF surface Failed: " << TTF_GetError() << endl;
      TTF_Quit();
      SDL_Quit();
      exit(1);
    }
    SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer_, surface);

    int width = surface->w;
    int height = surface->h;

    SDL_Rect messageRect;
    messageRect.x = pos.x;
    messageRect.y = pos.y;
    messageRect.w = width;
    messageRect.h = height;

    SDL_FreeSurface(surface);
    SDL_RenderCopy(renderer_, texture, NULL, &messageRect);
    SDL_DestroyTexture(texture);
  }

  SDL_Texture* SDLRenderer::createTexture(SDL_Surface& s)
  {
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer_, &s);

    if (texture == NULL) {
      // fprintf(stderr, "CreateTexture failed: %s\n", SDL_GetError());
      exit(1);
    }

    return texture;
  }

}
<|endoftext|>


<commit_before>#include "nixexpr.hh"
#include "parser.hh"
#include "hash.hh"
#include "util.hh"
#include "nixexpr-ast.hh"

#include <cstdlib>

using namespace nix;

struct Env;
struct Value;

typedef std::map<string, Value> Bindings;

struct Env
{
    Env * up;
    Bindings bindings;
};

typedef enum {
    tInt = 1,
    tAttrs,
    tThunk,
    tLambda,
    tCopy
} ValueType;

struct Value
{
    ValueType type;
    union
    {
        int integer;
        Bindings * attrs;
        struct {
            Env * env;
            Expr expr;
        } thunk;
        struct {
            Env * env;
            Pattern pat;
            Expr body;
        } lambda;
        Value * val;
    };
};

std::ostream & operator << (std::ostream & str, Value & v)
{
    switch (v.type) {
    case tInt:
        str << v.integer;
        break;
    case tAttrs:
        str << "{ ";
        foreach (Bindings::iterator, i, *v.attrs)
            str << i->first << " = " << i->second << "; ";
        str << "}";
        break;
    case tThunk:
        str << "<CODE>";
        break;
    case tLambda:
        str << "<LAMBDA>";
        break;
    default:
        abort();
    }
    return str;
}

static void eval(Env * env, Expr e, Value & v);

void forceValue(Value & v)
{
    if (v.type == tThunk) eval(v.thunk.env, v.thunk.expr, v);
    else if (v.type == tCopy) {
        forceValue(*v.val);
        v = *v.val;
    }
}

Value * lookupVar(Env * env, const string & name)
{
    for ( ; env; env = env->up) {
        Bindings::iterator i = env->bindings.find(name);
        if (i != env->bindings.end()) return &i->second;
    }
    throw Error("undefined variable");
}

unsigned long nrValues = 0;

unsigned long nrEnvs = 0;

Env * allocEnv()
{
    nrEnvs++;
    return new Env;
}

static void eval(Env * env, Expr e, Value & v)
{
    printMsg(lvlError, format("eval: %1%") % e);

    ATerm name;
    if (matchVar(e, name)) {
        Value * v2 = lookupVar(env, aterm2String(name));
        forceValue(*v2);
        v = *v2;
        return;
    }

    int n;
    if (matchInt(e, n)) {
        v.type = tInt;
        v.integer = n;
        return;
    }

    ATermList es;
    if (matchAttrs(e, es)) {
        v.type = tAttrs;
        v.attrs = new Bindings;
        ATerm e2, pos;
        for (ATermIterator i(es); i; ++i) {
            if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */
            Value & v2 = (*v.attrs)[aterm2String(name)];
            nrValues++;
            v2.type = tThunk;
            v2.thunk.env = env;
            v2.thunk.expr = e2;
        }
        return;
    }

    ATermList rbnds, nrbnds;
    if (matchRec(e, rbnds, nrbnds)) {
        Env * env2 = allocEnv();
        env2->up = env;

        v.type = tAttrs;
        v.attrs = &env2->bindings;
        ATerm name, e2, pos;
        for (ATermIterator i(rbnds); i; ++i) {
            if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */
            Value & v2 = env2->bindings[aterm2String(name)];
            nrValues++;
            v2.type = tThunk;
            v2.thunk.env = env2;
            v2.thunk.expr = e2;
        }

        return;
    }

    Expr e2;
    if (matchSelect(e, e2, name)) {
        eval(env, e2, v);
        if (v.type != tAttrs) throw TypeError("expected attribute set");
        Bindings::iterator i = v.attrs->find(aterm2String(name));
        if (i == v.attrs->end()) throw TypeError("attribute not found");
        forceValue(i->second);
        v = i->second;
        return;
    }

    Pattern pat; Expr body; Pos pos;
    if (matchFunction(e, pat, body, pos)) {
        v.type = tLambda;
        v.lambda.env = env;
        v.lambda.pat = pat;
        v.lambda.body = body;
        return;
    }

    Expr fun, arg;
    if (matchCall(e, fun, arg)) {
        eval(env, fun, v);
        if (v.type != tLambda) throw TypeError("expected function");

        Env * env2 = allocEnv();
        env2->up = env;

        ATermList formals; ATerm ellipsis;

        if (matchVarPat(v.lambda.pat, name)) {
            Value & vArg = env2->bindings[aterm2String(name)];
            vArg.type = tThunk;
            vArg.thunk.env = env;
            vArg.thunk.expr = arg;
        }

        else if (matchAttrsPat(v.lambda.pat, formals, ellipsis, name)) {
            Value * vArg;
            Value vArg_;

            if (name == sNoAlias)
                vArg = &vArg_;
            else
                vArg = &env2->bindings[aterm2String(name)];

            eval(env, arg, *vArg);
            if (vArg->type != tAttrs) throw TypeError("expected attribute set");

            /* For each formal argument, get the actual argument.  If
               there is no matching actual argument but the formal
               argument has a default, use the default. */
            unsigned int attrsUsed = 0;
            for (ATermIterator i(formals); i; ++i) {
                Expr name, def;
                DefaultValue def2;
                if (!matchFormal(*i, name, def2)) abort(); /* can't happen */

                Bindings::iterator j = vArg->attrs->find(aterm2String(name));

                Value & v = env2->bindings[aterm2String(name)];

                if (j == vArg->attrs->end()) {
                    if (!matchDefaultValue(def2, def)) def = 0;
                    if (def == 0) throw TypeError(format("the argument named `%1%' required by the function is missing")
                        % aterm2String(name));
                    v.type = tThunk;
                    v.thunk.env = env2;
                    v.thunk.expr = def;
                } else {
                    attrsUsed++;
                    v.type = tCopy;
                    v.val = &j->second;
                }

            }

            /* Check that each actual argument is listed as a formal
               argument (unless the attribute match specifies a
               `...').  TODO: show the names of the
               expected/unexpected arguments. */
            if (ellipsis == eFalse && attrsUsed != vArg->attrs->size())
                throw TypeError("function called with unexpected argument");
        }

        else abort();

        eval(env2, v.lambda.body, v);
        return;
    }

    abort();
}

void doTest(string s)
{
    EvalState state;
    Expr e = parseExprFromString(state, s, "/");
    printMsg(lvlError, format(">>>>> %1%") % e);
    Value v;
    eval(0, e, v);
    printMsg(lvlError, format("result: %1%") % v);
}

void run(Strings args)
{
    printMsg(lvlError, format("size of value: %1% bytes") % sizeof(Value));

    doTest("123");
    doTest("{ x = 1; y = 2; }");
    doTest("{ x = 1; y = 2; }.y");
    doTest("rec { x = 1; y = x; }.y");
    doTest("(x: x) 1");
    doTest("(x: y: y) 1 2");
    doTest("x: x");
    doTest("({x, y}: x) { x = 1; y = 2; }");
    doTest("({x, y}@args: args.x) { x = 1; y = 2; }");
    doTest("(args@{x, y}: args.x) { x = 1; y = 2; }");
    doTest("({x ? 1}: x) { }");
    doTest("({x ? 1, y ? x}: y) { x = 2; }");
    doTest("({x, y, ...}: x) { x = 1; y = 2; z = 3; }");
    doTest("({x, y, ...}@args: args.z) { x = 1; y = 2; z = 3; }");

    //Expr e = parseExprFromString(state, "let x = \"a\"; in x + \"b\"", "/");
    //Expr e = parseExprFromString(state, "(x: x + \"b\") \"a\"", "/");
    //Expr e = parseExprFromString(state, "\"a\" + \"b\"", "/");
    //Expr e = parseExprFromString(state, "\"a\" + \"b\"", "/");

    printMsg(lvlError, format("alloced %1% values") % nrValues);
    printMsg(lvlError, format("alloced %1% environments") % nrEnvs);
}

void printHelp()
{
}

string programId = "eval-test";
<commit_msg>* Implement blackholing.<commit_after>#include "nixexpr.hh"
#include "parser.hh"
#include "hash.hh"
#include "util.hh"
#include "nixexpr-ast.hh"

#include <cstdlib>

using namespace nix;

struct Env;
struct Value;

typedef std::map<string, Value> Bindings;

struct Env
{
    Env * up;
    Bindings bindings;
};

typedef enum {
    tInt = 1,
    tAttrs,
    tThunk,
    tLambda,
    tCopy,
    tBlackhole
} ValueType;

struct Value
{
    ValueType type;
    union
    {
        int integer;
        Bindings * attrs;
        struct {
            Env * env;
            Expr expr;
        } thunk;
        struct {
            Env * env;
            Pattern pat;
            Expr body;
        } lambda;
        Value * val;
    };
};

std::ostream & operator << (std::ostream & str, Value & v)
{
    switch (v.type) {
    case tInt:
        str << v.integer;
        break;
    case tAttrs:
        str << "{ ";
        foreach (Bindings::iterator, i, *v.attrs)
            str << i->first << " = " << i->second << "; ";
        str << "}";
        break;
    case tThunk:
        str << "<CODE>";
        break;
    case tLambda:
        str << "<LAMBDA>";
        break;
    default:
        abort();
    }
    return str;
}

static void eval(Env * env, Expr e, Value & v);

void forceValue(Value & v)
{
    if (v.type == tThunk) {
        v.type = tBlackhole;
        eval(v.thunk.env, v.thunk.expr, v);
    }
    else if (v.type == tCopy) {
        forceValue(*v.val);
        v = *v.val;
    }
    else if (v.type == tBlackhole)
        throw EvalError("infinite recursion encountered");
}

Value * lookupVar(Env * env, const string & name)
{
    for ( ; env; env = env->up) {
        Bindings::iterator i = env->bindings.find(name);
        if (i != env->bindings.end()) return &i->second;
    }
    throw Error("undefined variable");
}

unsigned long nrValues = 0;

unsigned long nrEnvs = 0;

Env * allocEnv()
{
    nrEnvs++;
    return new Env;
}

static void eval(Env * env, Expr e, Value & v)
{
    printMsg(lvlError, format("eval: %1%") % e);

    ATerm name;
    if (matchVar(e, name)) {
        Value * v2 = lookupVar(env, aterm2String(name));
        forceValue(*v2);
        v = *v2;
        return;
    }

    int n;
    if (matchInt(e, n)) {
        v.type = tInt;
        v.integer = n;
        return;
    }

    ATermList es;
    if (matchAttrs(e, es)) {
        v.type = tAttrs;
        v.attrs = new Bindings;
        ATerm e2, pos;
        for (ATermIterator i(es); i; ++i) {
            if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */
            Value & v2 = (*v.attrs)[aterm2String(name)];
            nrValues++;
            v2.type = tThunk;
            v2.thunk.env = env;
            v2.thunk.expr = e2;
        }
        return;
    }

    ATermList rbnds, nrbnds;
    if (matchRec(e, rbnds, nrbnds)) {
        Env * env2 = allocEnv();
        env2->up = env;

        v.type = tAttrs;
        v.attrs = &env2->bindings;
        ATerm name, e2, pos;
        for (ATermIterator i(rbnds); i; ++i) {
            if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */
            Value & v2 = env2->bindings[aterm2String(name)];
            nrValues++;
            v2.type = tThunk;
            v2.thunk.env = env2;
            v2.thunk.expr = e2;
        }

        return;
    }

    Expr e2;
    if (matchSelect(e, e2, name)) {
        eval(env, e2, v);
        if (v.type != tAttrs) throw TypeError("expected attribute set");
        Bindings::iterator i = v.attrs->find(aterm2String(name));
        if (i == v.attrs->end()) throw TypeError("attribute not found");
        forceValue(i->second);
        v = i->second;
        return;
    }

    Pattern pat; Expr body; Pos pos;
    if (matchFunction(e, pat, body, pos)) {
        v.type = tLambda;
        v.lambda.env = env;
        v.lambda.pat = pat;
        v.lambda.body = body;
        return;
    }

    Expr fun, arg;
    if (matchCall(e, fun, arg)) {
        eval(env, fun, v);
        if (v.type != tLambda) throw TypeError("expected function");

        Env * env2 = allocEnv();
        env2->up = env;

        ATermList formals; ATerm ellipsis;

        if (matchVarPat(v.lambda.pat, name)) {
            Value & vArg = env2->bindings[aterm2String(name)];
            vArg.type = tThunk;
            vArg.thunk.env = env;
            vArg.thunk.expr = arg;
        }

        else if (matchAttrsPat(v.lambda.pat, formals, ellipsis, name)) {
            Value * vArg;
            Value vArg_;

            if (name == sNoAlias)
                vArg = &vArg_;
            else
                vArg = &env2->bindings[aterm2String(name)];

            eval(env, arg, *vArg);
            if (vArg->type != tAttrs) throw TypeError("expected attribute set");

            /* For each formal argument, get the actual argument.  If
               there is no matching actual argument but the formal
               argument has a default, use the default. */
            unsigned int attrsUsed = 0;
            for (ATermIterator i(formals); i; ++i) {
                Expr name, def;
                DefaultValue def2;
                if (!matchFormal(*i, name, def2)) abort(); /* can't happen */

                Bindings::iterator j = vArg->attrs->find(aterm2String(name));

                Value & v = env2->bindings[aterm2String(name)];

                if (j == vArg->attrs->end()) {
                    if (!matchDefaultValue(def2, def)) def = 0;
                    if (def == 0) throw TypeError(format("the argument named `%1%' required by the function is missing")
                        % aterm2String(name));
                    v.type = tThunk;
                    v.thunk.env = env2;
                    v.thunk.expr = def;
                } else {
                    attrsUsed++;
                    v.type = tCopy;
                    v.val = &j->second;
                }
            }

            /* Check that each actual argument is listed as a formal
               argument (unless the attribute match specifies a
               `...').  TODO: show the names of the
               expected/unexpected arguments. */
            if (ellipsis == eFalse && attrsUsed != vArg->attrs->size())
                throw TypeError("function called with unexpected argument");
        }

        else abort();

        eval(env2, v.lambda.body, v);
        return;
    }

    abort();
}

void doTest(string s)
{
    EvalState state;
    Expr e = parseExprFromString(state, s, "/");
    printMsg(lvlError, format(">>>>> %1%") % e);
    Value v;
    eval(0, e, v);
    printMsg(lvlError, format("result: %1%") % v);
}

void run(Strings args)
{
    printMsg(lvlError, format("size of value: %1% bytes") % sizeof(Value));

    doTest("123");
    doTest("{ x = 1; y = 2; }");
    doTest("{ x = 1; y = 2; }.y");
    doTest("rec { x = 1; y = x; }.y");
    doTest("(x: x) 1");
    doTest("(x: y: y) 1 2");
    doTest("x: x");
    doTest("({x, y}: x) { x = 1; y = 2; }");
    doTest("({x, y}@args: args.x) { x = 1; y = 2; }");
    doTest("(args@{x, y}: args.x) { x = 1; y = 2; }");
    doTest("({x ? 1}: x) { }");
    doTest("({x ? 1, y ? x}: y) { x = 2; }");
    doTest("({x, y, ...}: x) { x = 1; y = 2; z = 3; }");
    doTest("({x, y, ...}@args: args.z) { x = 1; y = 2; z = 3; }");
    //doTest("({x ? y, y ? x}: y) { }");

    printMsg(lvlError, format("alloced %1% values") % nrValues);
    printMsg(lvlError, format("alloced %1% environments") % nrEnvs);
}

void printHelp()
{
}

string programId = "eval-test";
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <iostream>
#include <stdexcept>
#include <stdio.h>
#include <expat.h>
#include <string.h>
#include <fstream>
#include <string>
#include <stack>
#include <iomanip>

#include <votca/tools/property.h>
#include <votca/tools/colors.h>
#include <votca/tools/tokenizer.h>
#include <votca/tools/propertyiomanipulator.h>

#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#include <unistd.h>

namespace votca { namespace tools {

// ostream modifier defines the output format, level, indentation
const int Property::IOindex = std::ios_base::xalloc();

Property &Property::get(const string &key)
{
    Tokenizer tok(key, ".");
    Tokenizer::iterator n;

    n = tok.begin();
    if(n==tok.end()) return *this;

    Property *p;
    map<string, Property*>::iterator iter;
    if(*n=="") {
        p = this;
    }
    else {
        iter = _map.find(*n);

        if(iter == _map.end())
            throw runtime_error("property not found: " + key);

        p = (((*iter).second));
    }
    ++n;
    try {
        for(; n!=tok.end(); ++n) {
            p = &p->get(*n);
        }
    }
    catch(string err) { // catch here to get full key in exception
        throw runtime_error("property not found: " + key);
    }

    return *p;
}

std::list<Property *> Property::Select(const string &filter)
{
    Tokenizer tok(filter, ".");

    std::list<Property *> selection;

    if(tok.begin()==tok.end()) return selection;

    selection.push_back(this);

    for (Tokenizer::iterator n = tok.begin();
            n != tok.end(); ++n) {
        std::list<Property *> childs;
        for (std::list<Property *>::iterator p = selection.begin();
                p != selection.end(); ++p) {
                for (list<Property>::iterator iter = (*p)->_properties.begin();
                    iter != (*p)->_properties.end(); ++iter) {
                    if (wildcmp((*n).c_str(), (*iter).name().c_str())) {
                        childs.push_back(&(*iter));
                    }
                }
        }
        selection = childs;
    }

    return selection;
}

static void start_hndl(void *data, const char *el, const char **attr)
{
    stack<Property *> *property_stack =
        (stack<Property *> *)XML_GetUserData((XML_Parser*)data);

    Property *cur = property_stack->top();
    Property &np = cur->add(el, "");

    for (int i = 0; attr[i]; i += 2)
        np.setAttribute(attr[i], attr[i + 1]);

    property_stack->push(&np);
}

static void end_hndl(void *data, const char *el)
{
    stack<Property *> *property_stack =
        (stack<Property *> *)XML_GetUserData((XML_Parser*)data);
    property_stack->pop();
}

void char_hndl(void *data, const char *txt, int txtlen)
{
    stack<Property *> *property_stack =
        (stack<Property *> *)XML_GetUserData((XML_Parser*)data);

    Property *cur = property_stack->top();
    cur->value().append(txt, txtlen);
}

bool load_property_from_xml(Property &p, string filename)
{
  XML_Parser parser = XML_ParserCreate(NULL);
  if (! parser)
    throw std::runtime_error("Couldn't allocate memory for xml parser");

  XML_UseParserAsHandlerArg(parser);
  XML_SetElementHandler(parser, start_hndl, end_hndl);
  XML_SetCharacterDataHandler(parser, char_hndl);

  ifstream fl;
  fl.open(filename.c_str());
  if(!fl.is_open())
    throw std::ios_base::failure("Error on open xml file: " + filename);

  stack<Property *> pstack;
  pstack.push(&p);

  XML_SetUserData(parser, (void*)&pstack);
  while(!fl.eof()) {
    string line;
    getline(fl, line);
    line=line + "\n";
    if (! XML_Parse(parser, line.c_str(), line.length(), fl.eof()))
      throw  std::ios_base::failure(filename + ": Parse error at line " +
          boost::lexical_cast<string>(XML_GetCurrentLineNumber(parser)) + "\n" +
          XML_ErrorString(XML_GetErrorCode(parser)));
  }
  fl.close();
  return true;
}

void PrintNodeTXT(std::ostream &out, Property &p, const int start_level, int level=0, string prefix="", string offset="")
{

    list<Property>::iterator iter;

    if((p.value() != "") || p.HasChilds() ) {

        if ( level >= start_level ) {
                if((p.value()).find_first_not_of("\t\n ") != std::string::npos)
                        out << offset << prefix << " = " << p.value() << endl;
        } else {
            prefix="";
        }
    }

    for(iter = p.begin(); iter!=p.end(); ++iter) {
        if(prefix=="") {
            level++;
            PrintNodeTXT(out, (*iter), start_level, level, prefix + (*iter).name(), offset );
            level--;
        } else {
            level++;
            PrintNodeTXT(out, (*iter), start_level, level, prefix + "." + (*iter).name(), offset );
            level--;
        }
    }

}

void PrintNodeXML(std::ostream &out, Property &p, PropertyIOManipulator *piom, int level=0, string offset="")
{
    list<Property>::iterator iter;
    Property::AttributeIterator ia;
    bool _endl = true;
    bool has_value;

    const ColorSchemeBase *color = &DEFAULT_COLORS;

    string indent("");
    int start_level(0);

    if ( piom ) {
        start_level = piom->getLevel();
        indent   = piom->getIndentation();
        color = piom->getColorScheme();
    }

    string cKey = color->Magenta();
    string cAttribute = color->Blue();
    string cAttributeValue = color->Green();
    string cReset = color->Reset();

    // print starting only from the start_level (the first node (level 0) can be <> </>)
        if ( level >= start_level )  {
            // print the node name
            out << indent << offset << "<" << cKey << p.name() << cReset;
            // print the node attributes
            for(ia = p.firstAttribute(); ia!=p.lastAttribute(); ++ia)
                out << " "
                    << cAttribute << ia->first << cReset
                    << "=\""
                    << cAttributeValue << ia->second << cReset << "\"" ;
            out << ">";

            // print node value if it is not empty
            has_value = ( (p.value()).find_first_not_of("\t\n ") != std::string::npos );
            if( has_value ) {
                out <<  cAttributeValue <<  p.value() << cReset;
                _endl = false;
            }

            // check if we need the end of the line or not
            if( !has_value &&  p.HasChilds() ) out << endl;
            if( !has_value &&  !p.HasChilds() ) _endl = false;
        }

        // continue iteratively through the rest of the nodes
        for(iter = p.begin(); iter!=p.end(); ++iter) {
            level++;
            if (  level > start_level ) offset += "\t";
            PrintNodeXML(out, (*iter), piom, level, offset);
            if (  level > start_level ) offset.resize(offset.size()-1);
            level--;
        }

        if ( level >= start_level ) {
            if ( _endl ) {
                         out << indent << offset << "</" << cKey << p.name() << cReset << ">" << endl;
            } else {
                if (has_value) { // avoid indent after the value
                        out << "</" << cKey << p.name() << cReset << ">" << endl;
                } else {
                        out << indent << offset << "</" << cKey << p.name() << cReset << ">" << endl;
                }
            }
        }
}

void PrintNodeTEX(std::ostream &out, Property &p, PropertyIOManipulator *piom, int level=0, string prefix="") {

    list<Property>::iterator iter;
    string head_name;
    string _label(""); // reference of the xml file in the manual
    string _section(""); // reference of the description section in the manual
    string _help("");
    string _default(""); // default value if supplied
    string _unit(""); //unit, if supplied

   int start_level(0);

    if ( piom ) {
        start_level = piom->getLevel();
    }

    string header_format("\\subsection{%1%}\n"
                         "\\label{%2%}\n%3%\n"
                         "\\rowcolors{1}{invisiblegray}{white}\n"
                         "{\\small\n "
                         "\\begin{longtable}{m{3cm}|m{2cm}|m{1cm}|m{8cm}}\n"
                         " option & default & unit & description\\\\\n\\hline\n");

    string footer_format("\\end{longtable}\n}\n"
                         "\\noindent Return to the description of \\slink{%1%}{\\texttt{%2%}}.\n");

    string body_format(" \\hspace{%1%pt}\\hypertarget{%2%}{%3%} & %4% & %5% & %6% \\\\\n");

    // if this is the head node, print the header
    if ( level == start_level )  {
            head_name = p.name();
            _label = "calc:" + head_name;
            if ( p.hasAttribute("section") ) _section = p.getAttribute<string>("section");
            if ( p.hasAttribute("help") ) _help = p.getAttribute<string>("help");
            out << boost::format(header_format) % head_name % _label % _help;
            prefix = p.name();
     }

    if ( level > start_level ) {

        // if this node has children or a value or is not the first, start recursive printing
        if( ( p.value() != "" || p.HasChilds() ) && level > -1) {
            string _tex_name = boost::replace_all_copy( p.name(), "_", "\\_" );

            if ( p.hasAttribute("default") ) _default = p.getAttribute<string>("default");
            if ( p.hasAttribute("unit") ) _unit = p.getAttribute<string>("unit");
            if ( p.hasAttribute("help") ) _help = p.getAttribute<string>("help");

            out << boost::format(body_format) % int((level-start_level-1)*10)
                    % prefix
                    % _tex_name
                    % _default
                    % _unit
                    % _help;
        }
    }

    // continue iteratively through the rest of the nodes
    for(iter = p.begin(); iter != p.end(); ++iter) {
        if(prefix=="") {
            level++;
            PrintNodeTEX(out, (*iter), piom, level, prefix);
            level--;
        } else {
            level++;
            PrintNodeTEX(out, (*iter), piom, level, prefix);
            level--;
        }
    }

    // if this is the head node, print the footer
    if ( level == start_level )  out << boost::format(footer_format) % _section % head_name;
}

void PrintNodeHLP(std::ostream &out, Property &p, const int start_level=0, int level=0, string prefix="",  string offset="") {

    list<Property>::iterator iter;
    string head_name;
    string _help("");
    string _unit("");
    string _default("");
    string _name("");

    typedef Color<csRGB> ColorRGB; // use the RGB palette
    ColorRGB RGB; // Instance of an RGB palette
    string fmt =  "t|%1%%|15t|" + string(RGB.Blue()) + "%2%"
                                + string(RGB.Green()) + "%|40t|%3%%|55t|"
                                + string(RGB.Reset()) + "%4%\n";

    int _offset = level;

    // if this is the head node, print the header
    if ( level == start_level ) {
            head_name = string(RGB.Magenta()) + p.name();
            if ( p.hasAttribute("help") ) {
                if  ( p.hasAttribute("help") ) _help = string(RGB.Red()) + p.getAttribute<string>("help");
                out << boost::format(" %1%: %|18t| %2%" + string(RGB.Reset()) + "\n") % head_name % _help;
            }
            _offset=0;
            out << boost::format("%|3" + fmt) % "OPTION" % "DEFAULT" % "UNIT" % "DESCRIPTION";
    }

    if ( level > start_level ) {

            string ofmt;
            ofmt = "%|" + boost::lexical_cast<string>(_offset) + fmt;
            //cout << ofmt << " " << fmt << endl;
             if  ( p.hasAttribute("unit") )
                _unit = p.getAttribute<string>("unit");
            if  ( p.hasAttribute("default") )
                _default = p.getAttribute<string>("default");
            if  ( p.hasAttribute("help") ) _help = p.getAttribute<string>("help") ;
            if ( !_unit.empty() ) _unit = "[" + _unit + "]";
            if ( !_default.empty() ) _default = "(" + _default + ")";

             _name = p.name();

            out << boost::format(ofmt)
                    % _name
                    % _default
                    % _unit
                    % _help;
    }

    for(iter = p.begin(); iter != p.end(); ++iter) {
        if(prefix=="") {
            _offset = level + 2; level++;
            PrintNodeHLP(out, (*iter), start_level, level, (*iter).name(), offset);
            _offset = level - 2; level--;
        } else {
            _offset = level + 2; level++;
            PrintNodeHLP(out, (*iter), start_level, level, prefix + "." + (*iter).name(), offset);
            _offset = level - 2; level--;
        }
    }
}

std::ostream &operator<<(std::ostream &out, Property& p)
{
    if (!out.good())
        return out;

    std::ostream::sentry sentry(out);

    if(sentry)
    {
        // get the property format object attached to the stream
        PropertyIOManipulator *pm =
                (PropertyIOManipulator*)out.pword(Property::getIOindex());

        string _indentation("");
        int _level = 0;

        PropertyIOManipulator::Type _type = PropertyIOManipulator::XML;
        if (pm) {
            _indentation = pm->getIndentation();
            _level = pm->getLevel();
            _type = pm->getType();
            // check if we > or >> to a file and remove color codes
            // if ( out.tellp() != -1 )  - not suitable for pipes
            if( !isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO) ) {
                pm->setColorScheme<csDefault>();
            }

        }

         switch( _type )
        {
        default:
            PrintNodeTXT(out, p, _level);
            case PropertyIOManipulator::XML:
            PrintNodeXML(out, p, pm);
            break;
        case PropertyIOManipulator::TXT:
            PrintNodeTXT(out, p, _level, 0, "", _indentation);
            break;
         case PropertyIOManipulator::TEX:
            PrintNodeTEX(out, p, pm);
            break;
        case PropertyIOManipulator::HLP:
            PrintNodeHLP(out, p, _level, 0, "", _indentation);
            break;
        }
        //out << endl;
    }

    return out;
};

}}
<commit_msg>fix a gcc warning<commit_after>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <iostream>
#include <stdexcept>
#include <stdio.h>
#include <expat.h>
#include <string.h>
#include <fstream>
#include <string>
#include <stack>
#include <iomanip>

#include <votca/tools/property.h>
#include <votca/tools/colors.h>
#include <votca/tools/tokenizer.h>
#include <votca/tools/propertyiomanipulator.h>

#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#include <unistd.h>

namespace votca { namespace tools {

// ostream modifier defines the output format, level, indentation
const int Property::IOindex = std::ios_base::xalloc();

Property &Property::get(const string &key)
{
    Tokenizer tok(key, ".");
    Tokenizer::iterator n;

    n = tok.begin();
    if(n==tok.end()) return *this;

    Property *p;
    map<string, Property*>::iterator iter;
    if(*n=="") {
        p = this;
    }
    else {
        iter = _map.find(*n);

        if(iter == _map.end())
            throw runtime_error("property not found: " + key);

        p = (((*iter).second));
    }
    ++n;
    try {
        for(; n!=tok.end(); ++n) {
            p = &p->get(*n);
        }
    }
    catch(string err) { // catch here to get full key in exception
        throw runtime_error("property not found: " + key);
    }

    return *p;
}

std::list<Property *> Property::Select(const string &filter)
{
    Tokenizer tok(filter, ".");

    std::list<Property *> selection;

    if(tok.begin()==tok.end()) return selection;

    selection.push_back(this);

    for (Tokenizer::iterator n = tok.begin();
            n != tok.end(); ++n) {
        std::list<Property *> childs;
        for (std::list<Property *>::iterator p = selection.begin();
                p != selection.end(); ++p) {
                for (list<Property>::iterator iter = (*p)->_properties.begin();
                    iter != (*p)->_properties.end(); ++iter) {
                    if (wildcmp((*n).c_str(), (*iter).name().c_str())) {
                        childs.push_back(&(*iter));
                    }
                }
        }
        selection = childs;
    }

    return selection;
}

static void start_hndl(void *data, const char *el, const char **attr)
{
    stack<Property *> *property_stack =
        (stack<Property *> *)XML_GetUserData((XML_Parser*)data);

    Property *cur = property_stack->top();
    Property &np = cur->add(el, "");

    for (int i = 0; attr[i]; i += 2)
        np.setAttribute(attr[i], attr[i + 1]);

    property_stack->push(&np);
}

static void end_hndl(void *data, const char *el)
{
    stack<Property *> *property_stack =
        (stack<Property *> *)XML_GetUserData((XML_Parser*)data);
    property_stack->pop();
}

void char_hndl(void *data, const char *txt, int txtlen)
{
    stack<Property *> *property_stack =
        (stack<Property *> *)XML_GetUserData((XML_Parser*)data);

    Property *cur = property_stack->top();
    cur->value().append(txt, txtlen);
}

bool load_property_from_xml(Property &p, string filename)
{
  XML_Parser parser = XML_ParserCreate(NULL);
  if (! parser)
    throw std::runtime_error("Couldn't allocate memory for xml parser");

  XML_UseParserAsHandlerArg(parser);
  XML_SetElementHandler(parser, start_hndl, end_hndl);
  XML_SetCharacterDataHandler(parser, char_hndl);

  ifstream fl;
  fl.open(filename.c_str());
  if(!fl.is_open())
    throw std::ios_base::failure("Error on open xml file: " + filename);

  stack<Property *> pstack;
  pstack.push(&p);

  XML_SetUserData(parser, (void*)&pstack);
  while(!fl.eof()) {
    string line;
    getline(fl, line);
    line=line + "\n";
    if (! XML_Parse(parser, line.c_str(), line.length(), fl.eof()))
      throw  std::ios_base::failure(filename + ": Parse error at line " +
          boost::lexical_cast<string>(XML_GetCurrentLineNumber(parser)) + "\n" +
          XML_ErrorString(XML_GetErrorCode(parser)));
  }
  fl.close();
  return true;
}

void PrintNodeTXT(std::ostream &out, Property &p, const int start_level, int level=0, string prefix="", string offset="")
{

    list<Property>::iterator iter;

    if((p.value() != "") || p.HasChilds() ) {

        if ( level >= start_level ) {
                if((p.value()).find_first_not_of("\t\n ") != std::string::npos)
                        out << offset << prefix << " = " << p.value() << endl;
        } else {
            prefix="";
        }
    }

    for(iter = p.begin(); iter!=p.end(); ++iter) {
        if(prefix=="") {
            level++;
            PrintNodeTXT(out, (*iter), start_level, level, prefix + (*iter).name(), offset );
            level--;
        } else {
            level++;
            PrintNodeTXT(out, (*iter), start_level, level, prefix + "." + (*iter).name(), offset );
            level--;
        }
    }

}

void PrintNodeXML(std::ostream &out, Property &p, PropertyIOManipulator *piom, int level=0, string offset="")
{
    list<Property>::iterator iter;
    Property::AttributeIterator ia;
    bool _endl = true;
    bool has_value = false;

    const ColorSchemeBase *color = &DEFAULT_COLORS;

    string indent("");
    int start_level(0);

    if ( piom ) {
        start_level = piom->getLevel();
        indent   = piom->getIndentation();
        color = piom->getColorScheme();
    }

    string cKey = color->Magenta();
    string cAttribute = color->Blue();
    string cAttributeValue = color->Green();
    string cReset = color->Reset();

    // print starting only from the start_level (the first node (level 0) can be <> </>)
        if ( level >= start_level )  {
            // print the node name
            out << indent << offset << "<" << cKey << p.name() << cReset;
            // print the node attributes
            for(ia = p.firstAttribute(); ia!=p.lastAttribute(); ++ia)
                out << " "
                    << cAttribute << ia->first << cReset
                    << "=\""
                    << cAttributeValue << ia->second << cReset << "\"" ;
            out << ">";

            // print node value if it is not empty
            has_value = ( (p.value()).find_first_not_of("\t\n ") != std::string::npos );
            if( has_value ) {
                out <<  cAttributeValue <<  p.value() << cReset;
                _endl = false;
            }

            // check if we need the end of the line or not
            if( !has_value &&  p.HasChilds() ) out << endl;
            if( !has_value &&  !p.HasChilds() ) _endl = false;
        }

        // continue iteratively through the rest of the nodes
        for(iter = p.begin(); iter!=p.end(); ++iter) {
            level++;
            if (  level > start_level ) offset += "\t";
            PrintNodeXML(out, (*iter), piom, level, offset);
            if (  level > start_level ) offset.resize(offset.size()-1);
            level--;
        }

        if ( level >= start_level ) {
            if ( _endl ) {
                         out << indent << offset << "</" << cKey << p.name() << cReset << ">" << endl;
            } else {
                if (has_value) { // avoid indent after the value
                        out << "</" << cKey << p.name() << cReset << ">" << endl;
                } else {
                        out << indent << offset << "</" << cKey << p.name() << cReset << ">" << endl;
                }
            }
        }
}

void PrintNodeTEX(std::ostream &out, Property &p, PropertyIOManipulator *piom, int level=0, string prefix="") {

    list<Property>::iterator iter;
    string head_name;
    string _label(""); // reference of the xml file in the manual
    string _section(""); // reference of the description section in the manual
    string _help("");
    string _default(""); // default value if supplied
    string _unit(""); //unit, if supplied

   int start_level(0);

    if ( piom ) {
        start_level = piom->getLevel();
    }

    string header_format("\\subsection{%1%}\n"
                         "\\label{%2%}\n%3%\n"
                         "\\rowcolors{1}{invisiblegray}{white}\n"
                         "{\\small\n "
                         "\\begin{longtable}{m{3cm}|m{2cm}|m{1cm}|m{8cm}}\n"
                         " option & default & unit & description\\\\\n\\hline\n");

    string footer_format("\\end{longtable}\n}\n"
                         "\\noindent Return to the description of \\slink{%1%}{\\texttt{%2%}}.\n");

    string body_format(" \\hspace{%1%pt}\\hypertarget{%2%}{%3%} & %4% & %5% & %6% \\\\\n");

    // if this is the head node, print the header
    if ( level == start_level )  {
            head_name = p.name();
            _label = "calc:" + head_name;
            if ( p.hasAttribute("section") ) _section = p.getAttribute<string>("section");
            if ( p.hasAttribute("help") ) _help = p.getAttribute<string>("help");
            out << boost::format(header_format) % head_name % _label % _help;
            prefix = p.name();
     }

    if ( level > start_level ) {

        // if this node has children or a value or is not the first, start recursive printing
        if( ( p.value() != "" || p.HasChilds() ) && level > -1) {
            string _tex_name = boost::replace_all_copy( p.name(), "_", "\\_" );

            if ( p.hasAttribute("default") ) _default = p.getAttribute<string>("default");
            if ( p.hasAttribute("unit") ) _unit = p.getAttribute<string>("unit");
            if ( p.hasAttribute("help") ) _help = p.getAttribute<string>("help");

            out << boost::format(body_format) % int((level-start_level-1)*10)
                    % prefix
                    % _tex_name
                    % _default
                    % _unit
                    % _help;
        }
    }

    // continue iteratively through the rest of the nodes
    for(iter = p.begin(); iter != p.end(); ++iter) {
        if(prefix=="") {
            level++;
            PrintNodeTEX(out, (*iter), piom, level, prefix);
            level--;
        } else {
            level++;
            PrintNodeTEX(out, (*iter), piom, level, prefix);
            level--;
        }
    }

    // if this is the head node, print the footer
    if ( level == start_level )  out << boost::format(footer_format) % _section % head_name;
}

void PrintNodeHLP(std::ostream &out, Property &p, const int start_level=0, int level=0, string prefix="",  string offset="") {

    list<Property>::iterator iter;
    string head_name;
    string _help("");
    string _unit("");
    string _default("");
    string _name("");

    typedef Color<csRGB> ColorRGB; // use the RGB palette
    ColorRGB RGB; // Instance of an RGB palette
    string fmt =  "t|%1%%|15t|" + string(RGB.Blue()) + "%2%"
                                + string(RGB.Green()) + "%|40t|%3%%|55t|"
                                + string(RGB.Reset()) + "%4%\n";

    int _offset = level;

    // if this is the head node, print the header
    if ( level == start_level ) {
            head_name = string(RGB.Magenta()) + p.name();
            if ( p.hasAttribute("help") ) {
                if  ( p.hasAttribute("help") ) _help = string(RGB.Red()) + p.getAttribute<string>("help");
                out << boost::format(" %1%: %|18t| %2%" + string(RGB.Reset()) + "\n") % head_name % _help;
            }
            _offset=0;
            out << boost::format("%|3" + fmt) % "OPTION" % "DEFAULT" % "UNIT" % "DESCRIPTION";
    }

    if ( level > start_level ) {

            string ofmt;
            ofmt = "%|" + boost::lexical_cast<string>(_offset) + fmt;
            //cout << ofmt << " " << fmt << endl;
             if  ( p.hasAttribute("unit") )
                _unit = p.getAttribute<string>("unit");
            if  ( p.hasAttribute("default") )
                _default = p.getAttribute<string>("default");
            if  ( p.hasAttribute("help") ) _help = p.getAttribute<string>("help") ;
            if ( !_unit.empty() ) _unit = "[" + _unit + "]";
            if ( !_default.empty() ) _default = "(" + _default + ")";

             _name = p.name();

            out << boost::format(ofmt)
                    % _name
                    % _default
                    % _unit
                    % _help;
    }

    for(iter = p.begin(); iter != p.end(); ++iter) {
        if(prefix=="") {
            _offset = level + 2; level++;
            PrintNodeHLP(out, (*iter), start_level, level, (*iter).name(), offset);
            _offset = level - 2; level--;
        } else {
            _offset = level + 2; level++;
            PrintNodeHLP(out, (*iter), start_level, level, prefix + "." + (*iter).name(), offset);
            _offset = level - 2; level--;
        }
    }
}

std::ostream &operator<<(std::ostream &out, Property& p)
{
    if (!out.good())
        return out;

    std::ostream::sentry sentry(out);

    if(sentry)
    {
        // get the property format object attached to the stream
        PropertyIOManipulator *pm =
                (PropertyIOManipulator*)out.pword(Property::getIOindex());

        string _indentation("");
        int _level = 0;

        PropertyIOManipulator::Type _type = PropertyIOManipulator::XML;
        if (pm) {
            _indentation = pm->getIndentation();
            _level = pm->getLevel();
            _type = pm->getType();
            // check if we > or >> to a file and remove color codes
            // if ( out.tellp() != -1 )  - not suitable for pipes
            if( !isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO) ) {
                pm->setColorScheme<csDefault>();
            }

        }

         switch( _type )
        {
        default:
            PrintNodeTXT(out, p, _level);
            case PropertyIOManipulator::XML:
            PrintNodeXML(out, p, pm);
            break;
        case PropertyIOManipulator::TXT:
            PrintNodeTXT(out, p, _level, 0, "", _indentation);
            break;
         case PropertyIOManipulator::TEX:
            PrintNodeTEX(out, p, pm);
            break;
        case PropertyIOManipulator::HLP:
            PrintNodeHLP(out, p, _level, 0, "", _indentation);
            break;
        }
        //out << endl;
    }

    return out;
};

}}
<|endoftext|>


<commit_before>// Time:  O(n^2)
// Space: O(n)

class MyCalendarThree {
public:
    MyCalendarThree() {

    }

    int book(int start, int end) {
        ++books_[start];
        --books_[end];
        int result = 0;
        int cnt = 0;
        for (auto &book : books_) {
            cnt += book.second;
            result = max(result, cnt);
        }
        return result;
    }

private:
    map<int, int> books_;
};

/**
 * Your MyCalendarThree object will be instantiated and called as such:
 * MyCalendarThree obj = new MyCalendarThree();
 * int param_1 = obj.book(start,end);
 */
<commit_msg>Update my-calendar-iii.cpp<commit_after>// Time:  O(n^2)
// Space: O(n)

class MyCalendarThree {
public:
    MyCalendarThree() {

    }

    int book(int start, int end) {
        ++books_[start];
        --books_[end];
        int result = 0;
        int cnt = 0;
        for (const auto &book : books_) {
            cnt += book.second;
            result = max(result, cnt);
        }
        return result;
    }

private:
    map<int, int> books_;
};

/**
 * Your MyCalendarThree object will be instantiated and called as such:
 * MyCalendarThree obj = new MyCalendarThree();
 * int param_1 = obj.book(start,end);
 */
<|endoftext|>