<commit_before>/*
 / _____)             _              | |
( (____  _____ ____ _| |_ _____  ____| |__
 \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 _____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
    ( C )2014 Semtech

Description: -

License: Revised BSD License, see LICENSE.TXT file include in the project

Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
*/
#include "sx1276-hal.h"

const RadioRegisters_t SX1276MB1xAS::RadioRegsInit[] =
{
    { MODEM_FSK , REG_LNA                , 0x23 },
    { MODEM_FSK , REG_RXCONFIG           , 0x1E },
    { MODEM_FSK , REG_RSSICONFIG         , 0xD2 },
    { MODEM_FSK , REG_PREAMBLEDETECT     , 0xAA },
    { MODEM_FSK , REG_OSC                , 0x07 },
    { MODEM_FSK , REG_SYNCCONFIG         , 0x12 },
    { MODEM_FSK , REG_SYNCVALUE1         , 0xC1 },
    { MODEM_FSK , REG_SYNCVALUE2         , 0x94 },
    { MODEM_FSK , REG_SYNCVALUE3         , 0xC1 },
    { MODEM_FSK , REG_PACKETCONFIG1      , 0x98 },
    { MODEM_FSK , REG_FIFOTHRESH         , 0x8F },
    { MODEM_FSK , REG_IMAGECAL           , 0x02 },
    { MODEM_FSK , REG_DIOMAPPING1        , 0x00 },
    { MODEM_FSK , REG_DIOMAPPING2        , 0x30 },
    { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },
};

SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ),
                            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ),
                            PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
                            PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
                            PinName antSwitch )
                            : SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, mosi, miso, sclk, nss, reset, dio0, dio1, dio2, dio3, dio4, dio5),
                            antSwitch( antSwitch ),
                        #if( defined ( TARGET_NUCLEO_L152RE ) )
                            fake( D8 )
                        #else
                            fake( A3 )
                        #endif
{
    Reset( );

    RxChainCalibration( );

    IoInit( );

    SetOpMode( RF_OPMODE_SLEEP );

    IoIrqInit( dioIrq );

    RadioRegistersInit( );

    SetModem( MODEM_FSK );

    this->settings.State = IDLE ;
}

SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ),
                            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ) )
                        #if defined ( TARGET_NUCLEO_L152RE )
                        :   SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, D10, A0, D2, D3, D4, D5, A3, D9 ), // For NUCLEO L152RE dio4 is on port A3
                            antSwitch( A4 ),
                            fake( D8 )
                        #else
                        :   SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, PA_4, PC_4, PC_10, PC_11, PC_12, PD_2, PB_5, PB_6 ),
                            antSwitch( A4 ),
                            fake( PC_2 )
                        #endif
{
    Reset( );

    boardConnected = UNKNOWN;

    DetectBoardType( );

    RxChainCalibration( );

    IoInit( );

    SetOpMode( RF_OPMODE_SLEEP );
    IoIrqInit( dioIrq );

    RadioRegistersInit( );

    SetModem( MODEM_FSK );

    this->settings.State = IDLE ;
}

//-------------------------------------------------------------------------
//                      Board relative functions
//-------------------------------------------------------------------------
uint8_t SX1276MB1xAS::DetectBoardType( void )
{
    if( boardConnected == UNKNOWN )
    {
        antSwitch.input( );
        wait_ms( 1 );
        if( antSwitch == 1 )
        {
            boardConnected = SX1276MB1LAS;
        }
        else
        {
            boardConnected = SX1276MB1MAS;
        }
        antSwitch.output( );
        wait_ms( 1 );
    }
    return ( boardConnected );
}

void SX1276MB1xAS::IoInit( void )
{
    AntSwInit( );
    SpiInit( );
}

void SX1276MB1xAS::RadioRegistersInit( ){
    uint8_t i = 0;
    for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
    {
        SetModem( RadioRegsInit[i].Modem );
        Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
    }
}

void SX1276MB1xAS::SpiInit( void )
{
    nss = 1;
    spi.format( 8,0 );
    uint32_t frequencyToSet = 8000000;
    #if( defined ( TARGET_NUCLEO_L152RE ) ||  defined ( TARGET_LPC11U6X ) )
        spi.frequency( frequencyToSet );
    #elif( defined ( TARGET_KL25Z ) ) //busclock frequency is halved -> double the spi frequency to compensate
        spi.frequency( frequencyToSet * 2 );
    #else
        #warning "Check the board's SPI frequency"
    #endif
    wait(0.1);
}

void SX1276MB1xAS::IoIrqInit( DioIrqHandler *irqHandlers )
{
    #if( defined ( TARGET_NUCLEO_L152RE ) ||  defined ( TARGET_LPC11U6X ) )
        dio0.mode(PullDown);
        dio1.mode(PullDown);
        dio2.mode(PullDown);
        dio3.mode(PullDown);
        dio4.mode(PullDown);
    #endif
    dio0.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[0] ) );
    dio1.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[1] ) );
    dio2.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[2] ) );
    dio3.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[3] ) );
    dio4.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[4] ) );
}

void SX1276MB1xAS::IoDeInit( void )
{
    //nothing
}

uint8_t SX1276MB1xAS::GetPaSelect( uint32_t channel )
{
    if( channel > RF_MID_BAND_THRESH )
    {
        if( boardConnected == SX1276MB1LAS )
        {
            return RF_PACONFIG_PASELECT_PABOOST;
        }
        else
        {
            return RF_PACONFIG_PASELECT_RFO;
        }
    }
    else
    {
        return RF_PACONFIG_PASELECT_RFO;
    }
}

void SX1276MB1xAS::SetAntSwLowPower( bool status )
{
    if( isRadioActive != status )
    {
        isRadioActive = status;

        if( status == false )
        {
            AntSwInit( );
        }
        else
        {
            AntSwDeInit( );
        }
    }
}

void SX1276MB1xAS::AntSwInit( void )
{
    antSwitch = 0;
}

void SX1276MB1xAS::AntSwDeInit( void )
{
    antSwitch = 0;
}

void SX1276MB1xAS::SetAntSw( uint8_t rxTx )
{
    if( this->rxTx == rxTx )
    {
        //no need to go further
        return;
    }

    this->rxTx = rxTx;

    if( rxTx != 0 )
    {
        antSwitch = 1;
    }
    else
    {
        antSwitch = 0;
    }
}

bool SX1276MB1xAS::CheckRfFrequency( uint32_t frequency )
{
    //TODO: Implement check, currently all frequencies are supported
    return true;
}

void SX1276MB1xAS::Reset( void )
{
    reset.output();
    reset = 0;
    wait_ms( 1 );
    reset.input();
    wait_ms( 6 );
}

void SX1276MB1xAS::Write( uint8_t addr, uint8_t data )
{
    Write( addr, &data, 1 );
}

uint8_t SX1276MB1xAS::Read( uint8_t addr )
{
    uint8_t data;
    Read( addr, &data, 1 );
    return data;
}

void SX1276MB1xAS::Write( uint8_t addr, uint8_t *buffer, uint8_t size )
{
    uint8_t i;

    nss = 0;
    spi.write( addr | 0x80 );
    for( i = 0; i < size; i++ )
    {
        spi.write( buffer[i] );
    }
    nss = 1;
}

void SX1276MB1xAS::Read( uint8_t addr, uint8_t *buffer, uint8_t size )
{
    uint8_t i;

    nss = 0;
    spi.write( addr & 0x7F );
    for( i = 0; i < size; i++ )
    {
        buffer[i] = spi.write( 0 );
    }
    nss = 1;
}

void SX1276MB1xAS::WriteFifo( uint8_t *buffer, uint8_t size )
{
    Write( 0, buffer, size );
}

void SX1276MB1xAS::ReadFifo( uint8_t *buffer, uint8_t size )
{
    Read( 0, buffer, size );
}
<commit_msg>MCU's RXTX debug on LED. Board whitout PB_BOOST.<commit_after>/*
 / _____)             _              | |
( (____  _____ ____ _| |_ _____  ____| |__
 \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 _____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
    ( C )2014 Semtech

Description: -

License: Revised BSD License, see LICENSE.TXT file include in the project

Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
*/
#include "sx1276-hal.h"

const RadioRegisters_t SX1276MB1xAS::RadioRegsInit[] =
{
    { MODEM_FSK , REG_LNA                , 0x23 },
    { MODEM_FSK , REG_RXCONFIG           , 0x1E },
    { MODEM_FSK , REG_RSSICONFIG         , 0xD2 },
    { MODEM_FSK , REG_PREAMBLEDETECT     , 0xAA },
    { MODEM_FSK , REG_OSC                , 0x07 },
    { MODEM_FSK , REG_SYNCCONFIG         , 0x12 },
    { MODEM_FSK , REG_SYNCVALUE1         , 0xC1 },
    { MODEM_FSK , REG_SYNCVALUE2         , 0x94 },
    { MODEM_FSK , REG_SYNCVALUE3         , 0xC1 },
    { MODEM_FSK , REG_PACKETCONFIG1      , 0x98 },
    { MODEM_FSK , REG_FIFOTHRESH         , 0x8F },
    { MODEM_FSK , REG_IMAGECAL           , 0x02 },
    { MODEM_FSK , REG_DIOMAPPING1        , 0x00 },
    { MODEM_FSK , REG_DIOMAPPING2        , 0x30 },
    { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },
};

SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ),
                            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ),
                            PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
                            PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
                            PinName antSwitch )
                            : SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, mosi, miso, sclk, nss, reset, dio0, dio1, dio2, dio3, dio4, dio5),
                            antSwitch( antSwitch ),
                        #if( defined ( TARGET_NUCLEO_L152RE ) )
                            fake( D8 )
                        #else
                            fake( A3 )
                        #endif
{
    Reset( );

    RxChainCalibration( );

    IoInit( );

    SetOpMode( RF_OPMODE_SLEEP );

    IoIrqInit( dioIrq );

    RadioRegistersInit( );

    SetModem( MODEM_FSK );

    this->settings.State = IDLE ;
}

SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ),
                            void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ) )
                        #if defined ( TARGET_NUCLEO_L152RE )
                        :   SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, D10, A0, D2, D3, D4, D5, A3, D9 ), // For NUCLEO L152RE dio4 is on port A3
                            antSwitch( A4 ),
                            fake( D8 )
                        #else
                        :   SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, PA_4, PC_4, PC_10, PC_11, PC_12, PD_2, PB_5, PB_6 ),
                            antSwitch( PB_1 ),
                            fake( PC_2 )
                        #endif
{
    Reset( );

    boardConnected = UNKNOWN;

    DetectBoardType( );

    RxChainCalibration( );

    IoInit( );

    SetOpMode( RF_OPMODE_SLEEP );
    IoIrqInit( dioIrq );

    RadioRegistersInit( );

    SetModem( MODEM_FSK );

    this->settings.State = IDLE ;
}

