<commit_before>/**
 * Program an AVR with an mbed.
 */
#include "KickerBoard.hpp"

LocalFileSystem local("local");

int main() {
    // Store the thread's ID
    const osThreadId mainID = Thread::gettid();
    ASSERT(mainID != nullptr);

    // clear any extraneous rx serial bytes
    if (true) {
        Serial s(RJ_SERIAL_RXTX);
        // flush rx queue
        while (s.readable()) s.getc();

        // print out the baudrate we're using as a last resort
        // to let the user know they may or may not see it
        // depending on many factors.
        s.baud(57600);
    }

    // Turn on some startup LEDs to show they're working, they are turned off
    // before we hit the while loop
    statusLightsON(nullptr);

    // Set the default logging configurations
    isLogging = RJ_LOGGING_EN;
    rjLogLevel = INIT;

    /* Always send out an empty line at startup for keeping the console
     * clean on after a 'reboot' command is called;
     */
    if (isLogging) {
        // reset the console's default settings and enable the cursor
        printf("\033[m");
        fflush(stdout);
    }

    // Setup the interrupt priorities before launching each subsystem's task
    // thread.
    setISRPriorities();

    // Force off since the neopixel's hardware is stateless from previous
    // settings
    NeoStrip rgbLED(RJ_NEOPIXEL, 2);
    rgbLED.clear();

    // Set the RGB LEDs to a medium blue while the threads are started up
    float defaultBrightness = 0.02f;
    rgbLED.brightness(3 * defaultBrightness);
    rgbLED.setPixel(0, 0x00, 0x00, 0xFF);
    rgbLED.setPixel(1, 0x00, 0x00, 0xFF);
    rgbLED.write();

    // Start a periodic blinking LED to show system activity
    std::vector<DigitalOut> mbed_lights = {
        DigitalOut(LED1, 0), DigitalOut(LED2, 0), DigitalOut(LED3, 0),
        DigitalOut(LED4, 0),
    };
    RtosTimer live_light(imAlive, osTimerPeriodic, (void*)&mbed_lights);
    live_light.start(RJ_LIFELIGHT_TIMEOUT_MS);

    // Flip off the startup LEDs after a timeout period
    RtosTimer init_leds_off(statusLightsOFF, osTimerOnce);
    init_leds_off.start(RJ_STARTUP_LED_TIMEOUT_MS);

    // This is where the FPGA is actually configured with the bitfile's name
    // passed in
    bool fpga_ready = FPGA::Instance()->Init("/local/rj-fpga.nib");

    if (fpga_ready == true) {
        LOG(INIT, "FPGA Configuration Successful!");
    } else {
        LOG(FATAL, "FPGA Configuration Failed!");
    }

    fpga_err |= 1 << !fpga_ready;
    // the error code is valid now
    fpga_err |= 1 << 0;

    // Init IO Expander and turn  all LEDs
    MCP23017::Instance();

    // Startup the 3 separate threads, being sure that we wait for it
    // to signal back to us that we can startup the next thread. Not doing
    // so results in weird wierd things that are really hard to debug. Even
    // though this is multi-threaded code, that dosen't mean it's
    // a multi-core system.

    // Start the thread task for the on-board control loop
    Thread controller_task(Task_Controller, mainID, osPriorityHigh,
                           DEFAULT_STACK_SIZE / 2);
    Thread::signal_wait(MAIN_TASK_CONTINUE, osWaitForever);

    // Start the thread task for the serial console
    Thread console_task(Task_SerialConsole, mainID, osPriorityBelowNormal);
    Thread::signal_wait(MAIN_TASK_CONTINUE, osWaitForever);

    // Initialize the CommModule and CC1201 radio
    InitializeCommModule();

    DigitalOut rdy_led(RJ_RDY_LED, !fpga_ready);

    // Make sure all of the motors are enabled
    motors_Init();

    // Set error indicators
    if (fpga_err > 1) {
        // orange - error
        rgbLED.brightness(4 * defaultBrightness);
        rgbLED.setPixel(0, 0xFF, 0xA5, 0x00);
    } else {
        // green - no error...yet
        rgbLED.brightness(defaultBrightness);
        rgbLED.setPixel(0, 0x00, 0xFF, 0x00);
    }

    if (comm_err > 1) {
        // orange - error
        rgbLED.brightness(6 * defaultBrightness);
        rgbLED.setPixel(1, 0xFF, 0xA5, 0x00);
    } else {
        // green - no error...yet
        rgbLED.brightness(6 * defaultBrightness);
        rgbLED.setPixel(1, 0x00, 0xFF, 0x00);
    }

    if (comm_err > 1 && fpga_err > 1) {
        // bright as hell to make sure they know
        rgbLED.brightness(10 * defaultBrightness);
        // well, damn. everything is broke as hell
        rgbLED.setPixel(0, 0xFF, 0x00, 0x00);
        rgbLED.setPixel(1, 0xFF, 0x00, 0x00);
    }

    // push out the LED changes to the hardware
    rgbLED.write();

    // Set the watdog timer's initial config
    Watchdog::Set(RJ_WATCHDOG_TIMER_VALUE);

    // Release each thread into its operations in a structured manner
    controller_task.signal_set(SUB_TASK_CONTINUE);
    console_task.signal_set(SUB_TASK_CONTINUE);

    osStatus tState = osThreadSetPriority(mainID, osPriorityNormal);
    ASSERT(tState == osOK);

    rdy_led = fpga_ready;

    unsigned int ll = 0;

    MCP23017::Instance()->writeMask(0xFF00, 0xFF00);

    while (true) {
        // make sure we can always reach back to main by
        // renewing the watchdog timer periodicly
        rdy_led = !rdy_led;
        Watchdog::Renew();

        // periodically reset the console text's format
        ll++;
        if ((ll % 4) == 0) {
            printf("\033[m");
            fflush(stdout);
        }

        Thread::wait(RJ_WATCHDOG_TIMER_VALUE * 250);

        // M1
        // MCP23017::write_mask(~(1 << (8 + 1)), 0xFF00);

        // // M2
        // MCP23017::write_mask(~(1 << (8 + 0)), 0xFF00);

        // // M3
        // MCP23017::write_mask(~(1 << (8 + 5)), 0xFF00);

        // // M4
        // MCP23017::write_mask(~(1 << (8 + 7)), 0xFF00);

        // IMU
        // MCP23017::write_mask(~(1 << (8 + 6)), 0xFF00);

        // Det
        // MCP23017::write_mask(~(1 << (8 + 3)), 0xFF00);

        // Sense
        // MCP23017::write_mask(~(1 << (8 + 4)), 0xFF00);

        // Radio
        // MCP23017::write_mask(~(1 << (8 + 2)), 0xFF00);
    }
}

#define _EXTERN extern "C"

_EXTERN void HardFault_Handler() {
    __asm volatile(
        " tst lr, #4                                                \n"
        " ite eq                                                    \n"
        " mrseq r0, msp                                             \n"
        " mrsne r0, psp                                             \n"
        " ldr r1, [r0, #24]                                         \n"
        " ldr r2, hard_fault_handler_2_const                        \n"
        " bx r2                                                     \n"
        " hard_fault_handler_2_const: .word HARD_FAULT_HANDLER    	\n");
}

_EXTERN void HARD_FAULT_HANDLER(uint32_t* stackAddr) {
    /* These are volatile to try and prevent the compiler/linker optimising them
     * away as the variables never actually get used.  If the debugger won't
     * show the values of the variables, make them global my moving their
     * declaration outside of this function. */
    volatile uint32_t r0;
    volatile uint32_t r1;
    volatile uint32_t r2;
    volatile uint32_t r3;
    volatile uint32_t r12;
    volatile uint32_t lr;  /* Link register. */
    volatile uint32_t pc;  /* Program counter. */
    volatile uint32_t psr; /* Program status register. */

    r0 = stackAddr[0];
    r1 = stackAddr[1];
    r2 = stackAddr[2];
    r3 = stackAddr[3];
    r12 = stackAddr[4];
    lr = stackAddr[5];
    pc = stackAddr[6];
    psr = stackAddr[7];

    LOG(FATAL,
        "\r\n"
        "================================\r\n"
        "========== HARD FAULT ==========\r\n"
        "\r\n"
        "  MSP:\t0x%08X\r\n"
        "  HFSR:\t0x%08X\r\n"
        "  CFSR:\t0x%08X\r\n"
        "\r\n"
        "  r0:\t0x%08X\r\n"
        "  r1:\t0x%08X\r\n"
        "  r2:\t0x%08X\r\n"
        "  r3:\t0x%08X\r\n"
        "  r12:\t0x%08X\r\n"
        "  lr:\t0x%08X\r\n"
        "  pc:\t0x%08X\r\n"
        "  psr:\t0x%08X\r\n"
        "\r\n"
        "========== HARD FAULT ==========\r\n"
        "================================",
        __get_MSP, SCB->HFSR, SCB->CFSR, r0, r1, r2, r3, r12, lr, pc, psr);

    // do nothing so everything remains unchanged for debugging
    while (true) {
    }
}
<commit_msg>revert main.cpp changes from avr branch merge<commit_after>// ** DON'T INCLUDE <iostream>! THINGS WILL BREAK! **
#include <ctime>
#include <string>
#include <array>

#include <rtos.h>

#include <helper-funcs.hpp>
#include <watchdog.hpp>
#include <logger.hpp>
#include <assert.hpp>

#include "robot-devices.hpp"
#include "task-signals.hpp"
#include "task-globals.hpp"
#include "commands.hpp"
#include "fpga.hpp"
#include "io-expander.hpp"
#include "neostrip.hpp"

// task globals
uint16_t comm_err = 0;
uint16_t fpga_err = 0;
uint16_t imu_err = 0;

void Task_Controller(void const* args);

/**
 * @brief      { Sets the hardware configurations for the status LEDs & places
 * into the given state }
 *
 * @param[in]  state  { the next state of the LEDs }
 */
void statusLights(bool state) {
    DigitalInOut init_leds[] = {{RJ_BALL_LED, PIN_OUTPUT, OpenDrain, !state},
                                {RJ_RX_LED, PIN_OUTPUT, OpenDrain, !state},
                                {RJ_TX_LED, PIN_OUTPUT, OpenDrain, !state},
                                {RJ_RDY_LED, PIN_OUTPUT, OpenDrain, !state}};

    for (int i = 0; i < 4; i++) init_leds[i].mode(PullUp);
}

/**
 * @brief      { Turn all status LEDs on }
 */
void statusLightsON(void const* args) { statusLights(1); }

/**
 * @brief      { Turn all status LEDs off }
 */
void statusLightsOFF(void const* args) { statusLights(0); }

/**
 * [main Main The entry point of the system where each submodule's thread is
 * started.]
 * @return  [none]
 */