//-------------------------------------------------------------------------
//                      Board relative functions
//-------------------------------------------------------------------------
uint8_t SX1276MB1xAS::DetectBoardType( void )
{
	boardConnected = SX1276MB1MAS;
    return ( boardConnected );
}

void SX1276MB1xAS::IoInit( void )
{
    AntSwInit( );
    SpiInit( );
}

void SX1276MB1xAS::RadioRegistersInit( ){
    uint8_t i = 0;
    for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
    {
        SetModem( RadioRegsInit[i].Modem );
        Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
    }
}

void SX1276MB1xAS::SpiInit( void )
{
    nss = 1;
    spi.format( 8,0 );
    uint32_t frequencyToSet = 8000000;
    #if( defined ( TARGET_NUCLEO_L152RE ) ||  defined ( TARGET_LPC11U6X ) )
        spi.frequency( frequencyToSet );
    #elif( defined ( TARGET_KL25Z ) ) //busclock frequency is halved -> double the spi frequency to compensate
        spi.frequency( frequencyToSet * 2 );
    #else
        #warning "Check the board's SPI frequency"
    #endif
    wait(0.1);
}

void SX1276MB1xAS::IoIrqInit( DioIrqHandler *irqHandlers )
{
    #if( defined ( TARGET_NUCLEO_L152RE ) ||  defined ( TARGET_LPC11U6X ) )
        dio0.mode(PullDown);
        dio1.mode(PullDown);
        dio2.mode(PullDown);
        dio3.mode(PullDown);
        dio4.mode(PullDown);
    #endif
    dio0.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[0] ) );
    dio1.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[1] ) );
    dio2.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[2] ) );
    dio3.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[3] ) );
    dio4.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[4] ) );
}

void SX1276MB1xAS::IoDeInit( void )
{
    //nothing
}

uint8_t SX1276MB1xAS::GetPaSelect( uint32_t channel )
{
    if( channel > RF_MID_BAND_THRESH )
    {
        if( boardConnected == SX1276MB1LAS )
        {
            return RF_PACONFIG_PASELECT_PABOOST;
        }
        else
        {
            return RF_PACONFIG_PASELECT_RFO;
        }
    }
    else
    {
        return RF_PACONFIG_PASELECT_RFO;
    }
}

void SX1276MB1xAS::SetAntSwLowPower( bool status )
{
    if( isRadioActive != status )
    {
        isRadioActive = status;

        if( status == false )
        {
            AntSwInit( );
        }
        else
        {
            AntSwDeInit( );
        }
    }
}

void SX1276MB1xAS::AntSwInit( void )
{
    antSwitch = 0;
}

void SX1276MB1xAS::AntSwDeInit( void )
{
    antSwitch = 0;
}

void SX1276MB1xAS::SetAntSw( uint8_t rxTx )
{
    if( this->rxTx == rxTx )
    {
        //no need to go further
        return;
    }

    this->rxTx = rxTx;

    if( rxTx != 0 )
    {
        antSwitch = 1;
    }
    else
    {
        antSwitch = 0;
    }
}

bool SX1276MB1xAS::CheckRfFrequency( uint32_t frequency )
{
    //TODO: Implement check, currently all frequencies are supported
    return true;
}

void SX1276MB1xAS::Reset( void )
{
    reset.output();
    reset = 0;
    wait_ms( 1 );
    reset.input();
    wait_ms( 6 );
}

void SX1276MB1xAS::Write( uint8_t addr, uint8_t data )
{
    Write( addr, &data, 1 );
}

uint8_t SX1276MB1xAS::Read( uint8_t addr )
{
    uint8_t data;
    Read( addr, &data, 1 );
    return data;
}

void SX1276MB1xAS::Write( uint8_t addr, uint8_t *buffer, uint8_t size )
{
    uint8_t i;

    nss = 0;
    spi.write( addr | 0x80 );
    for( i = 0; i < size; i++ )
    {
        spi.write( buffer[i] );
    }
    nss = 1;
}

void SX1276MB1xAS::Read( uint8_t addr, uint8_t *buffer, uint8_t size )
{
    uint8_t i;

    nss = 0;
    spi.write( addr & 0x7F );
    for( i = 0; i < size; i++ )
    {
        buffer[i] = spi.write( 0 );
    }
    nss = 1;
}

void SX1276MB1xAS::WriteFifo( uint8_t *buffer, uint8_t size )
{
    Write( 0, buffer, size );
}