int main() {
    // Store the thread's ID
    const osThreadId mainID = Thread::gettid();
    ASSERT(mainID != nullptr);

    // clear any extraneous rx serial bytes
    if (true) {
        Serial s(RJ_SERIAL_RXTX);
        // flush rx queue
        while (s.readable()) s.getc();

        // print out the baudrate we're using as a last resort
        // to let the user know they may or may not see it
        // depending on many factors.
        s.baud(57600);
    }

    // Turn on some startup LEDs to show they're working, they are turned off
    // before we hit the while loop
    statusLightsON(nullptr);

    // Set the default logging configurations
    isLogging = RJ_LOGGING_EN;
    rjLogLevel = INIT;

    /* Always send out an empty line at startup for keeping the console
     * clean on after a 'reboot' command is called;
     */
    if (isLogging) {
        // reset the console's default settings and enable the cursor
        printf("\033[m");
        fflush(stdout);
    }

    // Setup the interrupt priorities before launching each subsystem's task
    // thread.
    setISRPriorities();

    // Force off since the neopixel's hardware is stateless from previous
    // settings
    NeoStrip rgbLED(RJ_NEOPIXEL, 2);
    rgbLED.clear();

    // Set the RGB LEDs to a medium blue while the threads are started up
    float defaultBrightness = 0.02f;
    rgbLED.brightness(3 * defaultBrightness);
    rgbLED.setPixel(0, 0x00, 0x00, 0xFF);
    rgbLED.setPixel(1, 0x00, 0x00, 0xFF);
    rgbLED.write();

    // Start a periodic blinking LED to show system activity
    std::vector<DigitalOut> mbed_lights = {
        DigitalOut(LED1, 0), DigitalOut(LED2, 0), DigitalOut(LED3, 0),
        DigitalOut(LED4, 0),
    };
    RtosTimer live_light(imAlive, osTimerPeriodic, (void*)&mbed_lights);
    live_light.start(RJ_LIFELIGHT_TIMEOUT_MS);

    // Flip off the startup LEDs after a timeout period
    RtosTimer init_leds_off(statusLightsOFF, osTimerOnce);
    init_leds_off.start(RJ_STARTUP_LED_TIMEOUT_MS);

    // This is where the FPGA is actually configured with the bitfile's name
    // passed in
    bool fpga_ready = FPGA::Instance()->Init("/local/rj-fpga.nib");

    if (fpga_ready == true) {
        LOG(INIT, "FPGA Configuration Successful!");
    } else {
        LOG(FATAL, "FPGA Configuration Failed!");
    }

    fpga_err |= 1 << !fpga_ready;
    // the error code is valid now
    fpga_err |= 1 << 0;

    // Init IO Expander and turn  all LEDs
    MCP23017::Instance();

    // Startup the 3 separate threads, being sure that we wait for it
    // to signal back to us that we can startup the next thread. Not doing
    // so results in weird wierd things that are really hard to debug. Even
    // though this is multi-threaded code, that dosen't mean it's
    // a multi-core system.

    // Start the thread task for the on-board control loop
    Thread controller_task(Task_Controller, mainID, osPriorityHigh,
                           DEFAULT_STACK_SIZE / 2);
    Thread::signal_wait(MAIN_TASK_CONTINUE, osWaitForever);

    // Start the thread task for the serial console
    Thread console_task(Task_SerialConsole, mainID, osPriorityBelowNormal);
    Thread::signal_wait(MAIN_TASK_CONTINUE, osWaitForever);

    // Initialize the CommModule and CC1201 radio
    InitializeCommModule();

    DigitalOut rdy_led(RJ_RDY_LED, !fpga_ready);

    // Make sure all of the motors are enabled
    motors_Init();

    // Set error indicators
    if (fpga_err > 1) {
        // orange - error
        rgbLED.brightness(4 * defaultBrightness);
        rgbLED.setPixel(0, 0xFF, 0xA5, 0x00);
    } else {
        // green - no error...yet
        rgbLED.brightness(defaultBrightness);
        rgbLED.setPixel(0, 0x00, 0xFF, 0x00);
    }

    if (comm_err > 1) {
        // orange - error
        rgbLED.brightness(6 * defaultBrightness);
        rgbLED.setPixel(1, 0xFF, 0xA5, 0x00);
    } else {
        // green - no error...yet
        rgbLED.brightness(6 * defaultBrightness);
        rgbLED.setPixel(1, 0x00, 0xFF, 0x00);
    }

    if (comm_err > 1 && fpga_err > 1) {
        // bright as hell to make sure they know
        rgbLED.brightness(10 * defaultBrightness);
        // well, damn. everything is broke as hell
        rgbLED.setPixel(0, 0xFF, 0x00, 0x00);
        rgbLED.setPixel(1, 0xFF, 0x00, 0x00);
    }

    // push out the LED changes to the hardware
    rgbLED.write();

    // Set the watdog timer's initial config
    Watchdog::Set(RJ_WATCHDOG_TIMER_VALUE);

    // Release each thread into its operations in a structured manner
    controller_task.signal_set(SUB_TASK_CONTINUE);
    console_task.signal_set(SUB_TASK_CONTINUE);

    osStatus tState = osThreadSetPriority(mainID, osPriorityNormal);
    ASSERT(tState == osOK);

    rdy_led = fpga_ready;

    unsigned int ll = 0;

    MCP23017::Instance()->writeMask(0xFF00, 0xFF00);

    while (true) {
        // make sure we can always reach back to main by
        // renewing the watchdog timer periodicly
        rdy_led = !rdy_led;
        Watchdog::Renew();

        // periodically reset the console text's format
        ll++;
        if ((ll % 4) == 0) {
            printf("\033[m");
            fflush(stdout);
        }

        Thread::wait(RJ_WATCHDOG_TIMER_VALUE * 250);

        // M1
        // MCP23017::write_mask(~(1 << (8 + 1)), 0xFF00);

        // // M2
        // MCP23017::write_mask(~(1 << (8 + 0)), 0xFF00);

        // // M3
        // MCP23017::write_mask(~(1 << (8 + 5)), 0xFF00);

        // // M4
        // MCP23017::write_mask(~(1 << (8 + 7)), 0xFF00);

        // IMU
        // MCP23017::write_mask(~(1 << (8 + 6)), 0xFF00);

        // Det
        // MCP23017::write_mask(~(1 << (8 + 3)), 0xFF00);

        // Sense
        // MCP23017::write_mask(~(1 << (8 + 4)), 0xFF00);

        // Radio
        // MCP23017::write_mask(~(1 << (8 + 2)), 0xFF00);
    }
}

#define _EXTERN extern "C"

_EXTERN void HardFault_Handler() {
    __asm volatile(
        " tst lr, #4                                                \n"
        " ite eq                                                    \n"
        " mrseq r0, msp                                             \n"
        " mrsne r0, psp                                             \n"
        " ldr r1, [r0, #24]                                         \n"
        " ldr r2, hard_fault_handler_2_const                        \n"
        " bx r2                                                     \n"
        " hard_fault_handler_2_const: .word HARD_FAULT_HANDLER    	\n");
}

_EXTERN void HARD_FAULT_HANDLER(uint32_t* stackAddr) {
    /* These are volatile to try and prevent the compiler/linker optimising them
     * away as the variables never actually get used.  If the debugger won't
     * show the values of the variables, make them global my moving their
     * declaration outside of this function. */
    volatile uint32_t r0;
    volatile uint32_t r1;
    volatile uint32_t r2;
    volatile uint32_t r3;
    volatile uint32_t r12;
    volatile uint32_t lr;  /* Link register. */
    volatile uint32_t pc;  /* Program counter. */
    volatile uint32_t psr; /* Program status register. */

    r0 = stackAddr[0];
    r1 = stackAddr[1];
    r2 = stackAddr[2];
    r3 = stackAddr[3];
    r12 = stackAddr[4];
    lr = stackAddr[5];
    pc = stackAddr[6];
    psr = stackAddr[7];

    LOG(FATAL,
        "\r\n"
        "================================\r\n"
        "========== HARD FAULT ==========\r\n"
        "\r\n"
        "  MSP:\t0x%08X\r\n"
        "  HFSR:\t0x%08X\r\n"
        "  CFSR:\t0x%08X\r\n"
        "\r\n"
        "  r0:\t0x%08X\r\n"
        "  r1:\t0x%08X\r\n"
        "  r2:\t0x%08X\r\n"
        "  r3:\t0x%08X\r\n"
        "  r12:\t0x%08X\r\n"
        "  lr:\t0x%08X\r\n"
        "  pc:\t0x%08X\r\n"
        "  psr:\t0x%08X\r\n"
        "\r\n"
        "========== HARD FAULT ==========\r\n"
        "================================",
        __get_MSP, SCB->HFSR, SCB->CFSR, r0, r1, r2, r3, r12, lr, pc, psr);

    // do nothing so everything remains unchanged for debugging
    while (true) {
    }
}

_EXTERN void NMI_Handler() { std::printf("NMI Fault!\n"); }

_EXTERN void MemManage_Handler() { std::printf("MemManage Fault!\n"); }

_EXTERN void BusFault_Handler() { std::printf("BusFault Fault!\n"); }

_EXTERN void UsageFault_Handler() { std::printf("UsageFault Fault!\n"); }
<|endoftext|>