void SX1276MB1xAS::ReadFifo( uint8_t *buffer, uint8_t size )
{
    Read( 0, buffer, size );
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include <math.h>
#include <stdlib.h>

#include "util.h"

#ifdef _MSC_VER
    #include <locale.h>
#else
    #include <sstream>
#endif

double atof_dot(const char *str)
{
#ifdef _MSC_VER
    return _atof_l(str, _create_locale(LC_NUMERIC, "C"));
#else
    double result;
    std::istringstream s(str);
    std::locale l("C");
    s.imbue(l);
    s >> result;
    return result;
#endif
}
<commit_msg>Fix memory leak in float literal parsing Issue=93<commit_after>//
// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include <math.h>
#include <stdlib.h>

#include "util.h"

#ifdef _MSC_VER
    #include <locale.h>
#else
    #include <sstream>
#endif

double atof_dot(const char *str)
{
#ifdef _MSC_VER
    _locale_t l = _create_locale(LC_NUMERIC, "C");
    double result = _atof_l(str, l);
    _free_locale(l);
    return result;
#else
    double result;
    std::istringstream s(str);
    std::locale l("C");
    s.imbue(l);
    s >> result;
    return result;
#endif
}
<|endoftext|>


<commit_before>#ifndef VAST_CONCEPT_SUPPORT_DETAIL_VARIANT_HPP
#define VAST_CONCEPT_SUPPORT_DETAIL_VARIANT_HPP

#include "vast/detail/type_list.hpp"
#include "vast/variant.hpp"

namespace vast {
namespace detail {

template <typename... Ts>
struct lazy_type_list {
  using type = type_list<Ts...>;
};

template <typename T, typename U>
struct lazy_variant_concat {
  using type = tl_concat_t<
    tl_make_t<typename T::types>,
    tl_make_t<typename U::types>
  >;
};

template <typename T, typename U>
struct lazy_variant_push_back {
  using type = tl_push_back_t<
    tl_make_t<typename T::types>,
    U
  >;
};

template <typename T, typename U>
using variant_type_concat =
  tl_distinct_t<
    typename std::conditional_t<
      is_variant<T>{} && is_variant<U>{},
      lazy_variant_concat<T, U>,
      std::conditional_t<
        is_variant<T>{},
        lazy_variant_push_back<T, U>,
        std::conditional_t<
          is_variant<U>{},
          lazy_variant_push_back<U, T>,
          lazy_type_list<T, U>
        >
      >
    >::type
  >;

template <typename T, typename U>
using flattened_variant = make_variant_from<
  variant_type_concat<T, U>
>;

} // namespace detail
} // namespace vast

#endif

<commit_msg>Fix missing type instantiation<commit_after>#ifndef VAST_CONCEPT_SUPPORT_DETAIL_VARIANT_HPP
#define VAST_CONCEPT_SUPPORT_DETAIL_VARIANT_HPP

#include "vast/detail/type_list.hpp"
#include "vast/variant.hpp"

namespace vast {
namespace detail {

template <typename... Ts>
struct lazy_type_list {
  using type = type_list<Ts...>;
};

template <typename T, typename U>
struct lazy_variant_concat {
  using type = tl_concat_t<
    tl_make_t<typename T::types>,
    tl_make_t<typename U::types>
  >;
};

template <typename T, typename U>
struct lazy_variant_push_back {
  using type = tl_push_back_t<
    tl_make_t<typename T::types>,
    U
  >;
};

template <typename T, typename U>
using variant_type_concat =
  tl_distinct_t<
    typename std::conditional_t<
      is_variant<T>{} && is_variant<U>{},
      lazy_variant_concat<T, U>,
      std::conditional_t<
        is_variant<T>{},
        lazy_variant_push_back<T, U>,
        std::conditional_t<
          is_variant<U>{},
          lazy_variant_push_back<U, T>,
          lazy_type_list<T, U>
        >
      >
    >::type
  >;

template <typename T, typename U>
using flattened_variant = typename make_variant_from<
  variant_type_concat<T, U>
>::type;

} // namespace detail
} // namespace vast

#endif

<|endoftext|>


<commit_before><commit_msg>Removed silly comments in demangle<commit_after><|endoftext|>


<commit_before>#include "allocate.hpp"
#include "utility/up_get.hpp"

using std::vector;
using std::shared_ptr;
using std::make_shared;
using std::move;
using std::string;
using std::static_pointer_cast;
using backend::utility::make_vector;

namespace backend {

allocate::allocate(const copperhead::system_variant& target,
                   const string& entry_point) : m_target(target),
                                                m_entry_point(entry_point),
                                                m_in_entry(false),
                                                m_allocations()
        {}

allocate::result_type allocate::operator()(const procedure &n) {
    if (n.id().id()  == m_entry_point) {
        m_in_entry = true;
        vector<shared_ptr<const statement> > statements;
        for(auto i = n.stmts().begin();
            i != n.stmts().end();
            i++) {
            auto new_stmt = static_pointer_cast<const statement>(
                boost::apply_visitor(*this, *i));
            if (m_allocations.size() > 0) {
                for(auto j = m_allocations.begin();
                    j != m_allocations.end();
                    j++) {
                    statements.push_back(*j);
                }
                m_allocations.clear();
            }
            statements.push_back(new_stmt);
        }
        auto stmts = make_shared<const suite>(move(statements));
        auto args =
            static_pointer_cast<const tuple>(
                boost::apply_visitor(*this, n.args()));
        auto t = n.type().ptr();
        auto ct = n.ctype().ptr();
        auto id =
            static_pointer_cast<const name>(
                boost::apply_visitor(*this, n.id()));
        result_type allocated = make_shared<const procedure>(
            id, args, stmts, t, ct);

        m_in_entry = false;
        return allocated;
    } else {
        return this->rewriter::operator()(n);
    }
}

allocate::result_type allocate::operator()(const bind &n) {
    if (m_in_entry &&
        detail::isinstance<ctype::sequence_t>(
            n.lhs().ctype()) &&
        detail::isinstance<apply>(n.rhs())) {

        bool lhs_is_name = detail::isinstance<name>(n.lhs());
        assert(lhs_is_name);
        const name& pre_lhs = boost::get<const name&>(n.lhs());

        //Construct cuarray for result
        shared_ptr<const ctype::type_t> impl_seq_ct =
            pre_lhs.ctype().ptr();
        // const ctype::sequence_t& pre_lhs_ct =
        //     detail::up_get<const ctype::sequence_t&>(pre_lhs.ctype());
        // shared_ptr<const ctype::type_t> sub_lhs_ct =
        //     pre_lhs_ct.sub().ptr();
        // shared_ptr<const ctype::type_t> impl_seq_ct =
        //     make_shared<const ctype::polytype_t>(
        //         make_vector<shared_ptr<const ctype::type_t> >
        //         (make_shared<const ctype::monotype_t>(copperhead::to_string(m_target)))
        //         (sub_lhs_ct),
        //         make_shared<const ctype::monotype_t>("sequence"));

        shared_ptr<const ctype::tuple_t> tuple_impl_seq_ct =
            make_shared<const ctype::tuple_t>(
                make_vector<shared_ptr<const ctype::type_t> >(impl_seq_ct));
        shared_ptr<const ctype::type_t> result_ct =
            make_shared<const ctype::monotype_t>("sp_cuarray");
        shared_ptr<const type_t> result_t =
            pre_lhs.type().ptr();
        shared_ptr<const name> result_name = make_shared<const name>(
            detail::wrap_array_id(pre_lhs.id()),
            result_t,
            result_ct);

        shared_ptr<const expression> new_rhs =
            static_pointer_cast<const expression>(
                boost::apply_visitor(*this, n.rhs()));

        shared_ptr<const bind> allocator = make_shared<const bind>(
            result_name, new_rhs);
        m_allocations.push_back(allocator);

        shared_ptr<const name> new_lhs = static_pointer_cast<const name>(
            boost::apply_visitor(*this, n.lhs()));
        shared_ptr<const templated_name> getter_name =
            make_shared<const templated_name>(
                detail::make_sequence(),
                tuple_impl_seq_ct);
        shared_ptr<const tuple> getter_args =
            make_shared<const tuple>(
                make_vector<shared_ptr<const expression> >(result_name)
                (make_shared<const apply>(
                    make_shared<const name>(copperhead::to_string(m_target)),
                    make_shared<const tuple>(make_vector<shared_ptr<const expression> >())))
                (make_shared<const literal>("true")));
        shared_ptr<const apply> getter_call =
            make_shared<const apply>(getter_name, getter_args);
        shared_ptr<const bind> retriever =
            make_shared<const bind>(new_lhs, getter_call);
        return retriever;
    } else {
        return this->rewriter::operator()(n);
    }
}

}
<commit_msg>Remove unneeded code.<commit_after>#include "allocate.hpp"
#include "utility/up_get.hpp"

using std::vector;
using std::shared_ptr;
using std::make_shared;
using std::move;
using std::string;
using std::static_pointer_cast;
using backend::utility::make_vector;

namespace backend {

allocate::allocate(const copperhead::system_variant& target,
                   const string& entry_point) : m_target(target),
                                                m_entry_point(entry_point),
                                                m_in_entry(false),
                                                m_allocations()
        {}

allocate::result_type allocate::operator()(const procedure &n) {
    if (n.id().id()  == m_entry_point) {
        m_in_entry = true;
        vector<shared_ptr<const statement> > statements;
        for(auto i = n.stmts().begin();
            i != n.stmts().end();
            i++) {
            auto new_stmt = static_pointer_cast<const statement>(
                boost::apply_visitor(*this, *i));
            if (m_allocations.size() > 0) {
                for(auto j = m_allocations.begin();
                    j != m_allocations.end();
                    j++) {
                    statements.push_back(*j);
                }
                m_allocations.clear();
            }
            statements.push_back(new_stmt);
        }
        auto stmts = make_shared<const suite>(move(statements));
        auto args =
            static_pointer_cast<const tuple>(
                boost::apply_visitor(*this, n.args()));
        auto t = n.type().ptr();
        auto ct = n.ctype().ptr();
        auto id =
            static_pointer_cast<const name>(
                boost::apply_visitor(*this, n.id()));
        result_type allocated = make_shared<const procedure>(
            id, args, stmts, t, ct);

        m_in_entry = false;
        return allocated;
    } else {
        return this->rewriter::operator()(n);
    }
}

allocate::result_type allocate::operator()(const bind &n) {
    if (m_in_entry &&
        detail::isinstance<ctype::sequence_t>(
            n.lhs().ctype()) &&
        detail::isinstance<apply>(n.rhs())) {

        bool lhs_is_name = detail::isinstance<name>(n.lhs());
        assert(lhs_is_name);
        const name& pre_lhs = boost::get<const name&>(n.lhs());

        //Construct cuarray for result
        shared_ptr<const ctype::type_t> impl_seq_ct =
            pre_lhs.ctype().ptr();

        shared_ptr<const ctype::tuple_t> tuple_impl_seq_ct =
            make_shared<const ctype::tuple_t>(
                make_vector<shared_ptr<const ctype::type_t> >(impl_seq_ct));
        shared_ptr<const ctype::type_t> result_ct =
            make_shared<const ctype::monotype_t>("sp_cuarray");
        shared_ptr<const type_t> result_t =
            pre_lhs.type().ptr();
        shared_ptr<const name> result_name = make_shared<const name>(
            detail::wrap_array_id(pre_lhs.id()),
            result_t,
            result_ct);

        shared_ptr<const expression> new_rhs =
            static_pointer_cast<const expression>(
                boost::apply_visitor(*this, n.rhs()));

        shared_ptr<const bind> allocator = make_shared<const bind>(
            result_name, new_rhs);
        m_allocations.push_back(allocator);

        shared_ptr<const name> new_lhs = static_pointer_cast<const name>(
            boost::apply_visitor(*this, n.lhs()));
        shared_ptr<const templated_name> getter_name =
            make_shared<const templated_name>(
                detail::make_sequence(),
                tuple_impl_seq_ct);
        shared_ptr<const tuple> getter_args =
            make_shared<const tuple>(
                make_vector<shared_ptr<const expression> >(result_name)
                (make_shared<const apply>(
                    make_shared<const name>(copperhead::to_string(m_target)),
                    make_shared<const tuple>(make_vector<shared_ptr<const expression> >())))
                (make_shared<const literal>("true")));
        shared_ptr<const apply> getter_call =
            make_shared<const apply>(getter_name, getter_args);
        shared_ptr<const bind> retriever =
            make_shared<const bind>(new_lhs, getter_call);
        return retriever;
    } else {
        return this->rewriter::operator()(n);
    }
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2012, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "amx/amx.h"

namespace amxutils {

const char *GetNativeName(AMX *amx, cell index) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	AMX_FUNCSTUBNT *natives = reinterpret_cast<AMX_FUNCSTUBNT*>(hdr->natives + amx->base);
	if (index >= 0 && index < ((hdr->libraries - hdr->natives) / hdr->defsize)) {
		return reinterpret_cast<char*>(natives[index].nameofs + amx->base);
	}
	return 0;
}

AMX_NATIVE GetNativeAddress(AMX *amx, cell index) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	AMX_FUNCSTUBNT *natives = reinterpret_cast<AMX_FUNCSTUBNT*>(hdr->natives + amx->base);
	if (index >= 0 && index < ((hdr->libraries - hdr->natives) / hdr->defsize)) {
		return reinterpret_cast<AMX_NATIVE>(natives[index].address);
	}
	return 0;
}

ucell GetPublicAddress(AMX *amx, cell index) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	AMX_FUNCSTUBNT *publics = reinterpret_cast<AMX_FUNCSTUBNT*>(hdr->publics + amx->base);
	if (index >=0 && index < ((hdr->natives - hdr->publics) / hdr->defsize)) {
		return publics[index].address;
	} else if (index == AMX_EXEC_MAIN) {
		return hdr->cip;
	}
	return 0;
}

const char *GetPublicName(AMX *amx, cell index) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	AMX_FUNCSTUBNT *publics = reinterpret_cast<AMX_FUNCSTUBNT*>(hdr->publics + amx->base);
	if (index >=0 && index < ((hdr->natives - hdr->publics) / hdr->defsize)) {
		return reinterpret_cast<char*>(amx->base + publics[index].nameofs);
	} else if (index == AMX_EXEC_MAIN) {
		return "main";
	}
	return 0;
}

unsigned char *GetDataPtr(AMX *amx) {
	unsigned char *data = amx->data;
	if (data == 0) {
		AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
		data = amx->base + hdr->dat;
	}
	return data;
}

unsigned char *GetCodePtr(AMX *amx) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	unsigned char *code = amx->base + hdr->cod;
	return code;
}

void PushStack(AMX *amx, cell value) {
	amx->stk -= sizeof(cell);
	*reinterpret_cast<cell*>(GetDataPtr(amx) + amx->stk) = value;
}

cell PopStack(AMX *amx) {
	cell value = *reinterpret_cast<cell*>(GetDataPtr(amx) + amx->stk);
	amx->stk += sizeof(cell);
	return value;
}

void PopStack(AMX *amx, int ncells) {
	amx->stk += sizeof(cell) * ncells;
}

} // namespace amxutils<commit_msg>amxutils: Add #include <stddef.h> for size_t<commit_after>// Copyright (c) 2011-2012, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <stddef.h> // for size_t in amx.h

#include "amx/amx.h"

namespace amxutils {

const char *GetNativeName(AMX *amx, cell index) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	AMX_FUNCSTUBNT *natives = reinterpret_cast<AMX_FUNCSTUBNT*>(hdr->natives + amx->base);
	if (index >= 0 && index < ((hdr->libraries - hdr->natives) / hdr->defsize)) {
		return reinterpret_cast<char*>(natives[index].nameofs + amx->base);
	}
	return 0;
}

AMX_NATIVE GetNativeAddress(AMX *amx, cell index) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	AMX_FUNCSTUBNT *natives = reinterpret_cast<AMX_FUNCSTUBNT*>(hdr->natives + amx->base);
	if (index >= 0 && index < ((hdr->libraries - hdr->natives) / hdr->defsize)) {
		return reinterpret_cast<AMX_NATIVE>(natives[index].address);
	}
	return 0;
}

ucell GetPublicAddress(AMX *amx, cell index) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	AMX_FUNCSTUBNT *publics = reinterpret_cast<AMX_FUNCSTUBNT*>(hdr->publics + amx->base);
	if (index >=0 && index < ((hdr->natives - hdr->publics) / hdr->defsize)) {
		return publics[index].address;
	} else if (index == AMX_EXEC_MAIN) {
		return hdr->cip;
	}
	return 0;
}