<commit_before>/*
Copyright 2011, 2012 Rogier van Dalen.

This file is part of Rogier van Dalen's Meta-programming library for C++.

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

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

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

#ifndef META_ENUMERATE_HPP_INCLUDED
#define META_ENUMERATE_HPP_INCLUDED

#include <boost/mpl/size_t.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/pair.hpp>

#include "meta/fwd.hpp"
#include "meta/range.hpp"
#include "meta/scan.hpp"

namespace meta {

    template <typename Direction, typename Range =void> struct enumerate;

    template <typename Range> struct enumerate <Range>
    : enumerate <typename default_direction <Range>::type, Range> {};

    template <typename Direction, typename Range> struct enumerate {
        // Initialise with the before-the-begin element (-1, void).
        typedef mpl::pair <mpl::size_t <-1>, void> before_begin;

        // Implementation without lambdas is faster.
        struct function {
            template <typename Previous, typename Type> struct apply
            {
                typedef typename mpl::next <typename Previous::first>::type
                    number;
                typedef mpl::pair <number, Type> type;
            };
        };

        // Enumerated list of types that starts with (-1, void).
        typedef scan <Direction, function, before_begin, Range> elements;
        // Remove the (-1, void)
        typedef typename drop <Direction, elements>::type type;
    };

} // namespace meta

#endif  // META_ENUMERATE_HPP_INCLUDED

<commit_msg>Fix warning in CLang 3.4<commit_after>/*
Copyright 2011, 2012 Rogier van Dalen.

This file is part of Rogier van Dalen's Meta-programming library for C++.

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

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

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

#ifndef META_ENUMERATE_HPP_INCLUDED
#define META_ENUMERATE_HPP_INCLUDED

#include <boost/mpl/size_t.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/pair.hpp>

#include "meta/fwd.hpp"
#include "meta/range.hpp"
#include "meta/scan.hpp"

namespace meta {

    template <typename Direction, typename Range =void> struct enumerate;

    template <typename Range> struct enumerate <Range>
    : enumerate <typename default_direction <Range>::type, Range> {};

    template <typename Direction, typename Range> struct enumerate {
        // Initialise with the before-the-begin element (-1, void).
        typedef mpl::pair <mpl::size_t <std::size_t (-1)>, void> before_begin;

        // Implementation without lambdas is faster.
        struct function {
            template <typename Previous, typename Type> struct apply
            {
                typedef typename mpl::next <typename Previous::first>::type
                    number;
                typedef mpl::pair <number, Type> type;
            };
        };

        // Enumerated list of types that starts with (-1, void).
        typedef scan <Direction, function, before_begin, Range> elements;
        // Remove the (-1, void)
        typedef typename drop <Direction, elements>::type type;
    };

} // namespace meta

#endif  // META_ENUMERATE_HPP_INCLUDED

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: namingservice.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2001-09-11 13:49:23 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <hash_map>

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _UNO_DISPATCHER_H_
#include <uno/dispatcher.h>
#endif
#ifndef _UNO_MAPPING_HXX_
#include <uno/mapping.hxx>
#endif

#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
#include <cppuhelper/queryinterface.hxx>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif
#ifndef _CPPUHELPER_FACTORY_HXX_
#include <cppuhelper/factory.hxx>
#endif
#ifndef _CPPUHELPER_COMPONENT_HXX_
#include <cppuhelper/component.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif
#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
#include <cppuhelper/implementationentry.hxx>
#endif

#include <com/sun/star/uno/XNamingService.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>

using namespace cppu;
using namespace rtl;
using namespace osl;
using namespace std;

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::registry;

#define SERVICENAME "com.sun.star.uno.NamingService"
#define IMPLNAME    "com.sun.star.comp.stoc.NamingService"

namespace stoc_namingservice
{
static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;

static Sequence< OUString > ns_getSupportedServiceNames()
{
    static Sequence < OUString > *pNames = 0;
    if( ! pNames )
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if( !pNames )
        {
            static Sequence< OUString > seqNames(1);
            seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
            pNames = &seqNames;
        }
    }
    return *pNames;
}

static OUString ns_getImplementationName()
{
    static OUString *pImplName = 0;
    if( ! pImplName )
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if( ! pImplName )
        {
            static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
            pImplName = &implName;
        }
    }
    return *pImplName;
}

struct equalOWString_Impl
{
  sal_Bool operator()(const OUString & s1, const OUString & s2) const
        { return s1 == s2; }
};

struct hashOWString_Impl
{
    size_t operator()(const OUString & rName) const
        { return rName.hashCode(); }
};

typedef hash_map
<
    OUString,
    Reference<XInterface >,
    hashOWString_Impl,
    equalOWString_Impl
> HashMap_OWString_Interface;

//==================================================================================================
class NamingService_Impl
    : public WeakImplHelper2 < XServiceInfo, XNamingService >
{
    Mutex                               aMutex;
    HashMap_OWString_Interface          aMap;
public:
    NamingService_Impl();
    ~NamingService_Impl();

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName()
    throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName )
    throw(::com::sun::star::uno::RuntimeException);
    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
    throw(::com::sun::star::uno::RuntimeException);
    static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static()
    {
        OUString aStr( OUString::createFromAscii( SERVICENAME ) );
        return Sequence< OUString >( &aStr, 1 );
    }

    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getRegisteredObject( const ::rtl::OUString& Name ) throw(Exception, RuntimeException);
    virtual void SAL_CALL registerObject( const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Object ) throw(Exception, RuntimeException);
    virtual void SAL_CALL revokeObject( const ::rtl::OUString& Name ) throw(Exception, RuntimeException);
};

//==================================================================================================
static Reference<XInterface> SAL_CALL NamingService_Impl_create( const Reference<XComponentContext> & )
{
    return *new NamingService_Impl();
}

//==================================================================================================
NamingService_Impl::NamingService_Impl()
{
    g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
}

//==================================================================================================
NamingService_Impl::~NamingService_Impl()
{
    g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}

// XServiceInfo
OUString NamingService_Impl::getImplementationName()
    throw(::com::sun::star::uno::RuntimeException)
{
    return ns_getImplementationName();
}

// XServiceInfo
sal_Bool NamingService_Impl::supportsService( const OUString & rServiceName )
    throw(::com::sun::star::uno::RuntimeException)
{
    const Sequence< OUString > & rSNL = getSupportedServiceNames();
    const OUString * pArray = rSNL.getConstArray();
    for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
    {
        if (pArray[nPos] == rServiceName)
            return sal_True;
    }
    return sal_False;
}

// XServiceInfo
Sequence< OUString > NamingService_Impl::getSupportedServiceNames()
    throw(::com::sun::star::uno::RuntimeException)
{
    return ns_getSupportedServiceNames();
}

// XServiceInfo
Reference< XInterface > NamingService_Impl::getRegisteredObject( const OUString& Name ) throw(Exception, RuntimeException)
{
    Guard< Mutex > aGuard( aMutex );
    Reference< XInterface > xRet;
    HashMap_OWString_Interface::iterator aIt = aMap.find( Name );
    if( aIt != aMap.end() )
        xRet = (*aIt).second;
    return xRet;
}

// XServiceInfo
void NamingService_Impl::registerObject( const OUString& Name, const Reference< XInterface >& Object ) throw(Exception, RuntimeException)
{
    Guard< Mutex > aGuard( aMutex );
    aMap[ Name ] = Object;
}

// XServiceInfo
void NamingService_Impl::revokeObject( const OUString& Name ) throw(Exception, RuntimeException)
{
    Guard< Mutex > aGuard( aMutex );
    aMap.erase( Name );
}

}

using namespace stoc_namingservice;
static struct ImplementationEntry g_entries[] =
{
    {
        NamingService_Impl_create, ns_getImplementationName,
        ns_getSupportedServiceNames, createSingleComponentFactory,
        &g_moduleCount.modCnt , 0
    },
    { 0, 0, 0, 0, 0, 0 }
};

extern "C"
{
sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
{
    return g_moduleCount.canUnload( &g_moduleCount , pTime );
}

//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
sal_Bool SAL_CALL component_writeInfo(
    void * pServiceManager, void * pRegistryKey )
{
    return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
}
//==================================================================================================
void * SAL_CALL component_getFactory(
    const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
    return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.5.208); FILE MERGED 2005/09/05 17:11:00 rt 1.5.208.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: namingservice.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 08:01:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <hash_map>

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _UNO_DISPATCHER_H_
#include <uno/dispatcher.h>
#endif
#ifndef _UNO_MAPPING_HXX_
#include <uno/mapping.hxx>
#endif

#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
#include <cppuhelper/queryinterface.hxx>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif
#ifndef _CPPUHELPER_FACTORY_HXX_
#include <cppuhelper/factory.hxx>
#endif
#ifndef _CPPUHELPER_COMPONENT_HXX_
#include <cppuhelper/component.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif
#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
#include <cppuhelper/implementationentry.hxx>
#endif

#include <com/sun/star/uno/XNamingService.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>

using namespace cppu;
using namespace rtl;
using namespace osl;
using namespace std;

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::registry;

#define SERVICENAME "com.sun.star.uno.NamingService"
#define IMPLNAME    "com.sun.star.comp.stoc.NamingService"

namespace stoc_namingservice
{
static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;

static Sequence< OUString > ns_getSupportedServiceNames()
{
    static Sequence < OUString > *pNames = 0;
    if( ! pNames )
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if( !pNames )
        {
            static Sequence< OUString > seqNames(1);
            seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
            pNames = &seqNames;
        }
    }
    return *pNames;
}

static OUString ns_getImplementationName()
{
    static OUString *pImplName = 0;
    if( ! pImplName )
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if( ! pImplName )
        {
            static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
            pImplName = &implName;
        }
    }
    return *pImplName;
}

struct equalOWString_Impl
{
  sal_Bool operator()(const OUString & s1, const OUString & s2) const
        { return s1 == s2; }
};

struct hashOWString_Impl
{
    size_t operator()(const OUString & rName) const
        { return rName.hashCode(); }
};

typedef hash_map
<
    OUString,
    Reference<XInterface >,
    hashOWString_Impl,
    equalOWString_Impl
> HashMap_OWString_Interface;

//==================================================================================================
class NamingService_Impl
    : public WeakImplHelper2 < XServiceInfo, XNamingService >
{
    Mutex                               aMutex;
    HashMap_OWString_Interface          aMap;
public:
    NamingService_Impl();
    ~NamingService_Impl();

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName()
    throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName )
    throw(::com::sun::star::uno::RuntimeException);
    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
    throw(::com::sun::star::uno::RuntimeException);
    static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static()
    {
        OUString aStr( OUString::createFromAscii( SERVICENAME ) );
        return Sequence< OUString >( &aStr, 1 );
    }

    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getRegisteredObject( const ::rtl::OUString& Name ) throw(Exception, RuntimeException);
    virtual void SAL_CALL registerObject( const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Object ) throw(Exception, RuntimeException);
    virtual void SAL_CALL revokeObject( const ::rtl::OUString& Name ) throw(Exception, RuntimeException);
};

//==================================================================================================
static Reference<XInterface> SAL_CALL NamingService_Impl_create( const Reference<XComponentContext> & )
{
    return *new NamingService_Impl();
}

//==================================================================================================
NamingService_Impl::NamingService_Impl()
{
    g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
}

//==================================================================================================
NamingService_Impl::~NamingService_Impl()
{
    g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}

// XServiceInfo
OUString NamingService_Impl::getImplementationName()
    throw(::com::sun::star::uno::RuntimeException)
{
    return ns_getImplementationName();
}

// XServiceInfo
sal_Bool NamingService_Impl::supportsService( const OUString & rServiceName )
    throw(::com::sun::star::uno::RuntimeException)
{
    const Sequence< OUString > & rSNL = getSupportedServiceNames();
    const OUString * pArray = rSNL.getConstArray();
    for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
    {
        if (pArray[nPos] == rServiceName)
            return sal_True;
    }
    return sal_False;
}

// XServiceInfo
Sequence< OUString > NamingService_Impl::getSupportedServiceNames()
    throw(::com::sun::star::uno::RuntimeException)
{
    return ns_getSupportedServiceNames();
}

// XServiceInfo
Reference< XInterface > NamingService_Impl::getRegisteredObject( const OUString& Name ) throw(Exception, RuntimeException)
{
    Guard< Mutex > aGuard( aMutex );
    Reference< XInterface > xRet;
    HashMap_OWString_Interface::iterator aIt = aMap.find( Name );
    if( aIt != aMap.end() )
        xRet = (*aIt).second;
    return xRet;
}

// XServiceInfo
void NamingService_Impl::registerObject( const OUString& Name, const Reference< XInterface >& Object ) throw(Exception, RuntimeException)
{
    Guard< Mutex > aGuard( aMutex );
    aMap[ Name ] = Object;
}

// XServiceInfo
void NamingService_Impl::revokeObject( const OUString& Name ) throw(Exception, RuntimeException)
{
    Guard< Mutex > aGuard( aMutex );
    aMap.erase( Name );
}

}

using namespace stoc_namingservice;
static struct ImplementationEntry g_entries[] =
{
    {
        NamingService_Impl_create, ns_getImplementationName,
        ns_getSupportedServiceNames, createSingleComponentFactory,
        &g_moduleCount.modCnt , 0
    },
    { 0, 0, 0, 0, 0, 0 }
};

extern "C"
{
sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
{
    return g_moduleCount.canUnload( &g_moduleCount , pTime );
}

//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
sal_Bool SAL_CALL component_writeInfo(
    void * pServiceManager, void * pRegistryKey )
{
    return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
}
//==================================================================================================
void * SAL_CALL component_getFactory(
    const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
    return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}
}
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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.
 *
 */