const char *GetPublicName(AMX *amx, cell index) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	AMX_FUNCSTUBNT *publics = reinterpret_cast<AMX_FUNCSTUBNT*>(hdr->publics + amx->base);
	if (index >=0 && index < ((hdr->natives - hdr->publics) / hdr->defsize)) {
		return reinterpret_cast<char*>(amx->base + publics[index].nameofs);
	} else if (index == AMX_EXEC_MAIN) {
		return "main";
	}
	return 0;
}

unsigned char *GetDataPtr(AMX *amx) {
	unsigned char *data = amx->data;
	if (data == 0) {
		AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
		data = amx->base + hdr->dat;
	}
	return data;
}

unsigned char *GetCodePtr(AMX *amx) {
	AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
	unsigned char *code = amx->base + hdr->cod;
	return code;
}

void PushStack(AMX *amx, cell value) {
	amx->stk -= sizeof(cell);
	*reinterpret_cast<cell*>(GetDataPtr(amx) + amx->stk) = value;
}

cell PopStack(AMX *amx) {
	cell value = *reinterpret_cast<cell*>(GetDataPtr(amx) + amx->stk);
	amx->stk += sizeof(cell);
	return value;
}

void PopStack(AMX *amx, int ncells) {
	amx->stk += sizeof(cell) * ncells;
}

} // namespace amxutils
<|endoftext|>


<commit_before><commit_msg>#81719# 'Replace' fixed in Thesaurus dialog<commit_after><|endoftext|>


<commit_before>#include "fileinfo.h"
#include "fileinfo_p.h"
#include <gio/gio.h>

namespace Fm {

const char defaultGFileInfoQueryAttribs[] = "standard::*,"
                                            "unix::*,"
                                            "time::*,"
                                            "access::*,"
                                            "id::filesystem,"
                                            "metadata::emblems";

FileInfo::FileInfo() {
    // FIXME: initialize numeric data members
}

FileInfo::FileInfo(const GFileInfoPtr& inf, const FilePath& parentDirPath) {
    setFromGFileInfo(inf, parentDirPath);
}

FileInfo::~FileInfo() {
}

void FileInfo::setFromGFileInfo(const GObjectPtr<GFileInfo>& inf, const FilePath& parentDirPath) {
    dirPath_ = parentDirPath;
    const char* tmp, *uri;
    GIcon* gicon;
    GFileType type;

    if (const char * name = g_file_info_get_name(inf.get()))
        name_ = name;

    dispName_ = g_file_info_get_display_name(inf.get());

    size_ = g_file_info_get_size(inf.get());

    tmp = g_file_info_get_content_type(inf.get());
    if(!tmp) {
        tmp = "application/octet-stream";
    }
    mimeType_ = MimeType::fromName(tmp);

    mode_ = g_file_info_get_attribute_uint32(inf.get(), G_FILE_ATTRIBUTE_UNIX_MODE);

    uid_ = gid_ = -1;
    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_UNIX_UID)) {
        uid_ = g_file_info_get_attribute_uint32(inf.get(), G_FILE_ATTRIBUTE_UNIX_UID);
    }
    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_UNIX_GID)) {
        gid_ = g_file_info_get_attribute_uint32(inf.get(), G_FILE_ATTRIBUTE_UNIX_GID);
    }

    type = g_file_info_get_file_type(inf.get());
    if(0 == mode_) { /* if UNIX file mode is not available, compose a fake one. */
        switch(type) {
        case G_FILE_TYPE_REGULAR:
            mode_ |= S_IFREG;
            break;
        case G_FILE_TYPE_DIRECTORY:
            mode_ |= S_IFDIR;
            break;
        case G_FILE_TYPE_SYMBOLIC_LINK:
            mode_ |= S_IFLNK;
            break;
        case G_FILE_TYPE_SHORTCUT:
            break;
        case G_FILE_TYPE_MOUNTABLE:
            break;
        case G_FILE_TYPE_SPECIAL:
            if(mode_) {
                break;
            }
            /* if it's a special file but it doesn't have UNIX mode, compose a fake one. */
            if(strcmp(tmp, "inode/chardevice") == 0) {
                mode_ |= S_IFCHR;
            }
            else if(strcmp(tmp, "inode/blockdevice") == 0) {
                mode_ |= S_IFBLK;
            }
            else if(strcmp(tmp, "inode/fifo") == 0) {
                mode_ |= S_IFIFO;
            }
#ifdef S_IFSOCK
            else if(strcmp(tmp, "inode/socket") == 0) {
                mode_ |= S_IFSOCK;
            }
#endif
            break;
        case G_FILE_TYPE_UNKNOWN:
            ;
        }
    }

    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_READ)) {
        isAccessible_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
    }
    else
        /* assume it's accessible */
    {
        isAccessible_ = true;
    }

    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) {
        isWritable_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
    }
    else
        /* assume it's writable */
    {
        isWritable_ = true;
    }

    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE)) {
        isDeletable_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE);
    }
    else
        /* assume it's deletable */
    {
        isDeletable_ = true;
    }

    /* special handling for symlinks */
    if(g_file_info_get_is_symlink(inf.get())) {
        mode_ &= ~S_IFMT; /* reset type */
        mode_ |= S_IFLNK; /* set type to symlink */
        goto _file_is_symlink;
    }

    isShortcut_ = false;

    switch(type) {
    case G_FILE_TYPE_SHORTCUT:
        isShortcut_ = true;
    /* Falls through. */
    case G_FILE_TYPE_MOUNTABLE:
        uri = g_file_info_get_attribute_string(inf.get(), G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
        if(uri) {
            if(g_str_has_prefix(uri, "file:///")) {
                auto filename = CStrPtr{g_filename_from_uri(uri, nullptr, nullptr)};
                target_ = filename.get();
            }
            else {
                target_ = uri;
            }
            if(!mimeType_) {
                mimeType_ = MimeType::guessFromFileName(target_.c_str());
            }
        }

        /* if the mime-type is not determined or is unknown */
        if(G_UNLIKELY(!mimeType_ || mimeType_->isUnknownType())) {
            /* FIXME: is this appropriate? */
            if(type == G_FILE_TYPE_SHORTCUT) {
                mimeType_ = MimeType::inodeShortcut();
            }
            else {
                mimeType_ = MimeType::inodeMountPoint();
            }
        }
        break;
    case G_FILE_TYPE_DIRECTORY:
        if(!mimeType_) {
            mimeType_ = MimeType::inodeDirectory();
        }
        isReadOnly_ = false; /* default is R/W */
        if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_FILESYSTEM_READONLY)) {
            isReadOnly_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_FILESYSTEM_READONLY);
        }
        /* directories should be writable to be deleted by user */
        if(isReadOnly_ || !isWritable_) {
            isDeletable_ = false;
        }
        break;
    case G_FILE_TYPE_SYMBOLIC_LINK:
_file_is_symlink:
        uri = g_file_info_get_symlink_target(inf.get());
        if(uri) {
            if(g_str_has_prefix(uri, "file:///")) {
                auto filename = CStrPtr{g_filename_from_uri(uri, nullptr, nullptr)};
                target_ = filename.get();
            }
            else {
                target_ = uri;
            }
            if(!mimeType_) {
                mimeType_ = MimeType::guessFromFileName(target_.c_str());
            }
        }
    /* Falls through. */
    /* continue with absent mime type */
    default: /* G_FILE_TYPE_UNKNOWN G_FILE_TYPE_REGULAR G_FILE_TYPE_SPECIAL */
        if(G_UNLIKELY(!mimeType_)) {
            if(!mimeType_) {
                mimeType_ = MimeType::guessFromFileName(name_.c_str());
            }
        }
    }

    /* if there is a custom folder icon, use it */
    if(isNative() && type == G_FILE_TYPE_DIRECTORY) {
        auto local_path = path().localPath();
        auto dot_dir = CStrPtr{g_build_filename(local_path.get(), ".directory", nullptr)};
        if(g_file_test(dot_dir.get(), G_FILE_TEST_IS_REGULAR)) {
            GKeyFile* kf = g_key_file_new();
            if(g_key_file_load_from_file(kf, dot_dir.get(), G_KEY_FILE_NONE, nullptr)) {
                CStrPtr icon_name{g_key_file_get_string(kf, "Desktop Entry", "Icon", nullptr)};
                if(icon_name) {
                    auto dot_icon = IconInfo::fromName(icon_name.get());
                    if(dot_icon && dot_icon->isValid()) {
                        icon_ = dot_icon;
                    }
                }
            }
            g_key_file_free(kf);
        }
     }

    if(!icon_) {
        /* try file-specific icon first */
        gicon = g_file_info_get_icon(inf.get());
        if(gicon) {
            icon_ = IconInfo::fromGIcon(gicon);
        }
    }

#if 0
    /* set "locked" icon on unaccesible folder */
    else if(!accessible && type == G_FILE_TYPE_DIRECTORY) {
        icon = g_object_ref(icon_locked_folder);
    }
    else {
        icon = g_object_ref(fm_mime_type_get_icon(mime_type));
    }
#endif

    /* if the file has emblems, add them to the icon */
    auto emblem_names = g_file_info_get_attribute_stringv(inf.get(), "metadata::emblems");
    if(emblem_names) {
        auto n_emblems = g_strv_length(emblem_names);
        for(int i = n_emblems - 1; i >= 0; --i) {
            emblems_.emplace_front(Fm::IconInfo::fromName(emblem_names[i]));
        }
    }

    tmp = g_file_info_get_attribute_string(inf.get(), G_FILE_ATTRIBUTE_ID_FILESYSTEM);
    filesystemId_ = g_intern_string(tmp);

    mtime_ = g_file_info_get_attribute_uint64(inf.get(), G_FILE_ATTRIBUTE_TIME_MODIFIED);
    atime_ = g_file_info_get_attribute_uint64(inf.get(), G_FILE_ATTRIBUTE_TIME_ACCESS);
    ctime_ = g_file_info_get_attribute_uint64(inf.get(), G_FILE_ATTRIBUTE_TIME_CHANGED);
    isHidden_ = g_file_info_get_is_hidden(inf.get());
    // g_file_info_get_is_backup() does not cover ".bak" and ".old".
    // NOTE: Here, dispName_ is not modified for desktop entries yet.
    isBackup_ = g_file_info_get_is_backup(inf.get())
                || dispName_.endsWith(QLatin1String(".bak"))
                || dispName_.endsWith(QLatin1String(".old"));
    isNameChangeable_ = true; /* GVFS tends to ignore this attribute */
    isIconChangeable_ = isHiddenChangeable_ = false;
    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME)) {
        isNameChangeable_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME);
    }

    // special handling for desktop entry files (show the name and icon defined in the desktop entry instead)
    if(isNative() && G_UNLIKELY(isDesktopEntry())) {
        auto local_path = path().localPath();
        GKeyFile* kf = g_key_file_new();
        if(g_key_file_load_from_file(kf, local_path.get(), G_KEY_FILE_NONE, nullptr)) {
            /* check if type is correct and supported */
            CStrPtr type{g_key_file_get_string(kf, "Desktop Entry", "Type", nullptr)};
            if(type) {
                // Type == "Link"
                if(strcmp(type.get(), G_KEY_FILE_DESKTOP_TYPE_LINK) == 0) {
                    CStrPtr uri{g_key_file_get_string(kf, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_URL, nullptr)};
                    if(uri) {
                        isShortcut_ = true;
                        target_ = uri.get();
                    }
                }
            }
            CStrPtr icon_name{g_key_file_get_string(kf, "Desktop Entry", "Icon", nullptr)};
            if(icon_name) {
                icon_ = IconInfo::fromName(icon_name.get());
            }
            /* Use title of the desktop entry for display */
            CStrPtr displayName{g_key_file_get_locale_string(kf, "Desktop Entry", "Name", nullptr, nullptr)};
            if(displayName) {
                dispName_ = displayName.get();
            }
            /* handle 'Hidden' key to set hidden attribute */
            if(!isHidden_) {
                isHidden_ = g_key_file_get_boolean(kf, "Desktop Entry", "Hidden", nullptr);
            }
        }
        g_key_file_free(kf);
    }

    if(!icon_ && mimeType_)
        icon_ = mimeType_->icon();