// Generates Objective C gRPC service interface out of Protobuf IDL.

#include <memory>

#include "src/compiler/config.h"
#include "src/compiler/objective_c_generator.h"
#include "src/compiler/objective_c_generator_helpers.h"

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>

using ::google::protobuf::compiler::objectivec::
    IsProtobufLibraryBundledProtoFile;
using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName;
using ::grpc_objective_c_generator::LocalImport;
using ::grpc_objective_c_generator::PreprocIfElse;
using ::grpc_objective_c_generator::PreprocIfNot;
using ::grpc_objective_c_generator::SystemImport;

namespace {

inline ::grpc::string ImportProtoHeaders(
    const grpc::protobuf::FileDescriptor* dep, const char* indent) {
  ::grpc::string header = grpc_objective_c_generator::MessageHeaderName(dep);

  if (!IsProtobufLibraryBundledProtoFile(dep)) {
    return indent + LocalImport(header);
  }

  ::grpc::string base_name = header;
  grpc_generator::StripPrefix(&base_name, "google/protobuf/");
  // create the import code snippet
  ::grpc::string framework_header =
      ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name;

  static const ::grpc::string kFrameworkImportsCondition =
      "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS";
  return PreprocIfElse(kFrameworkImportsCondition,
                       indent + SystemImport(framework_header),
                       indent + LocalImport(header));
}

}  // namespace

class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
 public:
  ObjectiveCGrpcGenerator() {}
  virtual ~ObjectiveCGrpcGenerator() {}

 public:
  virtual bool Generate(const grpc::protobuf::FileDescriptor* file,
                        const ::grpc::string& parameter,
                        grpc::protobuf::compiler::GeneratorContext* context,
                        ::grpc::string* error) const {
    if (file->service_count() == 0) {
      // No services.  Do nothing.
      return true;
    }

    static const ::grpc::string kNonNullBegin = "NS_ASSUME_NONNULL_BEGIN\n";
    static const ::grpc::string kNonNullEnd = "NS_ASSUME_NONNULL_END\n";
    static const ::grpc::string kProtocolOnly = "GPB_GRPC_PROTOCOL_ONLY";
    static const ::grpc::string kForwardDeclare =
        "GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO";

    ::grpc::string file_name =
        google::protobuf::compiler::objectivec::FilePath(file);

    {
      // Generate .pbrpc.h

      ::grpc::string imports = LocalImport(file_name + ".pbobjc.h");

      ::grpc::string system_imports = SystemImport("ProtoRPC/ProtoService.h") +
                                      SystemImport("ProtoRPC/ProtoRPC.h") +
                                      SystemImport("RxLibrary/GRXWriteable.h") +
                                      SystemImport("RxLibrary/GRXWriter.h");

      ::grpc::string forward_declarations = "@class GRPCProtoCall;\n\n";

      ::grpc::string class_declarations =
          grpc_objective_c_generator::GetAllMessageClasses(file);

      ::grpc::string class_imports;
      for (int i = 0; i < file->dependency_count(); i++) {
        class_imports += ImportProtoHeaders(file->dependency(i), "  ");
      }

      ::grpc::string protocols;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor* service = file->service(i);
        protocols += grpc_objective_c_generator::GetProtocol(service);
      }

      ::grpc::string interfaces;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor* service = file->service(i);
        interfaces += grpc_objective_c_generator::GetInterface(service);
      }

      Write(context, file_name + ".pbrpc.h",
            PreprocIfNot(kForwardDeclare, imports) + "\n" +
                PreprocIfNot(kProtocolOnly, system_imports) + "\n" +
                PreprocIfElse(kForwardDeclare, class_declarations,
                              class_imports) +
                "\n" + forward_declarations + "\n" + kNonNullBegin + "\n" +
                protocols + "\n" + PreprocIfNot(kProtocolOnly, interfaces) +
                "\n" + kNonNullEnd + "\n");
    }

    {
      // Generate .pbrpc.m

      ::grpc::string imports = LocalImport(file_name + ".pbrpc.h") +
                               LocalImport(file_name + ".pbobjc.h") +
                               SystemImport("ProtoRPC/ProtoRPC.h") +
                               SystemImport("RxLibrary/GRXWriter+Immediate.h");

      ::grpc::string class_imports;
      for (int i = 0; i < file->dependency_count(); i++) {
        class_imports += ImportProtoHeaders(file->dependency(i), "");
      }

      ::grpc::string definitions;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor* service = file->service(i);
        definitions += grpc_objective_c_generator::GetSource(service);
      }

      Write(context, file_name + ".pbrpc.m",
            PreprocIfNot(kProtocolOnly,
                         imports + "\n" + class_imports + "\n" + definitions));
    }

    return true;
  }

 private:
  // Write the given code into the given file.
  void Write(grpc::protobuf::compiler::GeneratorContext* context,
             const ::grpc::string& filename, const ::grpc::string& code) const {
    std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
        context->Open(filename));
    grpc::protobuf::io::CodedOutputStream coded_out(output.get());
    coded_out.WriteRaw(code.data(), code.size());
  }
};

int main(int argc, char* argv[]) {
  ObjectiveCGrpcGenerator generator;
  return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
}
<commit_msg>Changes \#if forward_declare <forward_decl> \#else <class_imports> \#end in .h files to <forward_decl> \#if <class_imports><commit_after>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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.
 *
 */

// Generates Objective C gRPC service interface out of Protobuf IDL.

#include <memory>

#include "src/compiler/config.h"
#include "src/compiler/objective_c_generator.h"
#include "src/compiler/objective_c_generator_helpers.h"

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>

using ::google::protobuf::compiler::objectivec::
    IsProtobufLibraryBundledProtoFile;
using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName;
using ::grpc_objective_c_generator::LocalImport;
using ::grpc_objective_c_generator::PreprocIfElse;
using ::grpc_objective_c_generator::PreprocIfNot;
using ::grpc_objective_c_generator::SystemImport;

namespace {

inline ::grpc::string ImportProtoHeaders(
    const grpc::protobuf::FileDescriptor* dep, const char* indent) {
  ::grpc::string header = grpc_objective_c_generator::MessageHeaderName(dep);

  if (!IsProtobufLibraryBundledProtoFile(dep)) {
    return indent + LocalImport(header);
  }

  ::grpc::string base_name = header;
  grpc_generator::StripPrefix(&base_name, "google/protobuf/");
  // create the import code snippet
  ::grpc::string framework_header =
      ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name;

  static const ::grpc::string kFrameworkImportsCondition =
      "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS";
  return PreprocIfElse(kFrameworkImportsCondition,
                       indent + SystemImport(framework_header),
                       indent + LocalImport(header));
}

}  // namespace

class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
 public:
  ObjectiveCGrpcGenerator() {}
  virtual ~ObjectiveCGrpcGenerator() {}

 public:
  virtual bool Generate(const grpc::protobuf::FileDescriptor* file,
                        const ::grpc::string& parameter,
                        grpc::protobuf::compiler::GeneratorContext* context,
                        ::grpc::string* error) const {
    if (file->service_count() == 0) {
      // No services.  Do nothing.
      return true;
    }

    static const ::grpc::string kNonNullBegin = "NS_ASSUME_NONNULL_BEGIN\n";
    static const ::grpc::string kNonNullEnd = "NS_ASSUME_NONNULL_END\n";
    static const ::grpc::string kProtocolOnly = "GPB_GRPC_PROTOCOL_ONLY";
    static const ::grpc::string kForwardDeclare =
        "GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO";

    ::grpc::string file_name =
        google::protobuf::compiler::objectivec::FilePath(file);

    {
      // Generate .pbrpc.h

      ::grpc::string imports = LocalImport(file_name + ".pbobjc.h");

      ::grpc::string system_imports = SystemImport("ProtoRPC/ProtoService.h") +
                                      SystemImport("ProtoRPC/ProtoRPC.h") +
                                      SystemImport("RxLibrary/GRXWriteable.h") +
                                      SystemImport("RxLibrary/GRXWriter.h");

      ::grpc::string forward_declarations = "@class GRPCProtoCall;\n\n";

      ::grpc::string class_declarations =
          grpc_objective_c_generator::GetAllMessageClasses(file);

      ::grpc::string class_imports;
      for (int i = 0; i < file->dependency_count(); i++) {
        class_imports += ImportProtoHeaders(file->dependency(i), "  ");
      }

      ::grpc::string protocols;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor* service = file->service(i);
        protocols += grpc_objective_c_generator::GetProtocol(service);
      }

      ::grpc::string interfaces;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor* service = file->service(i);
        interfaces += grpc_objective_c_generator::GetInterface(service);
      }

      Write(context, file_name + ".pbrpc.h",
            PreprocIfNot(kForwardDeclare, imports) + "\n" +
                PreprocIfNot(kProtocolOnly, system_imports) + "\n" +
                class_declarations + "\n"
                PreprocIfNot(kForwardDeclare, class_imports) +
                "\n" + forward_declarations + "\n" + kNonNullBegin + "\n" +
                protocols + "\n" + PreprocIfNot(kProtocolOnly, interfaces) +
                "\n" + kNonNullEnd + "\n");
    }

    {
      // Generate .pbrpc.m

      ::grpc::string imports = LocalImport(file_name + ".pbrpc.h") +
                               LocalImport(file_name + ".pbobjc.h") +
                               SystemImport("ProtoRPC/ProtoRPC.h") +
                               SystemImport("RxLibrary/GRXWriter+Immediate.h");

      ::grpc::string class_imports;
      for (int i = 0; i < file->dependency_count(); i++) {
        class_imports += ImportProtoHeaders(file->dependency(i), "");
      }

      ::grpc::string definitions;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor* service = file->service(i);
        definitions += grpc_objective_c_generator::GetSource(service);
      }

      Write(context, file_name + ".pbrpc.m",
            PreprocIfNot(kProtocolOnly,
                         imports + "\n" + class_imports + "\n" + definitions));
    }

    return true;
  }

 private:
  // Write the given code into the given file.
  void Write(grpc::protobuf::compiler::GeneratorContext* context,
             const ::grpc::string& filename, const ::grpc::string& code) const {
    std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
        context->Open(filename));
    grpc::protobuf::io::CodedOutputStream coded_out(output.get());
    coded_out.WriteRaw(code.data(), code.size());
  }
};