#if 0
    GFile* _gf = nullptr;
    GFileAttributeInfoList* list;
    auto list = g_file_query_settable_attributes(gf, nullptr, nullptr);
    if(G_LIKELY(list)) {
        if(g_file_attribute_info_list_lookup(list, G_FILE_ATTRIBUTE_STANDARD_ICON)) {
            icon_is_changeable = true;
        }
        if(g_file_attribute_info_list_lookup(list, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN)) {
            hidden_is_changeable = true;
        }
        g_file_attribute_info_list_unref(list);
    }
    if(G_UNLIKELY(_gf)) {
        g_object_unref(_gf);
    }
#endif
}

void FileInfo::bindCutFiles(const std::shared_ptr<const HashSet>& cutFilesHashSet) {
    cutFilesHashSet_ = cutFilesHashSet;
}

bool FileInfo::canThumbnail() const {
    /* We cannot use S_ISREG here as this exclude all symlinks */
    if(size_ == 0 ||  /* don't generate thumbnails for empty files */
            !(mode_ & S_IFREG) ||
            isDesktopEntry() ||
            isUnknownType()) {
        return false;
    }
    return true;
}

/* full path of the file is required by this function */
bool FileInfo::isExecutableType() const {
    if(isDesktopEntry()) {
        /* treat desktop entries as executables if
         they are native and have read permission */
        if(isNative() && (mode_ & (S_IRUSR|S_IRGRP|S_IROTH))) {
            if(isShortcut() && !target_.empty()) {
                /* handle shortcuts from desktop to menu entries:
                   first check for entries in /usr/share/applications and such
                   which may be considered as a safe desktop entry path
                   then check if that is a shortcut to a native file
                   otherwise it is a link to a file under menu:// */
                if (!g_str_has_prefix(target_.c_str(), "/usr/share/")) {
                    auto target = FilePath::fromPathStr(target_.c_str());
                    bool is_native = target.isNative();
                    if (is_native) {
                        return true;
                    }
                }
            }
            else {
                return true;
            }
        }
        return false;
    }
    else if(isText()) { /* g_content_type_can_be_executable reports text files as executables too */
        /* We don't execute remote files nor files in trash */
        if(isNative() && (mode_ & (S_IXOTH | S_IXGRP | S_IXUSR))) {
            /* it has executable bits so lets check shell-bang */
            auto pathStr = path().toString();
            int fd = open(pathStr.get(), O_RDONLY);
            if(fd >= 0) {
                char buf[2];
                ssize_t rdlen = read(fd, &buf, 2);
                close(fd);
                if(rdlen == 2 && buf[0] == '#' && buf[1] == '!') {
                    return true;
                }
            }
        }
        return false;
    }
    return mimeType_->canBeExecutable();
}

bool FileInfoList::isSameType() const {
    if(!empty()) {
        auto& item = front();
        for(auto it = cbegin() + 1; it != cend(); ++it) {
            auto& item2 = *it;
            if(item->mimeType() != item2->mimeType()) {
                return false;
            }
        }
    }
    return true;
}

bool FileInfoList::isSameFilesystem() const {
    if(!empty()) {
        auto& item = front();
        for(auto it = cbegin() + 1; it != cend(); ++it) {
            auto& item2 = *it;
            if(item->filesystemId() != item2->filesystemId()) {
                return false;
            }
        }
    }
    return true;
}

} // namespace Fm
<commit_msg>Fixed shortcut detection<commit_after>#include "fileinfo.h"
#include "fileinfo_p.h"
#include <gio/gio.h>

namespace Fm {

const char defaultGFileInfoQueryAttribs[] = "standard::*,"
                                            "unix::*,"
                                            "time::*,"
                                            "access::*,"
                                            "id::filesystem,"
                                            "metadata::emblems";

FileInfo::FileInfo() {
    // FIXME: initialize numeric data members
}

FileInfo::FileInfo(const GFileInfoPtr& inf, const FilePath& parentDirPath) {
    setFromGFileInfo(inf, parentDirPath);
}

FileInfo::~FileInfo() {
}

void FileInfo::setFromGFileInfo(const GObjectPtr<GFileInfo>& inf, const FilePath& parentDirPath) {
    dirPath_ = parentDirPath;
    const char* tmp, *uri;
    GIcon* gicon;
    GFileType type;

    if (const char * name = g_file_info_get_name(inf.get()))
        name_ = name;

    dispName_ = g_file_info_get_display_name(inf.get());

    size_ = g_file_info_get_size(inf.get());

    tmp = g_file_info_get_content_type(inf.get());
    if(!tmp) {
        tmp = "application/octet-stream";
    }
    mimeType_ = MimeType::fromName(tmp);

    mode_ = g_file_info_get_attribute_uint32(inf.get(), G_FILE_ATTRIBUTE_UNIX_MODE);

    uid_ = gid_ = -1;
    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_UNIX_UID)) {
        uid_ = g_file_info_get_attribute_uint32(inf.get(), G_FILE_ATTRIBUTE_UNIX_UID);
    }
    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_UNIX_GID)) {
        gid_ = g_file_info_get_attribute_uint32(inf.get(), G_FILE_ATTRIBUTE_UNIX_GID);
    }

    type = g_file_info_get_file_type(inf.get());
    if(0 == mode_) { /* if UNIX file mode is not available, compose a fake one. */
        switch(type) {
        case G_FILE_TYPE_REGULAR:
            mode_ |= S_IFREG;
            break;
        case G_FILE_TYPE_DIRECTORY:
            mode_ |= S_IFDIR;
            break;
        case G_FILE_TYPE_SYMBOLIC_LINK:
            mode_ |= S_IFLNK;
            break;
        case G_FILE_TYPE_SHORTCUT:
            break;
        case G_FILE_TYPE_MOUNTABLE:
            break;
        case G_FILE_TYPE_SPECIAL:
            if(mode_) {
                break;
            }
            /* if it's a special file but it doesn't have UNIX mode, compose a fake one. */
            if(strcmp(tmp, "inode/chardevice") == 0) {
                mode_ |= S_IFCHR;
            }
            else if(strcmp(tmp, "inode/blockdevice") == 0) {
                mode_ |= S_IFBLK;
            }
            else if(strcmp(tmp, "inode/fifo") == 0) {
                mode_ |= S_IFIFO;
            }
#ifdef S_IFSOCK
            else if(strcmp(tmp, "inode/socket") == 0) {
                mode_ |= S_IFSOCK;
            }
#endif
            break;
        case G_FILE_TYPE_UNKNOWN:
            ;
        }
    }

    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_READ)) {
        isAccessible_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
    }
    else
        /* assume it's accessible */
    {
        isAccessible_ = true;
    }

    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) {
        isWritable_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
    }
    else
        /* assume it's writable */
    {
        isWritable_ = true;
    }

    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE)) {
        isDeletable_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE);
    }
    else
        /* assume it's deletable */
    {
        isDeletable_ = true;
    }

    isShortcut_ = false;

    /* special handling for symlinks */
    if(g_file_info_get_is_symlink(inf.get())) {
        mode_ &= ~S_IFMT; /* reset type */
        mode_ |= S_IFLNK; /* set type to symlink */
        goto _file_is_symlink;
    }

    switch(type) {
    case G_FILE_TYPE_SHORTCUT:
        isShortcut_ = true;
    /* Falls through. */
    case G_FILE_TYPE_MOUNTABLE:
        uri = g_file_info_get_attribute_string(inf.get(), G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
        if(uri) {
            if(g_str_has_prefix(uri, "file:///")) {
                auto filename = CStrPtr{g_filename_from_uri(uri, nullptr, nullptr)};
                target_ = filename.get();
            }
            else {
                target_ = uri;
            }
            if(!mimeType_) {
                mimeType_ = MimeType::guessFromFileName(target_.c_str());
            }
        }

        /* if the mime-type is not determined or is unknown */
        if(G_UNLIKELY(!mimeType_ || mimeType_->isUnknownType())) {
            /* FIXME: is this appropriate? */
            if(type == G_FILE_TYPE_SHORTCUT) {
                mimeType_ = MimeType::inodeShortcut();
            }
            else {
                mimeType_ = MimeType::inodeMountPoint();
            }
        }
        break;
    case G_FILE_TYPE_DIRECTORY:
        if(!mimeType_) {
            mimeType_ = MimeType::inodeDirectory();
        }
        isReadOnly_ = false; /* default is R/W */
        if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_FILESYSTEM_READONLY)) {
            isReadOnly_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_FILESYSTEM_READONLY);
        }
        /* directories should be writable to be deleted by user */
        if(isReadOnly_ || !isWritable_) {
            isDeletable_ = false;
        }
        break;
    case G_FILE_TYPE_SYMBOLIC_LINK:
_file_is_symlink:
        uri = g_file_info_get_symlink_target(inf.get());
        if(uri) {
            if(g_str_has_prefix(uri, "file:///")) {
                auto filename = CStrPtr{g_filename_from_uri(uri, nullptr, nullptr)};
                target_ = filename.get();
            }
            else {
                target_ = uri;
            }
            if(!mimeType_) {
                mimeType_ = MimeType::guessFromFileName(target_.c_str());
            }
        }
    /* Falls through. */
    /* continue with absent mime type */
    default: /* G_FILE_TYPE_UNKNOWN G_FILE_TYPE_REGULAR G_FILE_TYPE_SPECIAL */
        if(G_UNLIKELY(!mimeType_)) {
            if(!mimeType_) {
                mimeType_ = MimeType::guessFromFileName(name_.c_str());
            }
        }
    }

    /* if there is a custom folder icon, use it */
    if(isNative() && type == G_FILE_TYPE_DIRECTORY) {
        auto local_path = path().localPath();
        auto dot_dir = CStrPtr{g_build_filename(local_path.get(), ".directory", nullptr)};
        if(g_file_test(dot_dir.get(), G_FILE_TEST_IS_REGULAR)) {
            GKeyFile* kf = g_key_file_new();
            if(g_key_file_load_from_file(kf, dot_dir.get(), G_KEY_FILE_NONE, nullptr)) {
                CStrPtr icon_name{g_key_file_get_string(kf, "Desktop Entry", "Icon", nullptr)};
                if(icon_name) {
                    auto dot_icon = IconInfo::fromName(icon_name.get());
                    if(dot_icon && dot_icon->isValid()) {
                        icon_ = dot_icon;
                    }
                }
            }
            g_key_file_free(kf);
        }
     }

    if(!icon_) {
        /* try file-specific icon first */
        gicon = g_file_info_get_icon(inf.get());
        if(gicon) {
            icon_ = IconInfo::fromGIcon(gicon);
        }
    }

#if 0
    /* set "locked" icon on unaccesible folder */
    else if(!accessible && type == G_FILE_TYPE_DIRECTORY) {
        icon = g_object_ref(icon_locked_folder);
    }
    else {
        icon = g_object_ref(fm_mime_type_get_icon(mime_type));
    }
#endif

    /* if the file has emblems, add them to the icon */
    auto emblem_names = g_file_info_get_attribute_stringv(inf.get(), "metadata::emblems");
    if(emblem_names) {
        auto n_emblems = g_strv_length(emblem_names);
        for(int i = n_emblems - 1; i >= 0; --i) {
            emblems_.emplace_front(Fm::IconInfo::fromName(emblem_names[i]));
        }
    }

    tmp = g_file_info_get_attribute_string(inf.get(), G_FILE_ATTRIBUTE_ID_FILESYSTEM);
    filesystemId_ = g_intern_string(tmp);

    mtime_ = g_file_info_get_attribute_uint64(inf.get(), G_FILE_ATTRIBUTE_TIME_MODIFIED);
    atime_ = g_file_info_get_attribute_uint64(inf.get(), G_FILE_ATTRIBUTE_TIME_ACCESS);
    ctime_ = g_file_info_get_attribute_uint64(inf.get(), G_FILE_ATTRIBUTE_TIME_CHANGED);
    isHidden_ = g_file_info_get_is_hidden(inf.get());
    // g_file_info_get_is_backup() does not cover ".bak" and ".old".
    // NOTE: Here, dispName_ is not modified for desktop entries yet.
    isBackup_ = g_file_info_get_is_backup(inf.get())
                || dispName_.endsWith(QLatin1String(".bak"))
                || dispName_.endsWith(QLatin1String(".old"));
    isNameChangeable_ = true; /* GVFS tends to ignore this attribute */
    isIconChangeable_ = isHiddenChangeable_ = false;
    if(g_file_info_has_attribute(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME)) {
        isNameChangeable_ = g_file_info_get_attribute_boolean(inf.get(), G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME);
    }

    // special handling for desktop entry files (show the name and icon defined in the desktop entry instead)
    if(isNative() && G_UNLIKELY(isDesktopEntry())) {
        auto local_path = path().localPath();
        GKeyFile* kf = g_key_file_new();
        if(g_key_file_load_from_file(kf, local_path.get(), G_KEY_FILE_NONE, nullptr)) {
            /* check if type is correct and supported */
            CStrPtr type{g_key_file_get_string(kf, "Desktop Entry", "Type", nullptr)};
            if(type) {
                // Type == "Link"
                if(strcmp(type.get(), G_KEY_FILE_DESKTOP_TYPE_LINK) == 0) {
                    CStrPtr uri{g_key_file_get_string(kf, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_URL, nullptr)};
                    if(uri) {
                        isShortcut_ = true;
                        target_ = uri.get();
                    }
                }
            }
            CStrPtr icon_name{g_key_file_get_string(kf, "Desktop Entry", "Icon", nullptr)};
            if(icon_name) {
                icon_ = IconInfo::fromName(icon_name.get());
            }
            /* Use title of the desktop entry for display */
            CStrPtr displayName{g_key_file_get_locale_string(kf, "Desktop Entry", "Name", nullptr, nullptr)};
            if(displayName) {
                dispName_ = displayName.get();
            }
            /* handle 'Hidden' key to set hidden attribute */
            if(!isHidden_) {
                isHidden_ = g_key_file_get_boolean(kf, "Desktop Entry", "Hidden", nullptr);
            }
        }
        g_key_file_free(kf);
    }

    if(!icon_ && mimeType_)
        icon_ = mimeType_->icon();

#if 0
    GFile* _gf = nullptr;
    GFileAttributeInfoList* list;
    auto list = g_file_query_settable_attributes(gf, nullptr, nullptr);
    if(G_LIKELY(list)) {
        if(g_file_attribute_info_list_lookup(list, G_FILE_ATTRIBUTE_STANDARD_ICON)) {
            icon_is_changeable = true;
        }
        if(g_file_attribute_info_list_lookup(list, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN)) {
            hidden_is_changeable = true;
        }
        g_file_attribute_info_list_unref(list);
    }
    if(G_UNLIKELY(_gf)) {
        g_object_unref(_gf);
    }
#endif
}

void FileInfo::bindCutFiles(const std::shared_ptr<const HashSet>& cutFilesHashSet) {
    cutFilesHashSet_ = cutFilesHashSet;
}

bool FileInfo::canThumbnail() const {
    /* We cannot use S_ISREG here as this exclude all symlinks */
    if(size_ == 0 ||  /* don't generate thumbnails for empty files */
            !(mode_ & S_IFREG) ||
            isDesktopEntry() ||
            isUnknownType()) {
        return false;
    }
    return true;
}

/* full path of the file is required by this function */
bool FileInfo::isExecutableType() const {
    if(isDesktopEntry()) {
        /* treat desktop entries as executables if
         they are native and have read permission */
        if(isNative() && (mode_ & (S_IRUSR|S_IRGRP|S_IROTH))) {
            if(isShortcut() && !target_.empty()) {
                /* handle shortcuts from desktop to menu entries:
                   first check for entries in /usr/share/applications and such
                   which may be considered as a safe desktop entry path
                   then check if that is a shortcut to a native file
                   otherwise it is a link to a file under menu:// */
                if (!g_str_has_prefix(target_.c_str(), "/usr/share/")) {
                    auto target = FilePath::fromPathStr(target_.c_str());
                    bool is_native = target.isNative();
                    if (is_native) {
                        return true;
                    }
                }
            }
            else {
                return true;
            }
        }
        return false;
    }
    else if(isText()) { /* g_content_type_can_be_executable reports text files as executables too */
        /* We don't execute remote files nor files in trash */
        if(isNative() && (mode_ & (S_IXOTH | S_IXGRP | S_IXUSR))) {
            /* it has executable bits so lets check shell-bang */
            auto pathStr = path().toString();
            int fd = open(pathStr.get(), O_RDONLY);
            if(fd >= 0) {
                char buf[2];
                ssize_t rdlen = read(fd, &buf, 2);
                close(fd);
                if(rdlen == 2 && buf[0] == '#' && buf[1] == '!') {
                    return true;
                }
            }
        }
        return false;
    }
    return mimeType_->canBeExecutable();
}

bool FileInfoList::isSameType() const {
    if(!empty()) {
        auto& item = front();
        for(auto it = cbegin() + 1; it != cend(); ++it) {
            auto& item2 = *it;
            if(item->mimeType() != item2->mimeType()) {
                return false;
            }
        }
    }
    return true;
}

bool FileInfoList::isSameFilesystem() const {
    if(!empty()) {
        auto& item = front();
        for(auto it = cbegin() + 1; it != cend(); ++it) {
            auto& item2 = *it;
            if(item->filesystemId() != item2->filesystemId()) {
                return false;
            }
        }
    }
    return true;
}

} // namespace Fm
<|endoftext|>


<commit_before>// -----------------------------------------------------------------------------
//
// Copyright (C) The BioDynaMo Project.
// All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//
// See the LICENSE file distributed with this work for details.
// See the NOTICE file distributed with this work for additional information
// regarding copyright ownership.
//
// -----------------------------------------------------------------------------

#include "core/scheduler.h"

#include <chrono>
#include <string>

#include "core/execution_context/in_place_exec_ctxt.h"
#include "core/gpu/gpu_helper.h"
#include "core/operation/bound_space_op.h"
#include "core/operation/diffusion_op.h"
#include "core/operation/displacement_op.h"
#include "core/operation/op_timer.h"
#include "core/param/param.h"
#include "core/resource_manager.h"
#include "core/simulation.h"
#include "core/simulation_backup.h"
#include "core/util/log.h"
#include "core/visualization/catalyst_adaptor.h"

namespace bdm {

Scheduler::Scheduler() {
  auto* param = Simulation::GetActive()->GetParam();
  backup_ = new SimulationBackup(param->backup_file_, param->restore_file_);
  if (backup_->RestoreEnabled()) {
    restore_point_ = backup_->GetSimulationStepsFromBackup();
  }
  visualization_ =
      new CatalystAdaptor(BDM_SRC_DIR "/visualization/simple_pipeline.py");
  bound_space_ = new BoundSpace();
  displacement_ = new DisplacementOp();
  diffusion_ = new DiffusionOp();

  // initialise operations_
  auto first_op =
      Operation("first", [](SimObject* so) { so->UpdateRunDisplacement(); });
  auto last_op = Operation(
      "last", [](SimObject* so) { so->ApplyRunDisplacementForAllNextTs(); });
  auto biology_module_op = Operation(
      "biology modules", [](SimObject* so) { so->RunBiologyModules(); });
  auto discretization_op = Operation(
      "discretization", [](SimObject* so) { so->RunDiscretization(); });

  auto displacement_op = Operation("displacement", *displacement_);

  operations_ = {first_op,          Operation("bound space", *bound_space_),
                 biology_module_op, displacement_op,
                 discretization_op, last_op};
  protected_operations_ = {first_op.name_, biology_module_op.name_,
                           discretization_op.name_, last_op.name_};
}

Scheduler::~Scheduler() {
  delete backup_;
  delete visualization_;
  delete bound_space_;
  delete displacement_;
  delete diffusion_;
  auto* param = Simulation::GetActive()->GetParam();
  if (param->statistics_) {
    std::cout << gStatistics << std::endl;
  }
}

void Scheduler::Simulate(uint64_t steps) {
  if (Restore(&steps)) {
    return;
  }

  Initialize();
  for (unsigned step = 0; step < steps; step++) {
    Execute(step == steps - 1);

    total_steps_++;
    Backup();
  }
}

uint64_t Scheduler::GetSimulatedSteps() const { return total_steps_; }

void Scheduler::AddOperation(const Operation& op) {
  auto it = operations_.end() - 2;
  operations_.insert(it, op);
}

void Scheduler::RemoveOperation(const std::string& name) {
  if (protected_operations_.find(name) != protected_operations_.end()) {
    Log::Warning("Scheduler::GetOperation",
                 "You tried to remove the protected operation ", name,
                 "! This request was ignored.");
    return;
  }
  for (auto it = operations_.begin(); it != operations_.end(); ++it) {
    if (name == it->name_) {
      operations_.erase(it);
      return;
    }
  }
}

Operation* Scheduler::GetOperation(const std::string& name) {
  if (protected_operations_.find(name) != protected_operations_.end()) {
    Log::Warning("Scheduler::GetOperation",
                 "You tried to get the protected operation ", name, "!");
    return nullptr;
  }
  for (uint64_t i = 0; i < operations_.size(); i++) {
    auto& op = operations_[i];
    if (name == op.name_) {
      return &op;
    }
  }
  return nullptr;
}

void Scheduler::Execute(bool last_iteration) {
  auto* sim = Simulation::GetActive();
  auto* rm = sim->GetResourceManager();
  auto* grid = sim->GetGrid();
  auto* param = sim->GetParam();

  Timing::Time("Set up exec context", [&]() {
    const auto& all_exec_ctxts = sim->GetAllExecCtxts();
    all_exec_ctxts[0]->SetupIterationAll(all_exec_ctxts);
  });

  Timing::Time("visualize", [&]() {
    visualization_->Visualize(total_steps_, last_iteration);
  });
  Timing::Time("neighbors", [&]() { grid->UpdateGrid(); });

  // update all sim objects: run all CPU operations
  const auto& scheduled_ops = GetScheduleOps();
  rm->ApplyOnAllElementsParallelDynamic(
      param->scheduling_batch_size_, [&](SimObject* so, SoHandle) {
        sim->GetExecutionContext()->Execute(so, scheduled_ops);
      });

  // update all sim objects: hardware accelerated operations
  if (param->run_mechanical_interactions_ && !displacement_->UseCpu()) {
    Timing::Time("displacement (GPU/FPGA)", *displacement_);
  }

  // finish updating sim objects
  Timing::Time("Tear down exec context", [&]() {
    const auto& all_exec_ctxts = sim->GetAllExecCtxts();
    all_exec_ctxts[0]->TearDownIterationAll(all_exec_ctxts);
  });

  // update all substances (DiffusionGrids)
  Timing::Time("diffusion", *diffusion_);
}

void Scheduler::Backup() {
  using std::chrono::seconds;
  using std::chrono::duration_cast;
  auto* param = Simulation::GetActive()->GetParam();
  if (backup_->BackupEnabled() &&
      duration_cast<seconds>(Clock::now() - last_backup_).count() >=
          param->backup_interval_) {
    last_backup_ = Clock::now();
    backup_->Backup(total_steps_);
  }
}

/// Restore the simulation if requested at the right time
/// @param steps number of simulation steps for a `Simulate` call
/// @return if `Simulate` should return early
bool Scheduler::Restore(uint64_t* steps) {
  if (backup_->RestoreEnabled() && restore_point_ > total_steps_ + *steps) {
    total_steps_ += *steps;
    // restore requested, but not last backup was not done during this call to
    // Simualte. Therefore, we skip it.
    return true;
  } else if (backup_->RestoreEnabled() && restore_point_ > total_steps_ &&
             restore_point_ < total_steps_ + *steps) {
    // Restore
    backup_->Restore();
    *steps = total_steps_ + *steps - restore_point_;
    total_steps_ = restore_point_;
  }
  return false;
}

// TODO(lukas, ahmad) After https://trello.com/c/0D6sHCK4 has been resolved
// think about a better solution, because some operations are executed twice
// if Simulate is called with one timestep.
void Scheduler::Initialize() {
  auto* sim = Simulation::GetActive();
  auto* grid = sim->GetGrid();
  auto* rm = sim->GetResourceManager();
  auto* param = sim->GetParam();

  // commit all changes
  const auto& all_exec_ctxts = sim->GetAllExecCtxts();
  all_exec_ctxts[0]->TearDownIterationAll(all_exec_ctxts);

  if (!is_gpu_environment_initialized_ && param->use_gpu_) {
    InitializeGPUEnvironment();
    is_gpu_environment_initialized_ = true;
  }

  if (param->bound_space_) {
    rm->ApplyOnAllElementsParallel(*bound_space_);
  }
  grid->Initialize();
  int lbound = grid->GetDimensionThresholds()[0];
  int rbound = grid->GetDimensionThresholds()[1];
  rm->ApplyOnAllDiffusionGrids([&](DiffusionGrid* dgrid) {
    // Create data structures, whose size depend on the grid dimensions
    dgrid->Initialize({lbound, rbound, lbound, rbound, lbound, rbound});
    // Initialize data structures with user-defined values
    dgrid->RunInitializers();
  });
}

std::vector<Operation> Scheduler::GetScheduleOps() {
  std::vector<Operation> scheduled_ops;
  scheduled_ops.reserve(operations_.size());
  auto* param = Simulation::GetActive()->GetParam();
  for (auto& op : operations_) {
    // special condition for displacement
    if (!param->run_mechanical_interactions_ && op.name_ == "displacement" &&
        !displacement_->UseCpu()) {
      continue;
    }
    if (total_steps_ % op.frequency_ == 0) {
      scheduled_ops.push_back(op);
    }
  }
  return scheduled_ops;
}

}  // namespace bdm
<commit_msg>Fix wrong run_mechanical_interactions flag propagation.<commit_after>// -----------------------------------------------------------------------------
//
// Copyright (C) The BioDynaMo Project.
// All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//
// See the LICENSE file distributed with this work for details.
// See the NOTICE file distributed with this work for additional information
// regarding copyright ownership.
//
// -----------------------------------------------------------------------------

#include "core/scheduler.h"

#include <chrono>
#include <string>

#include "core/execution_context/in_place_exec_ctxt.h"
#include "core/gpu/gpu_helper.h"
#include "core/operation/bound_space_op.h"
#include "core/operation/diffusion_op.h"
#include "core/operation/displacement_op.h"
#include "core/operation/op_timer.h"
#include "core/param/param.h"
#include "core/resource_manager.h"
#include "core/simulation.h"
#include "core/simulation_backup.h"
#include "core/util/log.h"
#include "core/visualization/catalyst_adaptor.h"

namespace bdm {

Scheduler::Scheduler() {
  auto* param = Simulation::GetActive()->GetParam();
  backup_ = new SimulationBackup(param->backup_file_, param->restore_file_);
  if (backup_->RestoreEnabled()) {
    restore_point_ = backup_->GetSimulationStepsFromBackup();
  }
  visualization_ =
      new CatalystAdaptor(BDM_SRC_DIR "/visualization/simple_pipeline.py");
  bound_space_ = new BoundSpace();
  displacement_ = new DisplacementOp();
  diffusion_ = new DiffusionOp();

  // initialise operations_
  auto first_op =
      Operation("first", [](SimObject* so) { so->UpdateRunDisplacement(); });
  auto last_op = Operation(
      "last", [](SimObject* so) { so->ApplyRunDisplacementForAllNextTs(); });
  auto biology_module_op = Operation(
      "biology modules", [](SimObject* so) { so->RunBiologyModules(); });
  auto discretization_op = Operation(
      "discretization", [](SimObject* so) { so->RunDiscretization(); });

  auto displacement_op = Operation("displacement", *displacement_);

  operations_ = {first_op,          Operation("bound space", *bound_space_),
                 biology_module_op, displacement_op,
                 discretization_op, last_op};
  protected_operations_ = {first_op.name_, biology_module_op.name_,
                           discretization_op.name_, last_op.name_};
}

Scheduler::~Scheduler() {
  delete backup_;
  delete visualization_;
  delete bound_space_;
  delete displacement_;
  delete diffusion_;
  auto* param = Simulation::GetActive()->GetParam();
  if (param->statistics_) {
    std::cout << gStatistics << std::endl;
  }
}

void Scheduler::Simulate(uint64_t steps) {
  if (Restore(&steps)) {
    return;
  }

  Initialize();
  for (unsigned step = 0; step < steps; step++) {
    Execute(step == steps - 1);

    total_steps_++;
    Backup();
  }
}

uint64_t Scheduler::GetSimulatedSteps() const { return total_steps_; }

void Scheduler::AddOperation(const Operation& op) {
  auto it = operations_.end() - 2;
  operations_.insert(it, op);
}

void Scheduler::RemoveOperation(const std::string& name) {
  if (protected_operations_.find(name) != protected_operations_.end()) {
    Log::Warning("Scheduler::GetOperation",
                 "You tried to remove the protected operation ", name,
                 "! This request was ignored.");
    return;
  }
  for (auto it = operations_.begin(); it != operations_.end(); ++it) {
    if (name == it->name_) {
      operations_.erase(it);
      return;
    }
  }
}

Operation* Scheduler::GetOperation(const std::string& name) {
  if (protected_operations_.find(name) != protected_operations_.end()) {
    Log::Warning("Scheduler::GetOperation",
                 "You tried to get the protected operation ", name, "!");
    return nullptr;
  }
  for (uint64_t i = 0; i < operations_.size(); i++) {
    auto& op = operations_[i];
    if (name == op.name_) {
      return &op;
    }
  }
  return nullptr;
}

void Scheduler::Execute(bool last_iteration) {
  auto* sim = Simulation::GetActive();
  auto* rm = sim->GetResourceManager();
  auto* grid = sim->GetGrid();
  auto* param = sim->GetParam();

  Timing::Time("Set up exec context", [&]() {
    const auto& all_exec_ctxts = sim->GetAllExecCtxts();
    all_exec_ctxts[0]->SetupIterationAll(all_exec_ctxts);
  });

  Timing::Time("visualize", [&]() {
    visualization_->Visualize(total_steps_, last_iteration);
  });
  Timing::Time("neighbors", [&]() { grid->UpdateGrid(); });

  // update all sim objects: run all CPU operations
  const auto& scheduled_ops = GetScheduleOps();
  rm->ApplyOnAllElementsParallelDynamic(
      param->scheduling_batch_size_, [&](SimObject* so, SoHandle) {
        sim->GetExecutionContext()->Execute(so, scheduled_ops);
      });

  // update all sim objects: hardware accelerated operations
  if (param->run_mechanical_interactions_ && !displacement_->UseCpu()) {
    Timing::Time("displacement (GPU/FPGA)", *displacement_);
  }

  // finish updating sim objects
  Timing::Time("Tear down exec context", [&]() {
    const auto& all_exec_ctxts = sim->GetAllExecCtxts();
    all_exec_ctxts[0]->TearDownIterationAll(all_exec_ctxts);
  });

  // update all substances (DiffusionGrids)
  Timing::Time("diffusion", *diffusion_);
}

void Scheduler::Backup() {
  using std::chrono::seconds;
  using std::chrono::duration_cast;
  auto* param = Simulation::GetActive()->GetParam();
  if (backup_->BackupEnabled() &&
      duration_cast<seconds>(Clock::now() - last_backup_).count() >=
          param->backup_interval_) {
    last_backup_ = Clock::now();
    backup_->Backup(total_steps_);
  }
}

/// Restore the simulation if requested at the right time
/// @param steps number of simulation steps for a `Simulate` call
/// @return if `Simulate` should return early
bool Scheduler::Restore(uint64_t* steps) {
  if (backup_->RestoreEnabled() && restore_point_ > total_steps_ + *steps) {
    total_steps_ += *steps;
    // restore requested, but not last backup was not done during this call to
    // Simualte. Therefore, we skip it.
    return true;
  } else if (backup_->RestoreEnabled() && restore_point_ > total_steps_ &&
             restore_point_ < total_steps_ + *steps) {
    // Restore
    backup_->Restore();
    *steps = total_steps_ + *steps - restore_point_;
    total_steps_ = restore_point_;
  }
  return false;
}

// TODO(lukas, ahmad) After https://trello.com/c/0D6sHCK4 has been resolved
// think about a better solution, because some operations are executed twice
// if Simulate is called with one timestep.
void Scheduler::Initialize() {
  auto* sim = Simulation::GetActive();
  auto* grid = sim->GetGrid();
  auto* rm = sim->GetResourceManager();
  auto* param = sim->GetParam();

  // commit all changes
  const auto& all_exec_ctxts = sim->GetAllExecCtxts();
  all_exec_ctxts[0]->TearDownIterationAll(all_exec_ctxts);

  if (!is_gpu_environment_initialized_ && param->use_gpu_) {
    InitializeGPUEnvironment();
    is_gpu_environment_initialized_ = true;
  }

  if (param->bound_space_) {
    rm->ApplyOnAllElementsParallel(*bound_space_);
  }
  grid->Initialize();
  int lbound = grid->GetDimensionThresholds()[0];
  int rbound = grid->GetDimensionThresholds()[1];
  rm->ApplyOnAllDiffusionGrids([&](DiffusionGrid* dgrid) {
    // Create data structures, whose size depend on the grid dimensions
    dgrid->Initialize({lbound, rbound, lbound, rbound, lbound, rbound});
    // Initialize data structures with user-defined values
    dgrid->RunInitializers();
  });
}

std::vector<Operation> Scheduler::GetScheduleOps() {
  std::vector<Operation> scheduled_ops;
  scheduled_ops.reserve(operations_.size());
  auto* param = Simulation::GetActive()->GetParam();
  for (auto& op : operations_) {
    // special condition for displacement
    if (op.name_ == "displacement" &&
        (!param->run_mechanical_interactions_ || !displacement_->UseCpu())) {
      continue;
    }
    if (total_steps_ % op.frequency_ == 0) {
      scheduled_ops.push_back(op);
    }
  }
  return scheduled_ops;
}

}  // namespace bdm
<|endoftext|>