int main(int argc, char* argv[]) {
  ObjectiveCGrpcGenerator generator;
  return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
}
<|endoftext|>


<commit_before>#include "InputHandler.h"
#include "SFML/Window.hpp"
#include "SFData.h"

Player::Direction InputHandler::LastInput;
int InputHandler::InputTime;
bool InputHandler::WindowClosed = false;

void InputHandler::PollEvents()
{
    sf::Event event;
    while (SFData::Window->pollEvent(event))
    {
		switch (event.type)
		{
			case sf::Event::KeyPressed:
				Player::Direction newInput = -1;
				switch (event.key.code)
				{
					case sf::Keyboard::W:
						newInput = Player::Up;
						break;
					case sf::Keyboard::A:
						newInput = Player::Left;
						break;
					case sf::Keyboard::S:
						newInput = Player::Down;
						break;
					case sf::Keyboard::D:
						newInput = Player::Right;
						break;
					default:
						continue;
				}
				if (newInput != LastInput)
				{
					LastInput = newInput;
					InputTime = -1;
				}
				break;
			case sf::Event::Closed:
				WindowClosed = true;
				break;
		}
	}
	InputTime++;
}
<commit_msg>Allow repeated input to reset frame counter<commit_after>#include "InputHandler.h"
#include "SFML/Window.hpp"
#include "SFData.h"

Player::Direction InputHandler::LastInput;
int InputHandler::InputTime;
bool InputHandler::WindowClosed = false;

void InputHandler::PollEvents()
{
    sf::Event event;
    while (SFData::Window->pollEvent(event))
    {
		switch (event.type)
		{
			case sf::Event::KeyPressed:
				Player::Direction newInput = (Player::Direction)-1;
				switch (event.key.code)
				{
					case sf::Keyboard::W:
						newInput = Player::Up;
						break;
					case sf::Keyboard::A:
						newInput = Player::Left;
						break;
					case sf::Keyboard::S:
						newInput = Player::Down;
						break;
					case sf::Keyboard::D:
						newInput = Player::Right;
						break;
					default:
						continue;
				}
				LastInput = newInput;
				InputTime = -1;
				break;
			case sf::Event::Closed:
				WindowClosed = true;
				break;
		}
	}
	InputTime++;
}
<|endoftext|>


<commit_before><?hh //strict

/**
 * This file is part of hhpack\color.
 *
 * (c) Noritaka Horio <holy.shared.design@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace hhpack\color;

final class Color
{

    private Set<StyleType> $styles;

    public function __construct(
        private ForegroundColor $color = ForegroundColor::DefaultColor,
        private BackgroundColor $backgroundColor = BackgroundColor::DefaultColor
    )
    {
        $this->styles = Set {};
    }

    public function color(ForegroundColor $color) : this
    {
        $this->color = $color;
        return $this;
    }

    public function background(BackgroundColor $color) : this
    {
        $this->backgroundColor = $color;
        return $this;
    }

    public function addStyle(StyleType $style) : this
    {
        $this->styles->add($style);
        return $this;
    }

    public function removeStyle(StyleType $style) : this
    {
        $this->styles->remove($style);
        return $this;
    }

    public function println(string $format, ...) : void
    {
        $text = call_user_func_array([ $this, 'format' ], func_get_args());
        fwrite(STDOUT, $text . PHP_EOL);
    }

    public function display(string $format, ...) : void
    {
        $text = call_user_func_array([ $this, 'format' ], func_get_args());
        fwrite(STDOUT, $text);
    }

    public static function fromColor(ForegroundColor $color) : this
    {
        return new Color($color);
    }

    public static function fromBackground(BackgroundColor $color) : this
    {
        return new Color(ForegroundColor::DefaultColor, $color);
    }

    public static function fromDefault() : this
    {
        return new Color();
    }

    public function format(string $format, ...) : string
    {
        $parts = Set { $format };
        $parts->addAll( func_get_args() );

        $text = call_user_func_array('sprintf', $parts->toArray());

        return $this->applyTo($text);
    }

    public function applyTo(string $text) : string
    {
        $styles = Set {};

        if ($this->styles->isEmpty()) {
            $this->addStyle(StyleType::DefaultStyle);
        }

        $styles->addAll($this->styles);

        $styles->add((string) $this->color);
        $styles->add((string) $this->backgroundColor);

        $styleText = implode(';', $styles->toValuesArray());

        return sprintf("\e[%sm%s\e[0m", $styleText, $text);
    }

}
<commit_msg>to inst_meth<commit_after><?hh //strict

/**
 * This file is part of hhpack\color.
 *
 * (c) Noritaka Horio <holy.shared.design@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace hhpack\color;

final class Color
{

    private Set<StyleType> $styles;

    public function __construct(
        private ForegroundColor $color = ForegroundColor::DefaultColor,
        private BackgroundColor $backgroundColor = BackgroundColor::DefaultColor
    )
    {
        $this->styles = Set {};
    }

    public function color(ForegroundColor $color) : this
    {
        $this->color = $color;
        return $this;
    }

    public function background(BackgroundColor $color) : this
    {
        $this->backgroundColor = $color;
        return $this;
    }

    public function addStyle(StyleType $style) : this
    {
        $this->styles->add($style);
        return $this;
    }

    public function removeStyle(StyleType $style) : this
    {
        $this->styles->remove($style);
        return $this;
    }

    public function println(string $format, ...) : void
    {
        $text = call_user_func_array(inst_meth($this, 'format'), func_get_args());
        fwrite(STDOUT, $text . PHP_EOL);
    }

    public function display(string $format, ...) : void
    {
        $text = call_user_func_array(inst_meth($this, 'format'), func_get_args());
        fwrite(STDOUT, $text);
    }

    public static function fromColor(ForegroundColor $color) : this
    {
        return new Color($color);
    }

    public static function fromBackground(BackgroundColor $color) : this
    {
        return new Color(ForegroundColor::DefaultColor, $color);
    }

    public static function fromDefault() : this
    {
        return new Color();
    }

    public function format(string $format, ...) : string
    {
        $parts = Set { $format };
        $parts->addAll( func_get_args() );

        $text = call_user_func_array('sprintf', $parts->toArray());

        return $this->applyTo($text);
    }

    public function applyTo(string $text) : string
    {
        $styles = Set {};

        if ($this->styles->isEmpty()) {
            $this->addStyle(StyleType::DefaultStyle);
        }

        $styles->addAll($this->styles);

        $styles->add((string) $this->color);
        $styles->add((string) $this->backgroundColor);

        $styleText = implode(';', $styles->toValuesArray());

        return sprintf("\e[%sm%s\e[0m", $styleText, $text);
    }

}
<|endoftext|>


<commit_before>#define CATCH_CONFIG_MAIN

#include <climits>
#include "../lib/catch.hpp"

extern "C"
{
#include "../inc/Date.h"
#include "../inc/LogEntry.h"
#include "../inc/parse.h"
extern unsigned short toHttpMethod(const char *str);
extern unsigned char toMonth(const char *str);
};

// TODO: test lgeAddToDaycounter()
// TODO: test struct LogStats

// TODO: more tests for parseLogEntry()

// TODO: run valigrind memory leak tests
// TODO: split test into multiple soruce files

TEST_CASE("architecture tests", "[architecture]")
{
	// for day in struct Date
	REQUIRE(UCHAR_MAX >= 31);
	// for year in struct Date
	REQUIRE(USHRT_MAX >= 9999);
	// for implementation of dtToNewString
	REQUIRE(USHRT_MAX <= 99999);
	REQUIRE(UCHAR_MAX <= 99999);
	// for implementation of parseLogEntry
	REQUIRE(LLONG_MAX >= 9999);
}

//
// ============   Date.h   ==========
//
TEST_CASE("date compare", "[src/Date.c/dtCompare]")
{
	struct Date d0 = { .year = 2016, .month = 1, .day = 10 };
	struct Date d1 = { .year = 2016, .month = 1, .day = 11 };
	struct Date d2 = { .year = 2016, .month = 2, .day = 10 };
	struct Date d3 = { .year = 2017, .month = 1, .day = 10 };

	REQUIRE(dtCompare(NULL, NULL) == 0);
	REQUIRE(dtCompare(NULL, &d0) < 0);
	REQUIRE(dtCompare(&d1, NULL) > 0);
	REQUIRE(dtCompare(&d3, &d3) == 0);
	REQUIRE(dtCompare(&d0, &d1) < 0);
	REQUIRE(dtCompare(&d0, &d2) < 0);
	REQUIRE(dtCompare(&d0, &d3) < 0);
	REQUIRE(dtCompare(&d3, &d0) > 0);
	REQUIRE(dtCompare(&d3, &d2) > 0);
}

TEST_CASE("date to new string", "[src/Date.c/dtToNewString]")
{
	char *str;
	struct Date d0 = {.year = 2016, .month = 12, .day = 24};

	REQUIRE(dtToNewString(NULL) == NULL);
	str = dtToNewString(&d0);
	REQUIRE(strcmp("2016/12/24", str) == 0);
	free(str);
}

TEST_CASE("date to string", "[src/Date.c/dtToString]")
{
	char buffer[64];
	char str0[] = "2016/12/24";
	struct Date d0 = {.year = 2016, .month = 12, .day = 24};

	REQUIRE(dtToString(NULL, NULL) < 0);
	REQUIRE(dtToString(NULL, buffer) < 0);
	REQUIRE(dtToString(&d0, NULL) < 0);
	REQUIRE(dtToString(&d0, buffer) == strlen(str0));
	REQUIRE(strcmp(buffer, str0) == 0);
}

//
// ============   LogEntry.h   ==========
//

//
// ============   parse.h   ==========
//
TEST_CASE("to HTTP method", "[src/parse.c/toHttpMethod]")
{
	REQUIRE(toHttpMethod(NULL) == HTTP_UNKNOWN);
	REQUIRE(toHttpMethod("CONNECT") == HTTP_CONNECT);
	REQUIRE(toHttpMethod("delete") == HTTP_DELETE);
	REQUIRE(toHttpMethod("gET") == HTTP_GET);
	REQUIRE(toHttpMethod("HeAd") == HTTP_HEAD);
	REQUIRE(toHttpMethod("optIons") == HTTP_OPTIONS);
	REQUIRE(toHttpMethod("POST") == HTTP_POST);
	REQUIRE(toHttpMethod("put") == HTTP_PUT);
	REQUIRE(toHttpMethod("tRaCe") == HTTP_TRACE);
	REQUIRE(toHttpMethod("GETS") == HTTP_UNKNOWN);
	REQUIRE(toHttpMethod("") == HTTP_UNKNOWN);
}

TEST_CASE("to month", "[src/parse.c/toMonth]")
{
	REQUIRE(toMonth(NULL) == 0);

	REQUIRE(toMonth("jan") == 1);
	REQUIRE(toMonth("feB") == 2);
	REQUIRE(toMonth("mAr") == 3);
	REQUIRE(toMonth("aPR") == 4);
	REQUIRE(toMonth("May") == 5);
	REQUIRE(toMonth("JuN") == 6);
	REQUIRE(toMonth("JUl") == 7);
	REQUIRE(toMonth("AUG") == 8);
	REQUIRE(toMonth("sep") == 9);
	REQUIRE(toMonth("ocT") == 10);
	REQUIRE(toMonth("nOv") == 11);
	REQUIRE(toMonth("dEC") == 12);

	REQUIRE(toMonth("august") == 0);
	REQUIRE(toMonth("") == 0);
}

// TODO: test too long input
TEST_CASE("parse log entry", "[src/parse.c/parseLogEntry]")
{
	// format: %t#%h#%u#%s#%I#%O#%U#%{Referer}i#%m
	struct LogEntry entry;
	FILE *file;

	// normal log line
	const char *s0 = "[07/Nov/2016:17:40:56 +0000]#1.2.3.4#-#200#1112#3757#/index.html#/#GET";
	file = fmemopen((char*)s0, strlen(s0), "r");

	REQUIRE(parseLogEntry(file, NULL) == -1);
	REQUIRE(parseLogEntry(NULL, &entry) == -1);
	REQUIRE(parseLogEntry(NULL, NULL) == -1);

	REQUIRE(parseLogEntry(file, &entry) == 0);
	REQUIRE(entry.date.day == 7);
	REQUIRE(entry.date.month == 11);
	REQUIRE(entry.date.year == 2016);
	REQUIRE(entry.http_method == HTTP_GET);
	REQUIRE(entry.http_status == 200);
	REQUIRE(entry.request_size == 1112);
	REQUIRE(entry.response_size == 3757);
	REQUIRE(strcmp(entry.remote_address, "1.2.3.4") == 0);
	REQUIRE(strcmp(entry.username, "-") == 0);
	REQUIRE(strcmp(entry.requested_file, "/index.html") == 0);
	REQUIRE(strcmp(entry.referer, "/") == 0);

	lgeFreeStrings(&entry);
	fclose(file);

	// very strange but still valid log line
	const char *s1 = "[12/mAR/9999:4:2:0 +1337]#fancy.url.com##999#4294967295#0#/!@$%##";
	file = fmemopen((char*)s1, strlen(s1), "r");

	REQUIRE(parseLogEntry(file, &entry) == 0);
	REQUIRE(entry.date.day == 12);
	REQUIRE(entry.date.month == 3);
	REQUIRE(entry.date.year == 9999);
	REQUIRE(entry.http_method == HTTP_UNKNOWN);
	REQUIRE(entry.http_status == 999);
	REQUIRE(entry.request_size == 4294967295);
	REQUIRE(entry.response_size == 0);
	REQUIRE(strcmp(entry.remote_address, "fancy.url.com") == 0);
	REQUIRE(strcmp(entry.username, "") == 0);
	REQUIRE(strcmp(entry.requested_file, "/!@$%") == 0);
	REQUIRE(strcmp(entry.referer, "") == 0);

	lgeFreeStrings(&entry);
	fclose(file);

	// invalid format (year >= 10000)
	const char *s2 = "[3/Oct/10000:4:2:0 +1337]#8.8.8.8#mike#200#257#2395#/index.html##GET";
	file = fmemopen((char*)s2, strlen(s2), "r");

	REQUIRE(parseLogEntry(file, &entry) == 1);

	fclose(file);
}
<commit_msg>Added test for dcAddLogEntry().<commit_after>#define CATCH_CONFIG_MAIN

#include <climits>
#include "../lib/catch.hpp"

extern "C"
{
#include "../inc/Date.h"
#include "../inc/DayCounter.h"
#include "../inc/LogEntry.h"
#include "../inc/parse.h"
extern unsigned short toHttpMethod(const char *str);
extern unsigned char toMonth(const char *str);
};

// TODO: test struct LogStats

// TODO: more tests for parseLogEntry()

// TODO: run valigrind memory leak tests
// TODO: split test into multiple soruce files

TEST_CASE("architecture tests", "[architecture]")
{
	// for day in struct Date
	REQUIRE(UCHAR_MAX >= 31);
	// for year in struct Date
	REQUIRE(USHRT_MAX >= 9999);
	// for implementation of dtToNewString
	REQUIRE(USHRT_MAX <= 99999);
	REQUIRE(UCHAR_MAX <= 99999);
	// for implementation of parseLogEntry
	REQUIRE(LLONG_MAX >= 9999);
}

//
// ============   Date.h   ==========
//
TEST_CASE("date compare", "[src/Date.c/dtCompare]")
{
	struct Date d0 = { .year = 2016, .month = 1, .day = 10 };
	struct Date d1 = { .year = 2016, .month = 1, .day = 11 };
	struct Date d2 = { .year = 2016, .month = 2, .day = 10 };
	struct Date d3 = { .year = 2017, .month = 1, .day = 10 };

	REQUIRE(dtCompare(NULL, NULL) == 0);
	REQUIRE(dtCompare(NULL, &d0) < 0);
	REQUIRE(dtCompare(&d1, NULL) > 0);
	REQUIRE(dtCompare(&d3, &d3) == 0);
	REQUIRE(dtCompare(&d0, &d1) < 0);
	REQUIRE(dtCompare(&d0, &d2) < 0);
	REQUIRE(dtCompare(&d0, &d3) < 0);
	REQUIRE(dtCompare(&d3, &d0) > 0);
	REQUIRE(dtCompare(&d3, &d2) > 0);
}

TEST_CASE("date to new string", "[src/Date.c/dtToNewString]")
{
	char *str;
	struct Date d0 = {.year = 2016, .month = 12, .day = 24};

	REQUIRE(dtToNewString(NULL) == NULL);
	str = dtToNewString(&d0);
	REQUIRE(strcmp("2016/12/24", str) == 0);
	free(str);
}

TEST_CASE("date to string", "[src/Date.c/dtToString]")
{
	char buffer[64];
	char str0[] = "2016/12/24";
	struct Date d0 = {.year = 2016, .month = 12, .day = 24};

	REQUIRE(dtToString(NULL, NULL) < 0);
	REQUIRE(dtToString(NULL, buffer) < 0);
	REQUIRE(dtToString(&d0, NULL) < 0);
	REQUIRE(dtToString(&d0, buffer) == strlen(str0));
	REQUIRE(strcmp(buffer, str0) == 0);
}

//
// ============   DayCounter.h   ==========
//
TEST_CASE("day counter add log entry", "[src/DayCounter.c/dcAddLogEntry]")
{
	struct DayCounter counter;
	struct LogEntry entry0;
	struct LogEntry entry1;
	entry0.remote_address = (char*)"127.0.0.1";
	entry0.request_size = 420;
	entry0.response_size = 1337;
	entry1.remote_address = (char*)"example.com";
	entry1.request_size = 12;
	entry1.response_size = 100;

	memset(&counter, 0, sizeof(struct DayCounter));

	REQUIRE_NOTHROW(dcAddLogEntry(NULL, NULL));
	REQUIRE_NOTHROW(dcAddLogEntry(NULL, &entry0));
	REQUIRE_NOTHROW(dcAddLogEntry(&counter, NULL));

	dcAddLogEntry(&counter, &entry0);

	REQUIRE(counter.n_requests == 1);
	// REQUIRE(counter.n_users == 1);
	REQUIRE(counter.n_bytes_in == 420);
	REQUIRE(counter.n_bytes_out == 1337);

	dcAddLogEntry(&counter, &entry1);
	dcAddLogEntry(&counter, &entry0);

	REQUIRE(counter.n_requests == 3);
	// REQUIRE(counter.n_users == 2);
	REQUIRE(counter.n_bytes_in == 852);
	REQUIRE(counter.n_bytes_out == 2774);
}

//
// ============   parse.h   ==========
//
TEST_CASE("to HTTP method", "[src/parse.c/toHttpMethod]")
{
	REQUIRE(toHttpMethod(NULL) == HTTP_UNKNOWN);
	REQUIRE(toHttpMethod("CONNECT") == HTTP_CONNECT);
	REQUIRE(toHttpMethod("delete") == HTTP_DELETE);
	REQUIRE(toHttpMethod("gET") == HTTP_GET);
	REQUIRE(toHttpMethod("HeAd") == HTTP_HEAD);
	REQUIRE(toHttpMethod("optIons") == HTTP_OPTIONS);
	REQUIRE(toHttpMethod("POST") == HTTP_POST);
	REQUIRE(toHttpMethod("put") == HTTP_PUT);
	REQUIRE(toHttpMethod("tRaCe") == HTTP_TRACE);
	REQUIRE(toHttpMethod("GETS") == HTTP_UNKNOWN);
	REQUIRE(toHttpMethod("") == HTTP_UNKNOWN);
}

TEST_CASE("to month", "[src/parse.c/toMonth]")
{
	REQUIRE(toMonth(NULL) == 0);

	REQUIRE(toMonth("jan") == 1);
	REQUIRE(toMonth("feB") == 2);
	REQUIRE(toMonth("mAr") == 3);
	REQUIRE(toMonth("aPR") == 4);
	REQUIRE(toMonth("May") == 5);
	REQUIRE(toMonth("JuN") == 6);
	REQUIRE(toMonth("JUl") == 7);
	REQUIRE(toMonth("AUG") == 8);
	REQUIRE(toMonth("sep") == 9);
	REQUIRE(toMonth("ocT") == 10);
	REQUIRE(toMonth("nOv") == 11);
	REQUIRE(toMonth("dEC") == 12);

	REQUIRE(toMonth("august") == 0);
	REQUIRE(toMonth("") == 0);
}

// TODO: test too long input
TEST_CASE("parse log entry", "[src/parse.c/parseLogEntry]")
{
	// format: %t#%h#%u#%s#%I#%O#%U#%{Referer}i#%m
	struct LogEntry entry;
	FILE *file;

	// normal log line
	const char *s0 = "[07/Nov/2016:17:40:56 +0000]#1.2.3.4#-#200#1112#3757#/index.html#/#GET";
	file = fmemopen((char*)s0, strlen(s0), "r");

	REQUIRE(parseLogEntry(file, NULL) == -1);
	REQUIRE(parseLogEntry(NULL, &entry) == -1);
	REQUIRE(parseLogEntry(NULL, NULL) == -1);

	REQUIRE(parseLogEntry(file, &entry) == 0);
	REQUIRE(entry.date.day == 7);
	REQUIRE(entry.date.month == 11);
	REQUIRE(entry.date.year == 2016);
	REQUIRE(entry.http_method == HTTP_GET);
	REQUIRE(entry.http_status == 200);
	REQUIRE(entry.request_size == 1112);
	REQUIRE(entry.response_size == 3757);
	REQUIRE(strcmp(entry.remote_address, "1.2.3.4") == 0);
	REQUIRE(strcmp(entry.username, "-") == 0);
	REQUIRE(strcmp(entry.requested_file, "/index.html") == 0);
	REQUIRE(strcmp(entry.referer, "/") == 0);

	lgeFreeStrings(&entry);
	fclose(file);

	// very strange but still valid log line
	const char *s1 = "[12/mAR/9999:4:2:0 +1337]#fancy.url.com##999#4294967295#0#/!@$%##";
	file = fmemopen((char*)s1, strlen(s1), "r");

	REQUIRE(parseLogEntry(file, &entry) == 0);
	REQUIRE(entry.date.day == 12);
	REQUIRE(entry.date.month == 3);
	REQUIRE(entry.date.year == 9999);
	REQUIRE(entry.http_method == HTTP_UNKNOWN);
	REQUIRE(entry.http_status == 999);
	REQUIRE(entry.request_size == 4294967295);
	REQUIRE(entry.response_size == 0);
	REQUIRE(strcmp(entry.remote_address, "fancy.url.com") == 0);
	REQUIRE(strcmp(entry.username, "") == 0);
	REQUIRE(strcmp(entry.requested_file, "/!@$%") == 0);
	REQUIRE(strcmp(entry.referer, "") == 0);

	lgeFreeStrings(&entry);
	fclose(file);

	// invalid format (year >= 10000)
	const char *s2 = "[3/Oct/10000:4:2:0 +1337]#8.8.8.8#mike#200#257#2395#/index.html##GET";
	file = fmemopen((char*)s2, strlen(s2), "r");

	REQUIRE(parseLogEntry(file, &entry) == 1);

	fclose(file);
}
<|endoftext|>


<commit_before>#include <iostream>
#define _USE_MATH_DEFINES
#include <cmath>
#include <cassert>

#include "ics3/ics"

int main(int argc, char **argv) {
  {
    ics::ID id(2);
    ics::Angle degree = ics::Angle::newDegree();
    ics::ICS3 ics("/dev/ttyUSB0", ics::ICSBaudrate::RATE115200);
    ics::Angle nowPos = ics.move(id, degree);
  }
  {
    std::cout << std::endl << "EepParam test section" << std::endl;
    ics::EepParam speed = ics::EepParam::speed();
    assert(127 == speed.get());
    speed.set(100);
    assert(100 == speed.get());
    try {
      speed.set(200);
      std::cerr << "Never run this" << std::endl;
    } catch (std::invalid_argument e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "angle test section" << std::endl;
    ics::Angle degree = ics::Angle::newDegree();
    ics::Angle radian = ics::Angle::newRadian();
    assert(degree.getRaw() == radian.getRaw());
    degree.set(0);
    radian.set(0);
    assert(degree.getRaw() == radian.getRaw());
    degree.set(90);
    radian.set(M_PI / 2);
    assert(degree.getRaw() == radian.getRaw());
    degree.set(60);
    radian.set(M_PI / 3);
    assert(degree.getRaw() == radian.getRaw());
    try {
      degree.set(150);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument &e) {
      std::cout << e.what() << std::endl;
    }
    try {
      radian.set(M_PI);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument &e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "parameter test section" << std::endl;
    ics::Parameter current = ics::Parameter::current();
    assert(63 == current.get());
    current.set(30);
    assert(30 == current.get());
    try {
      current.set(70);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument &e) {
      std::cout << e.what() << std::endl;
    }
  }
  return 0;
}
<commit_msg>Update test.cpp<commit_after>#include <iostream>
#define _USE_MATH_DEFINES
#include <cmath>
#include <cassert>

#include "ics3/ics"

int main(int argc, char **argv) {
  {
    ics::ID id(2);
    ics::Angle degree = ics::Angle::newDegree();
    ics::ICS3 ics("/dev/ttyUSB0", ics::ICSBaudrate::RATE115200);
    ics::Angle nowPos = ics.move(id, degree);
  }
  {
    std::cout << std::endl << "EepParam test section" << std::endl;
    ics::EepParam speed = ics::EepParam::speed();
    assert(127 == speed.get());
    speed.set(100);
    assert(100 == speed.get());
    try {
      speed.set(200);
      std::cerr << "Never run this" << std::endl;
    } catch (std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "angle test section" << std::endl;
    ics::Angle degree = ics::Angle::newDegree();
    ics::Angle radian = ics::Angle::newRadian();
    assert(degree.getRaw() == radian.getRaw());
    degree.set(0);
    radian.set(0);
    assert(degree.getRaw() == radian.getRaw());
    degree.set(90);
    radian.set(M_PI / 2);
    assert(degree.getRaw() == radian.getRaw());
    degree.set(60);
    radian.set(M_PI / 3);
    assert(degree.getRaw() == radian.getRaw());
    try {
      degree.set(150);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
    try {
      radian.set(M_PI);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  {
    std::cout << std::endl << "parameter test section" << std::endl;
    ics::Parameter current = ics::Parameter::current();
    assert(63 == current.get());
    current.set(30);
    assert(30 == current.get());
    try {
      current.set(70);
      std::cerr << "Never run this" << std::endl;
    } catch (const std::invalid_argument& e) {
      std::cout << e.what() << std::endl;
    }
  }
  return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <stdexcept>

const bool BLACK = 1;
const bool RED = 0;

template<typename T>
struct Node
{
	T value;
	bool color;
	Node* leftNode;
	Node* rightNode;
	Node* parNode;
};

template<typename T>
class RedBlackTree
{
private:
	Node<T>* root;
	Node<T>* NIL;
public:
	RedBlackTree();
	bool _color(const T& value) const;
	Node<T>* _root() const;
	Node<T>* _NIL() const;
	void left_rotate(Node<T>* currNode);
	void right_rotate(Node<T>* currNode);
	void insertFix(Node<T>* currNode);
	void insert(const T& value);
	void print(const Node<T>* tempNode, int level) const;
	Node<T>* findElement(const T& value) const;
};

template <typename T>
RedBlackTree<T>::RedBlackTree()
{
	NIL = new Node<T>;
	NIL->leftNode = NIL->parNode = NIL->rightNode = nullptr;
	NIL->color = BLACK;
	root = NIL;
}

template <typename T>
bool RedBlackTree<T>::_color(const T& value) const
{
	return findElement(value)->color;
}

template <typename T>
Node<T>* RedBlackTree<T>::_root() const
{
	return root;
}

template <typename T>
Node<T>* RedBlackTree<T>::_NIL()const
{
	return NIL;
}

template <typename T>
void RedBlackTree<T>::left_rotate(Node<T>* currNode)
{
	Node<T>* tempNode= currNode->rightNode;
	currNode->rightNode = tempNode->leftNode;
	if (tempNode->leftNode != NIL)
		tempNode->leftNode->parNode = currNode;
	if (tempNode!= NIL)
		tempNode->parNode = currNode->parNode;
	if (currNode->parNode != NIL)
	{
		if (currNode == currNode->parNode->leftNode)
			currNode->parNode->leftNode = tempNode;
		else
			currNode->parNode->rightNode = tempNode;
	}
	else
	{
		root = tempNode;
	}
	tempNode->leftNode = currNode;
	if (currNode != NIL)
		currNode->parNode = tempNode;
}

template <typename T>
void RedBlackTree<T>::right_rotate(Node<T> *currNode)
{
	Node<T> *tempNode= currNode->leftNode;
	currNode->leftNode = tempNode->rightNode;
	if (tempNode->rightNode != NIL)
		tempNode->rightNode->parNode = currNode;
	if (tempNode!= NIL)
		tempNode->parNode = currNode->parNode;
	if (currNode->parNode != NIL)
	{
		if (currNode == currNode->parNode->rightNode)
			currNode->parNode->rightNode = tempNode;
		else
			currNode->parNode->leftNode = tempNode;
	}
	else
	{
		root = tempNode;
	}

	tempNode->rightNode = currNode;
	if (currNode != NIL)
		currNode->parNode = tempNode;
}

template <typename T>
void RedBlackTree<T>::insertFix(Node<T>* currNode)
{
	while (currNode != root && currNode->parNode->color == RED)
	{
		if (currNode->parNode == currNode->parNode->parNode->leftNode)
		{
			Node<T>* tempNode= currNode->parNode->parNode->rightNode;
			if (tempNode->color == RED)
			{
				currNode->parNode->color = BLACK;
				tempNode->color = BLACK;
				currNode->parNode->parNode->color = RED;
				currNode = currNode->parNode->parNode;
			}

			else
			{
				if (currNode == currNode->parNode->rightNode)
				{
					currNode = currNode->parNode;
					left_rotate(currNode);
				}
				currNode->parNode->color = BLACK;
				currNode->parNode->parNode->color = RED;
				right_rotate(currNode->parNode->parNode);
			}
		}

		else
		{
			Node<T>* tempNode= currNode->parNode->parNode->leftNode;
			if (tempNode->color == RED)
			{
				currNode->parNode->color = BLACK;
				tempNode->color = BLACK;
				currNode->parNode->parNode->color = RED;
				currNode = currNode->parNode->parNode;
			}
			else
			{
				if (currNode == currNode->parNode->leftNode)
				{
					currNode = currNode->parNode;
					right_rotate(currNode);
				}
				currNode->parNode->color = BLACK;
				currNode->parNode->parNode->color = RED;
				left_rotate(currNode->parNode->parNode);
			}
		}
	}
	root->color = BLACK;
}

template <typename T>
void RedBlackTree<T>::insert(const T& value)
{
	if (findElement(value))
	{
		throw std::logic_error("This value is already added!\n");
	}
	Node<T>* child = new Node<T>;
	child->value = value;
	child->color = RED;
	child->leftNode = child->rightNode = child->parNode = NIL;
	Node<T>* parNode = NIL;
	Node<T>* tempNode= root;
	if (root == NIL)
	{
		root = child;
		root->color = BLACK;
		return;
	}
	while (tempNode!= NIL)
	{

		if (child->value == tempNode->value)
			return;

		parNode = tempNode;
		if (value < tempNode->value)
			tempNode= tempNode->leftNode;
		else
			tempNode= tempNode->rightNode;
	}
	if (value < parNode->value)
	{
		parNode->leftNode = child;
	}
	else
	{
		parNode->rightNode = child;

	}
	child->parNode = parNode;
	insertFix(child);
}

template <typename T>
void RedBlackTree<T>::print(const Node<T>* tempNode, int level)const
{
		if (root == NIL)
		{
			throw std::logic_error("Error! The tree is empty!\n");
		}
		if (tempNode!= NIL)
		{
			print(tempNode->leftNode, level + 1);
			for (int i = 0; i < level; i++)
				std::cout << "\t";
			std::cout << "(" << tempNode->color << ")";
			std::cout << tempNode->value << "\n";
			print(tempNode->rightNode, level + 1);
		}
	}

template <typename T>
Node<T>* RedBlackTree<T>::findElement(const T& value) const
{
	Node<T>* currNode = root;
	while (currNode != NIL)
	{
		if (value == currNode->value)
			return currNode;
		else
		{
			if (value < currNode->value)
				currNode = currNode->leftNode;
			else currNode = currNode->rightNode;
		}
	}
	return 0;
}
<commit_msg>Update red_black_tree.hpp<commit_after>#include <iostream>
#include <stdexcept>

const bool BLACK = 1;
const bool RED = 0;

template<typename T>
struct Node
{
	T value;
	bool color;
	Node* leftNode;
	Node* rightNode;
	Node* parNode;
};

template<typename T>
class RedBlackTree
{
private:
	Node<T>* root;
	Node<T>* NIL;
public:
	RedBlackTree();
	~RedBlackTree();
	bool _color(const T& value) const;
	Node<T>* _root() const;
	Node<T>* _NIL() const;
	void left_rotate(Node<T>* currNode);
	void right_rotate(Node<T>* currNode);
	void insertFix(Node<T>* currNode);
	void insert(const T& value);
	void destroyTree(Node<T>* node);
	void print(const Node<T>* tempNode, int level) const;
	Node<T>* findElement(const T& value) const;
};

template <typename T>
RedBlackTree<T>::RedBlackTree()
{
	NIL = new Node<T>;
	NIL->leftNode = NIL->parNode = NIL->rightNode = nullptr;
	NIL->color = BLACK;
	root = NIL;
}

template <typename T>
RedBlackTree::~RedBlackTree()
{
	destroyTree(root);
	delete NIL;
}

template <typename T>
void BinarySearchTree<T>::destroyTree(Node<T>* node)
{
	if (!node)
		return;

	while (node->leftNode != NIL)
		destroyTree(node->leftNode);

	while (node->rightNode != NIL)
		destroyTree(node->rightNode);

	delete node;
}

template <typename T>
bool RedBlackTree<T>::_color(const T& value) const
{
	return findElement(value)->color;
}

template <typename T>
Node<T>* RedBlackTree<T>::_root() const
{
	return root;
}

template <typename T>
Node<T>* RedBlackTree<T>::_NIL()const
{
	return NIL;
}

template <typename T>
void RedBlackTree<T>::left_rotate(Node<T>* currNode)
{
	Node<T>* tempNode= currNode->rightNode;
	currNode->rightNode = tempNode->leftNode;
	if (tempNode->leftNode != NIL)
		tempNode->leftNode->parNode = currNode;
	if (tempNode!= NIL)
		tempNode->parNode = currNode->parNode;
	if (currNode->parNode != NIL)
	{
		if (currNode == currNode->parNode->leftNode)
			currNode->parNode->leftNode = tempNode;
		else
			currNode->parNode->rightNode = tempNode;
	}
	else
	{
		root = tempNode;
	}
	tempNode->leftNode = currNode;
	if (currNode != NIL)
		currNode->parNode = tempNode;
}

template <typename T>
void RedBlackTree<T>::right_rotate(Node<T> *currNode)
{
	Node<T> *tempNode= currNode->leftNode;
	currNode->leftNode = tempNode->rightNode;
	if (tempNode->rightNode != NIL)
		tempNode->rightNode->parNode = currNode;
	if (tempNode!= NIL)
		tempNode->parNode = currNode->parNode;
	if (currNode->parNode != NIL)
	{
		if (currNode == currNode->parNode->rightNode)
			currNode->parNode->rightNode = tempNode;
		else
			currNode->parNode->leftNode = tempNode;
	}
	else
	{
		root = tempNode;
	}

	tempNode->rightNode = currNode;
	if (currNode != NIL)
		currNode->parNode = tempNode;
}

template <typename T>
void RedBlackTree<T>::insertFix(Node<T>* currNode)
{
	while (currNode != root && currNode->parNode->color == RED)
	{
		if (currNode->parNode == currNode->parNode->parNode->leftNode)
		{
			Node<T>* tempNode= currNode->parNode->parNode->rightNode;
			if (tempNode->color == RED)
			{
				currNode->parNode->color = BLACK;
				tempNode->color = BLACK;
				currNode->parNode->parNode->color = RED;
				currNode = currNode->parNode->parNode;
			}

			else
			{
				if (currNode == currNode->parNode->rightNode)
				{
					currNode = currNode->parNode;
					left_rotate(currNode);
				}
				currNode->parNode->color = BLACK;
				currNode->parNode->parNode->color = RED;
				right_rotate(currNode->parNode->parNode);
			}
		}

		else
		{
			Node<T>* tempNode= currNode->parNode->parNode->leftNode;
			if (tempNode->color == RED)
			{
				currNode->parNode->color = BLACK;
				tempNode->color = BLACK;
				currNode->parNode->parNode->color = RED;
				currNode = currNode->parNode->parNode;
			}
			else
			{
				if (currNode == currNode->parNode->leftNode)
				{
					currNode = currNode->parNode;
					right_rotate(currNode);
				}
				currNode->parNode->color = BLACK;
				currNode->parNode->parNode->color = RED;
				left_rotate(currNode->parNode->parNode);
			}
		}
	}
	root->color = BLACK;
}

template <typename T>
void RedBlackTree<T>::insert(const T& value)
{
	if (findElement(value))
	{
		throw std::logic_error("This value is already added!\n");
	}
	Node<T>* child = new Node<T>;
	child->value = value;
	child->color = RED;
	child->leftNode = child->rightNode = child->parNode = NIL;
	Node<T>* parNode = NIL;
	Node<T>* tempNode= root;
	if (root == NIL)
	{
		root = child;
		root->color = BLACK;
		return;
	}
	while (tempNode!= NIL)
	{

		if (child->value == tempNode->value)
			return;

		parNode = tempNode;
		if (value < tempNode->value)
			tempNode= tempNode->leftNode;
		else
			tempNode= tempNode->rightNode;
	}
	if (value < parNode->value)
	{
		parNode->leftNode = child;
	}
	else
	{
		parNode->rightNode = child;

	}
	child->parNode = parNode;
	insertFix(child);
}

template <typename T>
void RedBlackTree<T>::print(const Node<T>* tempNode, int level)const
{
		if (root == NIL)
		{
			throw std::logic_error("Error! The tree is empty!\n");
		}
		if (tempNode!= NIL)
		{
			print(tempNode->leftNode, level + 1);
			for (int i = 0; i < level; i++)
				std::cout << "\t";
			std::cout << "(" << tempNode->color << ")";
			std::cout << tempNode->value << "\n";
			print(tempNode->rightNode, level + 1);
		}
	}

template <typename T>
Node<T>* RedBlackTree<T>::findElement(const T& value) const
{
	Node<T>* currNode = root;
	while (currNode != NIL)
	{
		if (value == currNode->value)
			return currNode;
		else
		{
			if (value < currNode->value)
				currNode = currNode->leftNode;
			else currNode = currNode->rightNode;
		}
	}
	return 0;
}
<|endoftext|>


<commit_before>#include <boxer/boxer.h>
#include <windows.h>

namespace boxer {

namespace {

UINT getIcon(Style style) {
   switch (style) {
      case Style::Info:
         return MB_ICONINFORMATION;
      case Style::Warning:
         return MB_ICONWARNING;
      case Style::Error:
         return MB_ICONERROR;
      case Style::Question:
         return MB_ICONQUESTION;
      default:
         return MB_ICONINFORMATION;
   }
}

UINT getButtons(Buttons buttons) {
   switch (buttons) {
      case Buttons::OK:
      case Buttons::Quit: // There is no 'Quit' button on windows :(
         return MB_OK;
      case Buttons::OKCancel:
         return MB_OKCANCEL;
      case Buttons::YesNo:
         return MB_YESNO;
      default:
         return MB_OK;
   }
}

Selection getSelection(int response, Buttons buttons) {
   switch (response) {
      case IDOK:
         return buttons == Buttons::Quit ? Selection::Quit : Selection::OK;
      case IDCANCEL:
         return Selection::Cancel;
      case IDYES:
         return Selection::Yes;
      case IDNO:
         return Selection::No;
      default:
         return Selection::None;
   }
}

} // namespace

Selection show(const char *message, const char *title, Style style, Buttons buttons) {
   UINT flags = MB_TASKMODAL;

   flags |= getIcon(style);
   flags |= getButtons(buttons);

   return getSelection(MessageBox(nullptr, message, title, flags), buttons);
}

} // namespace boxer
<commit_msg>Define WIN32_LEAN_AND_MEAN on Windows<commit_after>#include <boxer/boxer.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

namespace boxer {

namespace {

UINT getIcon(Style style) {
   switch (style) {
      case Style::Info:
         return MB_ICONINFORMATION;
      case Style::Warning:
         return MB_ICONWARNING;
      case Style::Error:
         return MB_ICONERROR;
      case Style::Question:
         return MB_ICONQUESTION;
      default:
         return MB_ICONINFORMATION;
   }
}

UINT getButtons(Buttons buttons) {
   switch (buttons) {
      case Buttons::OK:
      case Buttons::Quit: // There is no 'Quit' button on Windows :(
         return MB_OK;
      case Buttons::OKCancel:
         return MB_OKCANCEL;
      case Buttons::YesNo:
         return MB_YESNO;
      default:
         return MB_OK;
   }
}

Selection getSelection(int response, Buttons buttons) {
   switch (response) {
      case IDOK:
         return buttons == Buttons::Quit ? Selection::Quit : Selection::OK;
      case IDCANCEL:
         return Selection::Cancel;
      case IDYES:
         return Selection::Yes;
      case IDNO:
         return Selection::No;
      default:
         return Selection::None;
   }
}

} // namespace

Selection show(const char *message, const char *title, Style style, Buttons buttons) {
   UINT flags = MB_TASKMODAL;

   flags |= getIcon(style);
   flags |= getButtons(buttons);

   return getSelection(MessageBox(nullptr, message, title, flags), buttons);
}

} // namespace boxer
<|endoftext|>