<commit_before>#include "cci/syntax/parser.hpp"
#include "cci/ast/expr.hpp"
#include "cci/ast/type.hpp"
#include "cci/syntax/diagnostics.hpp"
#include "cci/syntax/scanner.hpp"
#include "cci/syntax/sema.hpp"
#include "cci/util/contracts.hpp"
#include "cci/util/small_vector.hpp"
#include <algorithm>
#include <string_view>

using namespace cci;

auto Parser::peek(size_t lookahead) -> Token
{
    cci_expects(peeked_toks.size() >= lookahead);

    if (lookahead < peeked_toks.size())
        return peeked_toks[lookahead];

    Token peeking = scanner.next_token();
    peeked_toks.push_back(peeking);
    cci_ensures(lookahead + 1 == peeked_toks.size());
    return peeking;
}

auto Parser::consume() -> Token
{
    Token consumed = peek();
    std::move(std::next(peeked_toks.begin()), peeked_toks.end(),
              peeked_toks.begin());
    peeked_toks.pop_back();
    return consumed;
}

auto Parser::expect_and_consume(Category category) -> std::optional<Token>
{
    if (peek().is(category))
        return consume();

    diag.report(peek().location(), diag::Diag::expected_but_got)
        .args(category, peek().category);
    return std::nullopt;
}

auto Parser::parse_expression() -> std::optional<arena_ptr<Expr>>
{
    return parse_primary_expression();
}

auto Parser::parse_primary_expression() -> std::optional<arena_ptr<Expr>>
{
    std::optional<arena_ptr<Expr>> res;

    switch (peek().category)
    {
        default: cci_unreachable();
        case Category::numeric_constant:
            res = sema.act_on_numeric_constant(consume());
            break;

        case Category::char_constant:
        case Category::utf8_char_constant:
        case Category::utf16_char_constant:
        case Category::utf32_char_constant:
        case Category::wide_char_constant:
            res = sema.act_on_char_constant(consume());
            break;

        case Category::string_literal:
        case Category::utf8_string_literal:
        case Category::utf16_string_literal:
        case Category::utf32_string_literal:
        case Category::wide_string_literal:
            res = parse_string_literal_expression();
            break;
        case Category::l_paren: {
            Token lparen_tok = consume();

            if ((res = parse_expression()))
            {
                if (auto rparen_tok = expect_and_consume(Category::r_paren))
                    res = sema.act_on_paren_expr(res.value(),
                                                 lparen_tok.location(),
                                                 rparen_tok->location());
            }

            break;
        }
    }

    return res ? parse_postfix_expression(*res) : res;
}

auto Parser::parse_string_literal_expression()
    -> std::optional<arena_ptr<StringLiteral>>
{
    cci_expects(is_string_literal(peek().category));

    small_vector<Token, 4> string_toks{consume()};
    while (is_string_literal(peek().category))
        string_toks.push_back(consume());

    return sema.act_on_string_literal(string_toks);
}

auto Parser::parse_postfix_expression(arena_ptr<Expr> expr)
    -> std::optional<arena_ptr<Expr>>
{
    switch (peek().category)
    {
        case Category::l_bracket: {
            Token lbracket_tok = consume();
            if (auto inside_brackets = parse_expression())
            {
                if (auto rbracket_tok = expect_and_consume(Category::r_bracket))
                {
                    return sema.act_on_array_subscript(
                        expr, inside_brackets.value(), lbracket_tok.location(),
                        rbracket_tok->location());
                }
            }
            break;
        }
        default: return expr;
    }

    return std::nullopt;
}
<commit_msg>Make lbracket_tok const<commit_after>#include "cci/syntax/parser.hpp"
#include "cci/ast/expr.hpp"
#include "cci/ast/type.hpp"
#include "cci/syntax/diagnostics.hpp"
#include "cci/syntax/scanner.hpp"
#include "cci/syntax/sema.hpp"
#include "cci/util/contracts.hpp"
#include "cci/util/small_vector.hpp"
#include <algorithm>
#include <string_view>

using namespace cci;

auto Parser::peek(size_t lookahead) -> Token
{
    cci_expects(peeked_toks.size() >= lookahead);

    if (lookahead < peeked_toks.size())
        return peeked_toks[lookahead];

    Token peeking = scanner.next_token();
    peeked_toks.push_back(peeking);
    cci_ensures(lookahead + 1 == peeked_toks.size());
    return peeking;
}

auto Parser::consume() -> Token
{
    Token consumed = peek();
    std::move(std::next(peeked_toks.begin()), peeked_toks.end(),
              peeked_toks.begin());
    peeked_toks.pop_back();
    return consumed;
}

auto Parser::expect_and_consume(Category category) -> std::optional<Token>
{
    if (peek().is(category))
        return consume();

    diag.report(peek().location(), diag::Diag::expected_but_got)
        .args(category, peek().category);
    return std::nullopt;
}

auto Parser::parse_expression() -> std::optional<arena_ptr<Expr>>
{
    return parse_primary_expression();
}

auto Parser::parse_primary_expression() -> std::optional<arena_ptr<Expr>>
{
    std::optional<arena_ptr<Expr>> res;

    switch (peek().category)
    {
        default: cci_unreachable();
        case Category::numeric_constant:
            res = sema.act_on_numeric_constant(consume());
            break;

        case Category::char_constant:
        case Category::utf8_char_constant:
        case Category::utf16_char_constant:
        case Category::utf32_char_constant:
        case Category::wide_char_constant:
            res = sema.act_on_char_constant(consume());
            break;

        case Category::string_literal:
        case Category::utf8_string_literal:
        case Category::utf16_string_literal:
        case Category::utf32_string_literal:
        case Category::wide_string_literal:
            res = parse_string_literal_expression();
            break;
        case Category::l_paren: {
            Token lparen_tok = consume();

            if ((res = parse_expression()))
            {
                if (auto rparen_tok = expect_and_consume(Category::r_paren))
                    res = sema.act_on_paren_expr(res.value(),
                                                 lparen_tok.location(),
                                                 rparen_tok->location());
            }

            break;
        }
    }

    return res ? parse_postfix_expression(*res) : res;
}

auto Parser::parse_string_literal_expression()
    -> std::optional<arena_ptr<StringLiteral>>
{
    cci_expects(is_string_literal(peek().category));

    small_vector<Token, 4> string_toks{consume()};
    while (is_string_literal(peek().category))
        string_toks.push_back(consume());

    return sema.act_on_string_literal(string_toks);
}

auto Parser::parse_postfix_expression(arena_ptr<Expr> expr)
    -> std::optional<arena_ptr<Expr>>
{
    switch (peek().category)
    {
        case Category::l_bracket: {
            const Token lbracket_tok = consume();
            if (auto expr_inside_brackets = parse_expression())
            {
                if (auto rbracket_tok = expect_and_consume(Category::r_bracket))
                {
                    return sema.act_on_array_subscript(
                        expr, expr_inside_brackets.value(),
                        lbracket_tok.location(), rbracket_tok->location());
                }
            }
            break;
        }
        default: return expr;
    }

    return std::nullopt;
}
<|endoftext|>